Search code examples
cmakedependencieslibrariescmake-custom-command

How to build and add a dependency library in CMake


For my project, I need to build and include another library, https://github.com/t-dillon/tdoku/, as my dependency.

Toku is also built using CMake, and there's a build script I can run by doing:

$ cd lib/toku
$ ./BUILD.sh

This puts the library file in ./lib/tdoku/build/libtdoku.a.

I'm trying to build the Toku library inside CMake, and use it as a dependency. How can I do this?

I tried using add_custom_target, add_custom_command, add_dependencies, add_subdirectory to no avail.

My current CMakeLists.txt looks like:

cmake_minimum_required(VERSION 3.17)
project(project_1_cpp)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion")
set(CMAKE_CXX_FLAGS_DEBUG_INIT "")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3")

add_custom_target(toku)
add_custom_command(
  TARGET toku
  COMMAND ${CMAKE_SOURCE_DIR}/lib/tdoku/BUILD.sh
  WORKING_DIR ${CMAKE_SOURCE_DIR}/lib/tdoku
)

file(GLOB project_1_src "*.cpp")
add_executable(project_1_cpp ${project_1_src})
add_dependencies(tdoku project_1_cpp)
target_link_libraries(project_1_cpp ${CMAKE_SOURCE_DIR}/lib/tdoku/build/libtdoku.a)

Solution

  • From some help of @Tsyvarev, I first changed my CMakeLists.txt to include:

    add_custom_command(
      OUTPUT ${CMAKE_SOURCE_DIR}/lib/tdoku/build/libtdoku.a
      COMMAND ${CMAKE_SOURCE_DIR}/lib/tdoku/BUILD.sh tdoku
      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/lib/tdoku
    )
    add_custom_target(project DEPENDS ${CMAKE_SOURCE_DIR}/lib/tdoku/build/libtdoku.a)
    

    The key is that WORKING_DIR does not work, and I need to instead have WORKING_DIRECTORY. I figured this part out by trying to modify the build.sh script, and having it print things to a file, so I can know if it's being run at all, and what's breaking inside the script. I realized that the script's working directory was wrong.

    In fact, I believe I did all this before posting the question, but I got the following errors after, which lead me to think that the tdoku library wasn't compiling properly. It was, but it was linking incorrectly to my project:

    /usr/bin/ld: /usr/bin/ld: DWARF error: could not find variable specification at offset 223f
    /usr/bin/ld: DWARF error: could not find variable specification at offset 22ba
    

    I googled "DWARF error: could not find variable specification", which led me to ld.exe: DWARF error: could not find variable specification at offset 101cee. Googling cmake flto led me to How do I enable link time optimization (LTO) with CMake?.

    This finally allowed me to compile my project.

    The entire list of changes include:

    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
    
    add_custom_command(
      OUTPUT ${CMAKE_SOURCE_DIR}/lib/tdoku/build/libtdoku.a
      COMMAND ${CMAKE_SOURCE_DIR}/lib/tdoku/BUILD.sh tdoku
      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/lib/tdoku
    )
    add_custom_target(project DEPENDS ${CMAKE_SOURCE_DIR}/lib/tdoku/build/libtdoku.a)