Page MenuHomePhabricator

[CMake] Use PUBLIC link mode for static libraries
ClosedPublic

Authored by phosek on Feb 5 2020, 7:12 PM.

Details

Summary

Using INTERFACE prevents the use of imported libraries as we've done
in 00b3d49 because these aren't linked against the target, they're
only made part of the interface. This doesn't affect the output since
static libraries aren't being linked into, but it enables the use of
imported libraries.

Diff Detail

Event Timeline

phosek created this revision.Feb 5 2020, 7:12 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 5 2020, 7:12 PM

I don't quite understand what's going on here. Are you saying that if you have a static library which depends on an imported library as INTERFACE, targets that link against the static library won't link against the imported library, but if the static library depends on the imported library as PUBLIC, targets that link against the static library will link against the imported library?

phosek added a comment.Feb 6 2020, 2:07 PM

I don't quite understand what's going on here. Are you saying that if you have a static library which depends on an imported library as INTERFACE, targets that link against the static library won't link against the imported library, but if the static library depends on the imported library as PUBLIC, targets that link against the static library will link against the imported library?

If a target A depends on a library B as INTERFACE, the library B becomes a part of A's public interface, that is any library that depends on A will "link" against B (link here doesn't just mean regular linking, but also getting appropriate header dependencies), but A itself wouldn't. In case of PUBLIC, not only B becomes part of A's public interface, A will also link against B.

I hit this problem with D74102 where Support would INTERFACE depend on ZLIB::ZLIB which means that anything depending on Support would get ZLIB::ZLIB dependency (both headers and linking where appropriate), but Support itself wouldn't which defeats the purpose of using the imported library.

I'm not sure when would the INTERFACE semantics on static libraries make sense, IIUC the intent was to avoid linking other libraries into static libraries, but that's not something that CMake would ever do since you cannot really link anything to a static library (the only other semantics that would make sense is merging static libraries together but that's not something CMake does).

smeenai accepted this revision.Feb 6 2020, 2:50 PM

Ah, right, I forgot that "linking" includes header dependencies and so on. This makes sense.

Not this diff, but won't a BUILD_SHARED_LIBS build still have issues here, since then Support will only have a PRIVATE dependency on ZLIB::ZLIB and libraries which depend on Support won't get that dependency? (And if that's not a problem, then I'm wondering why the static case needs to be PUBLIC instead of PRIVATE.)

This revision is now accepted and ready to land.Feb 6 2020, 2:50 PM

Ah, right, I forgot that "linking" includes header dependencies and so on. This makes sense.

Not this diff, but won't a BUILD_SHARED_LIBS build still have issues here, since then Support will only have a PRIVATE dependency on ZLIB::ZLIB and libraries which depend on Support won't get that dependency? (And if that's not a problem, then I'm wondering why the static case needs to be PUBLIC instead of PRIVATE.)

That should be fine since only Support needs that dependency, not its dependents as zlib API isn't exposed across the Support API/ABI boundary.

This revision was automatically updated to reflect the committed changes.