Search code examples
c++cmakelinkerstatic-libraries

How to properly link to libraries in CMake (using Boehm GC)?


I've been trying to figure this out for a while, but can't seem to get it working. I've already checked a bunch of posts.

I have a static library libRuntime.a, generated like so:

cmake_minimum_required(VERSION 3.15)
project(Runtime)

set(CMAKE_CXX_STANDARD 17)

add_library(Runtime library.cpp)
find_library(GC gc)
message(${GC})
target_link_libraries(Runtime PUBLIC ${GC})

library.cpp uses Boehm GC, which is why I'm also linking it with my Runtime target.

Now, I want to call functions from my libRuntime.a, so I have the following other CMake project:

cmake_minimum_required(VERSION 3.15)
project(test)

set(CMAKE_CXX_STANDARD 17)

add_executable(test main.cpp)
find_library(TESTLIB Runtime lib)
message(${TESTLIB})
target_link_libraries(test ${TESTLIB})

I have pasted library.h into the project, and also pasted libRuntime.a into a directory called lib, so the definitions are known and the library is found. Calling functions from my Runtime library now gives me:

/path.../Scheme-Compiler/Runtime/library.cpp:12: undefined reference to `GC_init'
/usr/bin/ld: ../lib/libRuntime.a(library.cpp.o): in function `alloc_atom':

Thanks in advance


Solution

  • Because you use a separate CMake invocation to create the executable, the properties of the Runtime CMake target from your first project are not known. Specifically, CMake will not know any of the Runtime library's dependencies (i.e. GC), so you have to list them explicitly when linking Runtime to your executable:

    cmake_minimum_required(VERSION 3.15)
    project(test)
    
    set(CMAKE_CXX_STANDARD 17)
    
    add_executable(test main.cpp)
    find_library(TESTLIB Runtime lib)
    message(${TESTLIB})
    
    # Find GC library.
    find_library(GC gc)
    # Link GC here, along with the Runtime library.
    target_link_libraries(test PRIVATE ${GC} ${TESTLIB})