how to put compiler command line args in specific places using cmake

14,694

Solution 1

OK, it was much easier than I thought.

So according to the cmake docs:

Item names starting with '-', but not '-l' or '-framework', are treated as linker flags.

So the fix was just to:

add_library(wittyPlus SHARED empty.cpp)
target_link_libraries(wittyPlus 
    ${wtdbosqlite}
    ${WT_LIBRARIES}
    ${DB_LIBRARIES}
    ${Boost_LIBRARIES}
    "-Wl,--whole-archive"
    app models
    "-Wl,--no-whole-archive"
)

I don't know if it'll work on windows or not, I expect it will as cmake is super clever.

Looking at the result with objdump, it does seem to have a lot of boost stuff in the exports, so I might be doing something wrong.

objdump -C -t wittyPlus/libwittyPlus.so | grep -i boost

But it does have the stuff I need to link against it so, that's a step forward.

Any other answers still appreciated. Basically what I'm trying to do is the same as this question:

CMake: how create a single shared library from all static libraries of subprojects?

Solution 2

If you are building the static libraries yourself, you can use this approach: https://stackoverflow.com/a/29824424/4069571 namely building them as object libraries first, then linking them into the respective shared and static libs.

Share:
14,694
matiu
Author by

matiu

Live in Australia.

Updated on June 04, 2022

Comments

  • matiu
    matiu almost 2 years

    So I'm building a shared library, out of two static libraries.

    This answer says the way to do it is to insert -Wl,--whole-archive before my static libs, the -Wl,--no-whole-archive after them.

    So what I have in cmake at the moment for the shared library is:

    add_library(wittyPlus SHARED empty.cpp)
    target_link_libraries(wittyPlus 
        ${wtdbosqlite}
        ${WT_LIBRARIES}
        ${DB_LIBRARIES}
        ${Boost_LIBRARIES}
        app models
    )
    

    So what I need is for it to add the -Wl,--whole-archive before app and models, then -Wl,--no-whole-archive after them (so that the standard library imports don't get exported by the shared lib).

    What's the easiest way to do this in CMake ?


    Addition: So I'd like to use the standard cmake stuff as much as possible, that way I don't have to do any extra work for windows builds, as CMake kindly removes the compiler definitions that aren't supported on the platform being built.

  • Mark Lakata
    Mark Lakata almost 9 years
    Have you found a work around that doesn't require a null empty.cpp file?
  • matiu
    matiu almost 9 years
    No, I use empty.cpp all the time.
  • Mark Lakata
    Mark Lakata almost 9 years
    I looks like you can do file(WRITE empty.cpp "") if you don't want to pollute your real source tree with junk files.
  • dubbaluga
    dubbaluga over 6 years
    In case your compiler doesn't like to compile empty cpp files (error message), sacrifice a few bytes in your binary and replace the "" with something like "int dummy = 0;".
  • Erik Aronesty
    Erik Aronesty about 4 years
    on windows it's /WHOLEARCHIVE
  • Yug Singh
    Yug Singh about 4 years
    Thanks for the answer. Saved a lot of time