0

I'm trying to follow the approach taken here to call an existing Makefile (that builds a static library) from within CMake.

My situation looks as follows

  • Static library built with a Makefile in directory project/makefile_lib
  • Another library (cmake_lib) built with CMake that depends on makefile_lib in directory project
  • Executable that uses cmake_lib also in directory project

My CMakeLists.txt in project looks as follows.

project(cmake_makefile)
cmake_minimum_required(VERSION 2.8.12)

add_subdirectory(makefile_lib)

add_library(cmake_lib cmake_lib.c)

target_include_directories(cmake_lib
    PRIVATE makefile_lib
)

target_link_libraries(cmake_lib makefile_lib)

add_executable(main main.c)

target_link_libraries(main cmake_lib)

And the CMakeLists.txt in project/makefile_lib

add_custom_target(build_makefile_lib
    ALL
    COMMAND ${CMAKE_MAKE_PROGRAM}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "makefile_lib makefile"
)

add_library(makefile_lib STATIC IMPORTED)
set_target_properties(makefile_lib
    PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libmakefile_lib.a
)

add_dependencies(makefile_lib build_makefile_lib)

According to the add_dependencies documentation:

Dependencies added to an IMPORTED target are followed transitively in its place since the target itself does not build.

From within the project directory I invoke

mkdir build
cd build/
cmake ..
make

But the Makefile in project/makefile_lib is never invoked and the build fails with cannot find -lmakefile-lib.

Interestingly, this approach works if I move the content of project/makefile_lib into project and replace the add_subdirectory command in the top-level CMakeLists.txt with the content of project/makefile_lib/CMakeLists.txt.

Why is the add_dependencies command in this case seemingly not followed transitively?

Community
  • 1
  • 1
simon
  • 1,125
  • 1
  • 10
  • 20
  • The difference is, that when your code is part of the root `CMakeLists.txt` that `WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}` points to your root `project` directory. Otherwise it points to `project/makefile_lib`. Are you sure your `makefile` is in the sub-directory? – Florian May 03 '16 at 13:00

1 Answers1

1

The problem was with the add_library command. From the documentation

The target name has scope in the directory in which it is created and below, but the GLOBAL option extends visibility.

So the solution was to add the GLOBAL option to the add_library command in the project/makefile_lib/CMakeLists.txt

add_custom_target(build_makefile_lib
    ALL
    COMMAND ${CMAKE_MAKE_PROGRAM}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "makefile_lib makefile"
)

add_library(makefile_lib STATIC IMPORTED GLOBAL)
set_target_properties(makefile_lib
    PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libmakefile_lib.a
)

add_dependencies(makefile_lib build_makefile_lib)

Edit: Note that this does not work for CMake versions <= 2.8.7 where the GLOBAL flag does not yet exist. See here for a possible workaround.

simon
  • 1,125
  • 1
  • 10
  • 20