Reputation: 173
I am aware that incremental linking is not a compiler feature, but a linker feature. In the past, I have used MSVC's incremental linking (/INCREMENTAL
) and now I want to use it in my project that compiles with clang
(or gcc
if need be). My project consists of three static libraries (A, B, and C) and one executable (D). As a side note, D depends B and C, while C depends on A and B.
From my understanding, all I have to do is pass -Wl,-i
to the linker (CMake uses ld
by default) as seen here. My CMakeLists.txt
looks like this:
set(LINKER_FLAGS "-Wl,-i")
add_library(A)
target_link_options(A PRIVATE ${LINKER_FLAGS})
target_link_libraries(A PRIVATE libSomeLib.so)
add_library(B)
target_link_options(B PRIVATE ${LINKER_FLAGS})
add_library(C)
target_link_options(C PRIVATE ${LINKER_FLAGS})
add_executable(D)
target_link_libraries(D PRIVATE libSomeOtherLib.so C B A)
target_link_options(D PRIVATE ${LINKER_FLAGS})
However, I get this error:
/usr/bin/ld: -r and -pie may not be used together
I then decided to run /usr/bin/ld --help
and search for these flags. I saw that -r, -i, --relocatable
are explained as Generate relocatable output
.
Changing to -Wl,-i,-nostdlib,-nostartfiles
,-Wl,-i,-nostdlib,-nostartfiles,-no-pie
or -Wl,-r
(or any combination of these flags) does not change the error message.
However, if I remove -Wl
and just use -r
, I get /usr/bin/ld: attempted static link of dynamic object libSomeOtherLib.so
.
My questions are:
ld
?-Wl
?clang++ main.cpp -Wl,-i -o main
I still get /usr/bin/ld: -r and -pie may not be used together
. Why?-Wl
flags to all targets or is it enough to set them just for my executable?Edit:
The documentation says that target_link_libraries
cannot be used to add options for static library targets, since they do not use a linker, so I have removed them from my CMakeLists.txt
(the original code is still present in the question for clarity).
Removing all target_link_options
(for the three static libraries as seen stated in the documentation) and target_link_options(D PRIVATE ${LINKER_FLAGS})
for the executable doesn't solve anything. My generator is ninja
and I can see the build commands in build.ninja
. When looking at the flags, I only see that -Wl,-i
is only passed to the executable (LINK_FLAGS = -Wl,-i
), while the three static libraries have no linker flags (explained in the documentation). So I need target_link_options(D PRIVATE ${LINKER_FLAGS})
to somehow pass -Wl,-i
to the linker.
When passing -Wl,-i
to set_property(TARGET A PROPERTY STATIC_LIBRARY_OPTIONS ${INCREMENTAL_LINKING})
, I see that ar
is called for each static library and it outputs /usr/bin/ar: invalid option -- 'W'
.
Current CMakeLists.txt
:
set(LINKER_FLAGS "-Wl,-i")
add_library(A)
set_property(TARGET A PROPERTY STATIC_LIBRARY_OPTIONS ${INCREMENTAL_LINKING})
target_link_libraries(A PRIVATE libSomeLib.so)
add_library(B)
set_property(TARGET B PROPERTY STATIC_LIBRARY_OPTIONS ${INCREMENTAL_LINKING})
add_library(C)
set_property(TARGET C PROPERTY STATIC_LIBRARY_OPTIONS ${INCREMENTAL_LINKING})
add_executable(D)
target_link_libraries(D PRIVATE libSomeOtherLib.so C B A)
target_link_options(D PRIVATE ${LINKER_FLAGS})
Upvotes: 0
Views: 809