Open bretbrownjr opened 7 months ago
Here's my thoughts (because LLVM is such a pain, and always on my mind): I think it makes sense to encourage one CPS file per conceptual project (it's possible a single repo contains multiple conceptual projects, like libLLVM and clang, which live in the same repo but are conceptually different projects, even if clang requires LLVM), and then use components for representing, well, components.
So absl would have a single CPS file, which might (with redactions look like):
{
"components": {
"time": {"requires": [":time_zone"]},
"time_zone": {}
}
}
This makes sense in that it prevents odd situations where components from one version of a library accidentally get mixed with another one; it should also speed up load time since an implementation does less I/O. It also would allow exploiting private components (which I like more and more) to hide implementation details which having separate CPS files would not
Do we recommend absl_time_zone.cps or do we recommend an omnibus absl.cps that includes models for each library shipped by the absl project?
I don't know that it's our place to make such a blanket recommendation. Rather, what is the project trying to accomplish?
Qt, for example, enforces that you can't mix and match components (e.g. core, gui, widgets, xmlpatterns, webengine). A project like that should ship as a single CPS "project". I suspect llvm/clang should, or at least could, ship as multiple projects.
More generally, the "rule" is that the project is a tool for ensuring that a set of components all comes from the same build. It's even possible for multiple repos to ship as a single CPS project (one has to be "primary").
Another rule is that if users expect to consume A without also consuming B (again, e.g. llvm without clang), then you should ship as separate projects.
it prevents odd situations where components from one version of a library accidentally get mixed with another one
Exactly; that is a major purpose, if not the purpose, of projects.
Let's keep in mind the implications for build systems going forward. If we expect projectname::libraryname
[1] will be an ecosystem-wide name for a given library, we should note that as a primary design decision and explain our reasoning. It should be a fairly prominent part of the documentation, for instance in conceptual guides and maybe even quick start guides.
This fits naturally for some things like CMake, Meson, and bazel (maybe substituting ::
for a /
to make the name path-like). I'm not sure it's as natural a fit for pkg-config
unless we set some standard mapping rules. Though likely we'll also have to design some recommended or standard coping mechanisms when projectname_libraryname.pc
is inappropriate or unavailable for whatever reason.
[1] Maybe the delimiter for ::
can be played with depending on the syntax of the build system.
Note: the name according to CPS is project:library
with one :
. (I know I often will write two out of habit, but the official spec is one.) It's assumed/intended that build systems will parse this as a 2-tuple and map that to their own internal convention as needed. It's also assumed that users will write these using their build tool's convention, at least when they appear in e.g. a CMakeLists.txt
. (For example, in Bazel you'd likely write @project//:library
.)
In other words, the canonical name isn't a string that contains one or more :
s, it is a 2-tuple. How that 2-tuple is written as a string is expected to vary depending on the tool.
This fits naturally for some things like CMake, Meson, and bazel (maybe substituting :: for a / to make the name path-like). I'm not sure it's as natural a fit for pkg-config unless we set some standard mapping rules.
Meson has as syntax for handling these kind of dependencies, qt for example:
dependency('qt', version : ['>=6', '<7'], modules : ['core', 'widgets'])
Which the meson implementation would transform into ['qt:core', 'qt:widgets']
, and would then call cps-config qt --component core --component widgets
As such I frankly don't care what the divider is :)
Though likely we'll also have to design some recommended or standard coping mechanisms when projectname_libraryname.pc is inappropriate or unavailable for whatever reason.
pkg-config naming is such a mess because there are no recommendations and various projects have different solutions:
Qt<Version><Component>
, so Qt6Core.pc
<name>-<major_version>.0
, so `gtk+-3.0x11-<component>
, so we have both glproto
and x11-xcb
pixman-1
ompi-<language interface>
, so ompi-c
, ompi-cxx
, ompi-fort
Should CPS files adopt RelWithDebInfo as an explicit default or should it be unqualified like the pkg-config metadata?
This probably deserves a separate discussion. On Linux at least it is common for the debug info to be split out of the package provided by the distro.
Should CPS files adopt
RelWithDebInfo
as an explicit default or should it be unqualified like the pkg-config metadata?
Configurations are... complicated, and right now CPS isn't trying to say what they look like, just that they're a thing that can exist. In practice, you're more likely to encounter static
/shared
from anything a distro ships, as distros don't usually ship separate release
and debug
libraries. (Also, to a consumer, there is little to no practical difference between release
and relwithdebinfo
.)
Is there currently support for "private" libraries like this? If not, should we add a tracking issue?
There is not currently support. I'd suggested that #29 should metamorphose into said issue.
Completion Criteria
Documentation about how to practically convert existing CMake and/or pkg-config projects to CPS should be started. It can be iterated on as we gain experience, but sharing lessons learned in discoverable ways is important to new adopters and contributors.
Background
Structure
It seems like
absl_time_zone
is an implementation library that installs headers but expects only otherabsl
libraries to make use of them,absl_time
especially. It needs to provide build systems information for discovering headers and libraries to link, of course, but end-users shouldn't be directly referencing this library, so it's an example of a "private" library.CMake Metadata
On my Linux machine,
find_package(absl)
in CMake imports dozens and dozens ofIMPORTED
library targets withabsl::
namespace scopes.For instance,
absl::time_zone
has aRelWithDebInfo
IMPORTED
SHARED
library located at${_IMPORT_PREFIX}/lib/libabsl_time_zone.so.2308.0.0
.pkg-config
metadataThe relevant
pkg-config
metadata in/usr/lib/pkgconfig/absl_time_zone.pc
is as follows:Questions
Do we recommend
absl_time_zone.cps
or do we recommend an omnibusabsl.cps
that includes models for each library shipped by theabsl
project?Should CPS files adopt
RelWithDebInfo
as an explicit default or should it be unqualified like thepkg-config
metadata?Is there currently support for "private" libraries like this? If not, should we add a tracking issue?