C++ Logo

sg15

Advanced search

Re: Packaging: Where should "library interface object files" live?

From: David Blaikie <dblaikie_at_[hidden]>
Date: Wed, 14 Feb 2024 07:27:06 -0800
+1 to Daniel's perspective.

The counterargument/use cases mentioned in the linked bug (
https://github.com/llvm/llvm-project/issues/80639 ) are concerns around ABI
stability across different flags/options.

My gut reaction is that (having consumers build the modular objects) is not
how we should encourage people to write/distribute modules - and if ABI
stability is an issue, like libc++ does for non-modular code, they can
force/ensure that certain features that are ABI unstable, do not appear in
the modular object through marking those features always_inline or whatever
other techniques they're using today.

Though, for argument's sake - how bad would it be if projects got to choose
which way they wanted to distribute the modular objects (prebuilt &
available in the library versus consumer built) - while still insisting
that there are no interface-only modular libraries (you have to make a
.a/.so anyway, even if it's empty, to mark where your module description
json is). Seems harder to convince people of th elatter, and there's a risk
the ecosystem evolves to support interface-only modular libraries, which
then makes discovery more complicated/less consistent...

On Tue, Feb 13, 2024 at 9:29 AM Daniel Ruoso via SG15 <sg15_at_[hidden]>
wrote:

> So far, my expectation has been that the library will ship with the
> objects produced from the interface files, and that when importing a module
> from a pre-built library, the build system should produce only the BMI.
>
> Are there any use cases that drive the other approach?
>
> Daniel
>
> On Tue, Feb 13, 2024, 11:11 Jan Kokemüller via SG15 <sg15_at_[hidden]>
> wrote:
>
>> Hi,
>>
>> let's say I'm packaging a modularized C++ library "foo" that consists of a
>> module implementation unit "foo.cpp" and an importable module unit
>> "foo.cppm".
>> Where should the "library interface object files" live? In the
>> "libfoo.{a,so}"
>> I ship, or can I punt this task to the consumer, who will compile the
>> importable module unit "foo.cppm" anyway (to get the BMI's)?
>>
>> With "library interface object files" I mean the object files that are
>> generated by compiling the importable module unit "foo.cppm". I'm using
>> the
>> terminology from Daniela Engert's talk here:
>> <https://youtu.be/nP8QcvPpGeM?t=333>
>>
>> At least with Clang, the "library interface object files" will at least
>> contain
>> the symbol for the "module initializer function" as laid out by the
>> proposed
>> updates to the Itanium ABI:
>> <
>> https://github.com/itanium-cxx-abi/cxx-abi/pull/144/files#diff-b803017e5afd1b6dfe35e5e0e719d895559129c35b93f056074a72928269ae23R5022-R5048
>> >
>>
>> So far I had assumed from following discussions and from my own
>> experiments
>> with CMake >= 3.28 and reading Conan's plan
>> (<https://blog.conan.io/2023/10/17/modules-the-packaging-story.html>)
>> that the
>> "library interface object files" (that contain e.g. the symbols for the
>> module
>> initializer functions) will live in the library artifact "libfoo.{a,so}".
>> That
>> way, as a consumer of that library, I can describe that library in my
>> CMake
>> build system by creating an "imported" CMake target, without having to
>> build
>> anything else except for the BMI's of the importable module units.
>>
>> Furthermore, I had also assumed that the P2577R2 style metadata file that
>> describes the modules of a library is placed next to a library artifact
>> that
>> contains the "library interface object files" (including the module
>> initializer
>> symbols). That is also the reason I thought there always _exists_ a
>> library
>> artifact for the metadata file to be placed next to, as the library
>> artifact
>> will always at least contain the module initializer symbol.
>>
>> In contrast, an alternative style of packaging a modularized library is
>> possible, where the library artifact does _not_ contain the "library
>> interface
>> object files", instead requiring the consumer to build them in addition
>> to the
>> BMI's. In CMake terms, users then could _not_ create an "imported" library
>> target, instead having to add a "proper" library target to their build
>> that
>> "owns" the "library interface object files".
>>
>> In my mind, this alternative style creates a number of headaches for the
>> build
>> and packaging ecosystems as they have to cope with those additional
>> libraries
>> required for holding the "library interface object files". It would
>> certainly
>> be simpler for consumers if those symbols where "owned" by the library
>> artifact
>> itself.
>>
>> I stumbled across this issue as I was trying to consume the experimental
>> libc++
>> "std" module. libc++ chose the second approach, i.e. the module
>> initializer
>> symbols are not packaged up in any library artifact provided by libc++.
>> In the
>> resulting discussion on the libc++ bug tracker
>> (<https://github.com/llvm/llvm-project/issues/80639>) people have
>> encouraged me
>> to approach SG15.
>>
>> What do you think about this issue? I'm curious about use cases for the
>> alternative packaging approach. Certainly there would need to be another
>> key
>> like "library-contains-interface-object-files" in the metadata file so
>> that
>> users know what kind of packaging approach was used. But I hope there can
>> be
>> convergence on one approach so that kind of complexity could be avoided.
>>
>> -Jan
>> _______________________________________________
>> SG15 mailing list
>> SG15_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>>
> _______________________________________________
> SG15 mailing list
> SG15_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>

Received on 2024-02-14 15:27:18