You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.3 KiB

enable_language(C)
cmake_policy(SET CMP0095 NEW)
file(WRITE "${CMAKE_BINARY_DIR}/A.c" "void libA(void) {}\n")
file(WRITE "${CMAKE_BINARY_DIR}/C.c" "void libC(void) {}\n")
file(WRITE "${CMAKE_BINARY_DIR}/BUseAC.c" [[
extern void libA(void);
extern void libC(void);
void libB(void)
{
libA();
libC();
}
]])
file(WRITE "${CMAKE_BINARY_DIR}/mainABC.c" [[
extern void libA(void);
extern void libB(void);
extern void libC(void);
int main(void)
{
libA();
libB();
libC();
return 0;
}
]])
set(lib_dirExe "${CMAKE_BINARY_DIR}/Exe")
set(lib_dirA "${CMAKE_BINARY_DIR}/libA")
set(lib_dirB "${CMAKE_BINARY_DIR}/libB")
set(lib_dirC "${CMAKE_BINARY_DIR}/libC")
file(MAKE_DIRECTORY ${lib_dirExe})
file(MAKE_DIRECTORY ${lib_dirA})
file(MAKE_DIRECTORY ${lib_dirB})
file(MAKE_DIRECTORY ${lib_dirC})
add_library(A SHARED "${CMAKE_BINARY_DIR}/A.c")
set_property(TARGET A PROPERTY LIBRARY_OUTPUT_DIRECTORY ${lib_dirA})
add_library(C SHARED "${CMAKE_BINARY_DIR}/C.c")
set_property(TARGET C PROPERTY LIBRARY_OUTPUT_DIRECTORY ${lib_dirC})
# We doesn't need to set A as a dependency of B, because we don't need `RUNPATH` value set for B
add_library(B SHARED "${CMAKE_BINARY_DIR}/BUseAC.c")
target_link_libraries(B PRIVATE A C)
set_property(TARGET B PROPERTY LIBRARY_OUTPUT_DIRECTORY ${lib_dirB})
# We MUST have empty `RUNPATH` in A & B
set_target_properties(A B C PROPERTIES
BUILD_WITH_INSTALL_RPATH 1
)
# The executable is really workable without `RUNPATH` in B
add_executable(exe "${CMAKE_BINARY_DIR}/mainABC.c")
target_link_libraries(exe A B C)
set_property(TARGET exe PROPERTY RUNTIME_OUTPUT_DIRECTORY ${lib_dirExe})
# We MUST have `RUNPATH` in exe, not `RPATH`
# Test will pass if we have `RPATH`, because of the inheritance
target_link_options(exe PRIVATE -Wl,--enable-new-dtags)
install(CODE [[
# Work with non-installed binary, because of the RUNPATH values
set(exeFile "$<TARGET_FILE:exe>")
# Check executable is can be successfully finished
execute_process(
COMMAND "${exeFile}"
COMMAND_ERROR_IS_FATAL ANY
)
# Check dependencies resolved
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RESOLVED
PRE_INCLUDE_REGEXES "^lib[ABC]\\.so$"
PRE_EXCLUDE_REGEXES ".*"
EXECUTABLES
"${exeFile}"
)
message(STATUS "Resolved dependencies: ${RESOLVED}")
]])