Skip to content

Commit

Permalink
corrosion_link_libraries: Forward static libraries dependencies
Browse files Browse the repository at this point in the history
If a user tries to use `corrosion_link_libraries` on static libraries,
forward the dependencies to C/C++ consumers by internally calling
`target_link_libraries()`.
  • Loading branch information
jschwe committed Apr 23, 2024
1 parent b25a1fa commit 10da46b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
3 changes: 3 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
### New features

- Support using the `$<CONFIG>` generator expression in `OUTPUT_DIRECTORY`. [#459]
- If `corrosion_link_libraries()` is called on a Rust static library target, then
`target_link_libraries()` is called to propogate the dependencies to C/C++ consumers.
Previously a warning was emitted in this case and the arguments ignored.

### Fixes

Expand Down
16 changes: 10 additions & 6 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1071,11 +1071,15 @@ function(corrosion_set_features target_name)
endfunction()

function(corrosion_link_libraries target_name)
if(TARGET "${target_name}-static" AND NOT TARGET "${target_name}-shared")
message(WARNING "The target ${target_name} builds a static library."
"The linker is never invoked for a static libraries to link has effect "
" aside from establishing a build dependency."
)
if(TARGET "${target_name}-static")
message(DEBUG "The target ${target_name} builds a static Rust library."
"Calling `target_link_libraries()` instead."
)
target_link_libraries("${target_name}-static" INTERFACE ${ARGN})
if(NOT TARGET "${target_name}-shared")
# Early return, since Rust won't invoke the linker for static libraries
return()
endif()
endif()
add_dependencies(_cargo-build_${target_name} ${ARGN})
foreach(library ${ARGN})
Expand All @@ -1089,7 +1093,7 @@ function(corrosion_link_libraries target_name)
corrosion_add_target_local_rustflags(${target_name} "-L$<TARGET_LINKER_FILE_DIR:${library}>")
corrosion_add_target_local_rustflags(${target_name} "-l$<TARGET_LINKER_FILE_BASE_NAME:${library}>")
endforeach()
endfunction(corrosion_link_libraries)
endfunction()

function(corrosion_install)
# Default install dirs
Expand Down
10 changes: 7 additions & 3 deletions doc/src/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,21 @@ For rust `cdylib`s and `bin`s, the linker is invoked via `rustc` and CMake just

When CMake invokes the linker, everything is as usual. CMake will call the linker with
the compiler as the linker driver and users can just use the regular CMake functions to
modify linking behaviour. The corrosion functions mentioned below have **no effect**.
modify linking behaviour. `corrosion_set_linker()` has **no effect**.
As a convenience, `corrosion_link_libraries()` will forward its arguments to `target_link_libraries()`.

#### Rustc invokes the linker

Rust `cdylib`s and `bin`s are linked via `rustc`. Corrosion provides several helper functions
to influence the linker invocation for such targets.

`corrosion_link_libraries()` is essentially the equivalent to `target_link_libraries()`,
if the target is a rust `cdylib` or `bin`.
`corrosion_link_libraries()` is a limited version of `target_link_libraries()`
for rust `cdylib` or `bin` targets.
Under the hood this function passes `-l` and `-L` flags to the linker invocation and
ensures the linked libraries are built first.
Much of the advanced functionality available in `target_link_libraries()` is not implemented yet,
but pull-requests are welcome! In the meantime, users may want to use
`corrosion_add_target_local_rustflags()` to pass customized linking flags.

`corrosion_set_linker()` can be used to specify a custom linker, in case the default one
chosen by corrosion is not what you want.
Expand Down

0 comments on commit 10da46b

Please sign in to comment.