Skip to content

CMake: Install _TestingInternals in static library builds #651

New issue

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

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

Already on GitHub? # to your account

Merged

Conversation

kateinoigakukun
Copy link
Member

@kateinoigakukun kateinoigakukun commented Aug 29, 2024

When building the Testing library as a static library (BUILD_SHARED_LIBS=FALSE), _TestingInternals is not included in the libTesting.a archive by default. (when building as a shared library, libTesting.so includes _TestingInternals objects). This causes the linker to complain about missing symbols, so we need to ship lib_TestingInternals.a and autolink it too.

This change is required to ship swift-testing as a part of Swift SDK for WebAssembly

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

@grynspan
Copy link
Contributor

@etcwilde @rintaro Please review.

@grynspan grynspan added wasi/wasm 🧭 WebAssembly support build 🧱 Affects the project's build configuration or process swift-6.1 labels Aug 29, 2024
Comment on lines 99 to 100
set_property(TARGET Testing PROPERTY STATIC_LIBRARY_OPTIONS
$<TARGET_OBJECTS:_TestingInternals>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reasons not to use target_link_options(Testing $<TARGET_OBJECTS:_TestingInternals>)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note This command cannot be used to add options for static library targets, since they do not use a linker. To add archiver or MSVC librarian flags, see the STATIC_LIBRARY_OPTIONS target property.

https://cmake.org/cmake/help/latest/command/target_link_options.html

Yes, it's intentional. Options specified to target_link_options are passed only when linking but not archiving, so we need to use STATIC_LIBRARY_OPTIONS here.

Copy link
Contributor

@etcwilde etcwilde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, this is kind of how static archives work, there should be a lib_TestingInternals.a that libTesting.a depends on.
You'll have to remove the dependency on _TestingInternals.a or you'll have duplicate symbols.
I think rather than going through the link options, you can actually list the objects as "sources" to the target, so

add_library(BlahBlah ...)

# ...

target_sources(BlahBlah PRIVATE $<TARGET_OBJECTS:_TestingInternals>)

which I think looks a bit cleaner than mucking with the properties directly.

Are you testing with older versions of CMake as well? I seem to recall the old build model having no idea how to deal with object files getting linked into a Swift target so it would just omit them.

@compnerd, do you have opinions here?

Edit:

Are you testing with older versions of CMake as well? I seem to recall the old build model having no idea how to deal with object files getting linked into a Swift target so it would just omit them.

Hmm, I suppose that's why you'd be passing them as link flags instead of sources.

@grynspan
Copy link
Contributor

We definitely would prefer it not to be possible to directly link to _TestingInternals as it's not, as the name suggests, public. It's definitely not ABI- or API-stable and just houses our C++ gunk.

@etcwilde
Copy link
Contributor

From the shared library perspective, that's fine, they have things like "visibility". But that's not really one of the facilities that static archives provide in general. Whether it's all in one archive or two, the symbols are still there for the poking. If people do poke at it, that's on them though.

TBH, we should probably update the minimum CMake version and take the sources that are currently going into lib_TestingInternals.a and shove them directly into libTesting.a. Then there is no _TestingInternals library to link against. The difference here is that we

@grynspan
Copy link
Contributor

… is that we…?

@etcwilde
Copy link
Contributor

That's likely me talking to future me. :)

@compnerd
Copy link
Member

I think that I would prefer that we expose the internal library. The way that you build the library matters as that is encoded into the module and the static nature of the library (e.g. if _TestingInternals is static and Testing is dynamic, the modules would be isolated but then merged into a single library and _TestingInternals would be fully internalized).

@kateinoigakukun kateinoigakukun force-pushed the yt/bundle-cpp-objs-static branch from a4a69d9 to fa7c0f3 Compare September 3, 2024 18:22
@kateinoigakukun kateinoigakukun changed the title CMake: Merge private dependencies into single static objects archive CMake: Install _TestingInternals in static library builds Sep 3, 2024
@kateinoigakukun
Copy link
Member Author

I like @compnerd's option as its simplicity and it does not require the new split build model in CMake.
Updated the change to do that.

# type: The type of the library (STATIC_LIBRARY, SHARED_LIBRARY, or EXECUTABLE).
# Typically, the value of the TYPE target property.
# result_var_name: The name of the variable to set
function(get_swift_install_lib_dir type result_var_name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of wonder if we should factor this out into its own module, sort of like GNUInstallDirs, and have it set a bunch of cached variables so that it's easier for distributors to override? Would be fine for a different PR though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should bother. I'd really rather just sink this down into CMake itself and support install(TARGETS ...) properly for Swift targets.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way, the library installation directory of swift-testing is a bit different than the conventional one (not lib/swift/<os> but lib/swift/<os>/testing on darwin), so we need a project specific logic that cannot be shared across packages.

@etcwilde
Copy link
Contributor

etcwilde commented Sep 6, 2024

CC @compnerd

# type: The type of the library (STATIC_LIBRARY, SHARED_LIBRARY, or EXECUTABLE).
# Typically, the value of the TYPE target property.
# result_var_name: The name of the variable to set
function(get_swift_install_lib_dir type result_var_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should bother. I'd really rather just sink this down into CMake itself and support install(TARGETS ...) properly for Swift targets.

When building the Testing library as a static library
(BUILD_SHARED_LIBS=FALSE), `_TestingInternals` was not being installed
alongside the main library. This caused the missing symbol error when
linking against the Testing library statically.
@kateinoigakukun kateinoigakukun force-pushed the yt/bundle-cpp-objs-static branch from fa7c0f3 to ed97c9c Compare September 8, 2024 04:23
@kateinoigakukun
Copy link
Member Author

@swift-ci test

@kateinoigakukun kateinoigakukun merged commit f078f7a into swiftlang:main Sep 8, 2024
3 checks passed
@grynspan grynspan added this to the Swift 6.1 milestone Sep 10, 2024
stmontgomery added a commit that referenced this pull request Sep 17, 2024
- **Explanation**: Switch to the official [600.0.0
tag](https://github.com/swiftlang/swift-syntax/releases/tag/600.0.0) for
swift-syntax, which was recently created.
- **Original PR**: [#651
https://github.com/swiftlang/swift-testing/pull/672](https://github.com/swiftlang/swift-testing/pull/690)
- **Risk**: Low
- **Testing**: Tested in ci.swift.org
- **Reviewer**: @grynspan @briancroom
stmontgomery added a commit that referenced this pull request Sep 20, 2024
- **Explanation**: Switch to the official [600.0.0
tag](https://github.com/swiftlang/swift-syntax/releases/tag/600.0.0) for
swift-syntax, which was recently created.
- **Original PR**: [#651
https://github.com/swiftlang/swift-testing/pull/672](https://github.com/swiftlang/swift-testing/pull/690)
- **Risk**: Low
- **Testing**: Tested in ci.swift.org
- **Reviewer**: @grynspan @briancroom
grynspan pushed a commit that referenced this pull request Sep 24, 2024
- **Explanation**: When building the Testing library as a static library
(BUILD_SHARED_LIBS=FALSE), `_TestingInternals` is not included in the
`libTesting.a` archive by default. (when building as a shared library,
`libTesting.so` includes `_TestingInternals` objects). This causes the
linker to complain about missing symbols, so we need to ship
`lib_TestingInternals.a` and autolink it too.
- **Original PR**: #651
#672
- **Risk**: Low; NFC for non WASI platforms
- **Testing**: Tested in ci.swift.org
- **Reviewer**: @grynspan @briancroom
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
build 🧱 Affects the project's build configuration or process wasi/wasm 🧭 WebAssembly support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants