17

I would like to use CMake to link my project to my shared library. The library is only shared between a handful of projects and is rather small, so I would really like to build it before it is linked. Building it every time seems a better idea than having to maintain an up-to-date precompiled version, because I ten to change it together with the project. It is separate, because it contains stuff I will almost certainly need in the next project.

How can I configure CMake to do it?

My current CMakeLists.txt for the relevant project looks like this:

find_package( Boost REQUIRED COMPONENTS unit_test_framework)

include_directories(${BaumWelch_SOURCE_DIR}/../../grzesLib/src
                    ${BaumWelch_SOURCE_DIR}/src 
                    ${Boost_INCLUDE_DIRS})

if(CMAKE_COMPILER_IS_GNUCXX)
    add_definitions(-g -std=c++11 -Wall -Werror -Wextra -pedantic -Wuninitialized)
endif()


# Create the unit tests executable
add_executable(
 baumwelchtests stateindextest.cpp baumiterationtest.cpp baumwelchtest.cpp sampleparameters.cpp sdetest.cpp
 # Key includes for setting up Boost.Test
 testrunner.cpp
 # Just for handy reference
 exampletests.cpp
)

# Link the libraries
target_link_libraries( baumwelchtests ${Boost_LIBRARIES} baumwelchlib grzeslib)

but obviously the compilation fails with:

/usr/bin/ld: cannot find -lgrzeslib
Grzenio
  • 35,875
  • 47
  • 158
  • 240
  • Does it work if you add .a to the libname? – drescherjm Mar 22 '13 at 12:01
  • @drescherjm, this library is potentially not even compiled at that point, moreover I don't specify anywhere where the binary would be, so I am sure adding .a to the libname will not help. – Grzenio Mar 22 '13 at 15:07

1 Answers1

30

You mentioned you'd like to build the library rather than use a precompiled version. If the library has a CMakeList, you should add it using add_subdirectory(path/to/the/library/source/directory). It will then become a subproject of your project and you can use names of its targets normally in your CMakeList.

Note that while the command is called add_subdirectory, it can be an arbitrary directory on disk; it doesn't have to be a subdirectory of the master project's source dir. In case it's not a subdirectory, you have to explicitly specify a binary directory for it as well. Example:

add_subdirectory(/path/to/the/library/source/directory subproject/grzeslib)

The second argument, if given as a relative path, is interpreted relative to CMAKE_CURRENT_BINARY_DIR.

ssc
  • 9,528
  • 10
  • 64
  • 94
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 3
    I tried that, but I get the following error: `add_subdirectory not given a binary directory but the given source directory "/home/ga1009/PhD/cpp/grzesLib/src" is not a subdirectory of "/home/ga1009/PhD/cpp/pmi/cpp". When specifying an out-of-tree source a binary directory must be explicitly specified.`. What should I do about this one? – Grzenio Mar 22 '13 at 15:03
  • @Grzenio I've added the info to the answer. – Angew is no longer proud of SO Mar 22 '13 at 17:28
  • I get the same error of @Grzenio ... it doesn't allow me to put any arbitrary directory. – Wagner Patriota Sep 26 '16 at 18:27
  • @WagnerPatriota The answer already addresses this: you need to specify the binary directory as well when adding a non-subdir. – Angew is no longer proud of SO Sep 27 '16 at 08:32
  • it doesn't work. I do `set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..)` for example... then `add_subdirectory("../lib1")`. it still complains. :-/ – Wagner Patriota Sep 28 '16 at 22:50
  • 2
    @WagnerPatriota That's not what I meant *at all.* `CMAKE_CURRENT_BINARY_DIR` is a read-only variable (or at least should be treated as such). You need to pass the intended binary dir as second argument to `add_subdirectory`, *like the answer shows.* – Angew is no longer proud of SO Sep 29 '16 at 06:10