Package binary configurations and CPS file location proposal #58
Replies: 4 comments 8 replies
-
Yes, that has always been the intent. But that's a function of the build system that doesn't need to be (and, I would argue, shouldn't be) specified by CPS. The search mechanism is what to do when you haven't been given specific instructions.
...and IIUC you want the build tool to be able to override those, also? Sure, agreed, but see previous comment. (In this case, note that
Um. Okay, I can imagine cases where that might be useful, but I think you'll find it difficult getting CMake to implement it. I am opposed to suggesting that this is a requirement.
Perhaps, but this seems orthogonal to the core specification. I don't know if CMake would use it, since we already have our own mechanism.
If by "could be" you mean tools should try the specified path first, that's obviously how this would work. If you mean a package not found there should be a hard error... IMHO that should be up to the tool to decide. I have no problem if tools want to make that an optional behavior. I'm less convinced falling back to search shouldn't at least be an option, or that it shouldn't be the default option (e.g. as it is currently in CMake). In summary: you are free to write a build tool that works this way. I see nothing in CPS that stops you from doing so. However, I suspect it would be extremely challenging for at least some build tools (e.g. CMake) to support what you are proposing. |
Beta Was this translation helpful? Give feedback.
-
Do you have your own version of |
Beta Was this translation helpful? Give feedback.
-
On a less important bikeshedding note, I'm thinking this model for separation of concerns is helpful to me:
That status quo is that current tools do some or all of those actions. CMake with Point being, for interop and eventual convergence, I think we need dependency maps as another "seam" in the architecture. On a technical level, it could be a separate project from CPS that specifies how dependency solutions are encoded and decode, but it would be great for all us humans if we didn't have to keep two specifications collated. |
Beta Was this translation helpful? Give feedback.
-
How, then, if I've already imported the release Foo package, do I import the asan Foo package? This requires them to have separate identities, and it requires that different configurations of the consumer link to different targets. You can do the latter with generator expressions, but it's a lot messier than linking to different configurations of the same component/target. A much more sane approach is to provide the release and asan builds as different configurations of the same package. |
Beta Was this translation helpful? Give feedback.
-
Proposal
In addition to the package search mechanism described in the current spec (https://cps-org.github.io/cps/searching.html), it should also be possible to tell the build system exactly where to find the .cps files - without relying on a filesystem search, if the user so chooses (or if a package manager or other tool is able to unequivocally generate the paths to all required dependencies).
As the transitive dependencies are not directly referenced by the build systems, it is not possible to rely on expliciting the paths in the build systems, like some
load_cps_file(/full/path/to/foo.cps)
, but rather a mapping of dependencies to the exact location of the cps on disk should be allowed if the dependencies locations are known by the user or another tool like a package manager is able to provide.Conceptually something like:
As a corollary for multi-configuration systems:
In practice this will translate to being able to provide a different mapping for each one of the configurations.
The tools shouldn’t necessarily impose packages to provide all configurations or that all configurations must exist within the same prefix.
As implementation hint, the proposal could be implemented by one “cps-map.json” file that contains the configurations and the locations:
Or several files, one per configuration:
cps-map-Debug.json
cps-map-Release.json
cps-map-DebugAsan.json
It is perfectly valid and possible to have build systems and tools to use automatic strategies for locating CPS files, the current proposal fits without problems in this strategy, just the automatic search functionality could be skipped when an entry already exists in the mapping. This proposal also recommends that tools that automatically search for CPS files, output this file as a result for improved debuggability and user experience.
Current CPS status and proposed functionality
The current CPS status assume in several places that different binary configurations will always be available in the same tree. This would be a blocker for many different situations described in the following section rationale.
The sample CPS file in https://cps-org.github.io/cps/sample.html, contains:
And assuming this is a “sample.cps” file, the strategy of locating and using the “sample.cps” assumes that this will be in one location and a subtree.
Furthermore, the https://cps-org.github.io/cps/configurations.html#configuration-merging section describes how different configurations must be merged and a convention of names like
name:*.cps
should be followed.The current proposal means that the following structure must also be supported:
/path/to/myoptimize/sample.cps
/other/path/to/sample.cps
And then, build systems could use these specific files, without any kind of automatic finding, with an explicit mapping like:
cps-map.json
Note that the 2 different folders do not necessarily have to be in the same tree.
Rationale
Let's consider a team creating a “foo” package, and they build a Linux, static library, in “Release” mode, and the package has no dependencies. The build or the team produces a
foo.cps
, and they package everything in afoo.tgz
, compute its “foo.sha256” checksum and upload it to their servers, to reuse it while building other applications that depend on “foo”, even creating manifests (SBOMs) for their applications, tracing the dependency “foo” including its checksum.Now the same team wants to introduce a sanitized build. Some sanitizers instrument the built artifacts, producing different binaries, and even some sanitizers strongly recommend or mandate that all the dependencies should be built with the same sanitizing flags. So the team proceeds to do a sanitized build of the “foo” library, which they do in a different folder, and they end up creating a new
foo-san.tgz
, that also includes its own internalfoo.cps
. Now they want to be able to build their applications against this sanitized “foo” binary, so they should be able to explicitly point the build system to the sanitizedfoo.cps
file.This example with sanitizers introduces the challenge of managing binary variants. The sanitizers themselves have variability and different combinations of sanitizers will result in different and often incompatible binaries, but this issue goes beyond the sanitizer example.
We can summarize these challenges:
foo-xxx.cps
naming scheme that models such variability. This applies both for a file name or a folder hierarchy with folders representing segments of the binary variability.One important case where such a mapping will be more relevant and necessary is cross-building. When cross-building, the selection of dependencies depends on the “host” configuration (the one that will run the final binary), not the “build” (the current build machine), and this “host” configuration has a huge variability, that can depend on multiple factors, including low level hardware boards details. Modeling and trying to resolve automatically the dependencies for this configuration can be daunting, and it is already one of the current challenges with existing dependencies' location strategies. But this is resolved trivially if users can explicitly define the location of the CPS files they want to use for their build.
There are other dimensions of binary variability beyond the current compilation options, and there are many developers that need to support them. One common example is having one shared library that is being released as final product to customers, and this shared library might be built with exactly the same compiler, architecture, build-type, compiler flags, in the exact same machine from the exact same code, but with different dependencies. Something as trivial as a dependency getting a performance or security update. Users will need to be able to have 2 different binaries of their shared library with all possible inputs exactly the same, just with different dependencies, and develop and test them in parallel. This use case is also almost impossible to model without an explicit mapping.
Finally the “build-type” or “configuration” dimension also falls in this category. Even if some users could be creating and releasing packages that contains more than one configuration, like the Release and Debug one, this approach cannot be generalized:
Advantages
The current proposal brings many advantages, without necessarily impeding or forbidding other currently existing or future approaches:
Beta Was this translation helpful? Give feedback.
All reactions