Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Case Study: absl_time_zone #36

Open
bretbrownjr opened this issue Feb 27, 2024 · 7 comments
Open

Case Study: absl_time_zone #36

bretbrownjr opened this issue Feb 27, 2024 · 7 comments
Labels
documentation This issue describes a problem which can be addressed by documentation rather than a schema change. question The issue asks for information and will likely not result in a change to the specification.

Comments

@bretbrownjr
Copy link
Collaborator

bretbrownjr commented Feb 27, 2024

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 other absl 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 of IMPORTED library targets with absl:: namespace scopes.

For instance, absl::time_zone has a RelWithDebInfo IMPORTED SHARED library located at ${_IMPORT_PREFIX}/lib/libabsl_time_zone.so.2308.0.0.

pkg-config metadata

The relevant pkg-config metadata in /usr/lib/pkgconfig/absl_time_zone.pc is as follows:

prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib
includedir=/usr/include

Name: absl_time_zone
Description: Abseil time_zone library
URL: https://abseil.io/
Version: 20230802
Requires:
Libs: -L${libdir}  -labsl_time_zone 
Cflags: -I${includedir} -DNOMINMAX

Questions

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?

Should CPS files adopt RelWithDebInfo as an explicit default or should it be unqualified like the pkg-config metadata?

Is there currently support for "private" libraries like this? If not, should we add a tracking issue?

@bretbrownjr bretbrownjr added question The issue asks for information and will likely not result in a change to the specification. documentation This issue describes a problem which can be addressed by documentation rather than a schema change. labels Feb 27, 2024
@dcbaker
Copy link
Collaborator

dcbaker commented Feb 27, 2024

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

@mwoehlke
Copy link
Member

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.

@bretbrownjr
Copy link
Collaborator Author

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.

@mwoehlke
Copy link
Member

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.

@dcbaker
Copy link
Collaborator

dcbaker commented Feb 29, 2024

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's naming scheme is Qt<Version><Component>, so Qt6Core.pc
  • Gnome tends to favor <name>-<major_version>.0, so `gtk+-3.0
  • Xorg lists their libraries by just component name, or by x11-<component>, so we have both glproto and x11-xcb
  • pixman uses pixman-1
  • OpenMPI uses ompi-<language interface>, so ompi-c, ompi-cxx, ompi-fort

@dcbaker
Copy link
Collaborator

dcbaker commented Feb 29, 2024

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.

@mwoehlke
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation This issue describes a problem which can be addressed by documentation rather than a schema change. question The issue asks for information and will likely not result in a change to the specification.
Projects
None yet
Development

No branches or pull requests

3 participants