Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake dependencies: force recompile on external library change

Tags:

cmake

ada

I'm trying to correctly manage a dependency of a target on a externally built library, and somehow I'm not succeeding. I have read tutorials, posts and examples aplenty and yet, since I'm new to CMake, I guess I'm missing some obvious thing.

Setup is as follows. An external library built in another (CMake unsupported) language produces a libadatest.a. I've used ExternalProject_Add for this. Then, there is another regular C target that uses this lib. Everything works fine, but if I change the original lib, even if I recompile it, the C target is not recompiled. Here is a complete sample. I'm using CMake 2.8.12:

cmake_minimum_required(VERSION 2.8)    
include(ExternalProject)

ExternalProject_Add(
    AdaTestExternal # Not important
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
    BUILD_COMMAND gprbuild -P${CMAKE_CURRENT_SOURCE_DIR}/adalibtest -XOBJ_DIR=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY} -XLIB_DIR=${CMAKE_CURRENT_BINARY_DIR}
    ALWAYS 1    # Force build, gprbuild will take care of dependencies
    # BUILD_ALWAYS 1 # For 3.0 higher versions?
    INSTALL_COMMAND ""
)
add_custom_target(AdaTest DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libadatest.a)
link_directories(${CMAKE_CURRENT_BINARY_DIR}) # Needed or won't find it

add_executable(main_ada main.c)
add_dependencies(main_ada AdaTest) # We must depend on the final output lib
target_link_libraries(main_ada adatest)

What I've attempted is to create an intermediate custom target which depends on the actual library, and in turn make the main C target depend on this target.

When I remove the externally built library (libadatest.a), that's properly externally recompiled but the main executable is not re-linked. Plainly seen in that the timestamp of the library is fresher than the executable which uses it.

I've also tried this instead of the custom target, with same negative result:

add_library(AdaTest
    UNKNOWN IMPORTED
    IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libadatest.a)
like image 308
Álex Avatar asked Jul 01 '15 12:07

Álex


1 Answers

Found the proper solution (which was, as expected, simple) in this old post: http://www.cmake.org/pipermail/cmake/2010-November/041072.html

The gist is to use the actual file in target_link_libraries, so its timestamp is checked. So no need for intermediate or custom dependencies:

set(AdaTestLib ${CMAKE_CURRENT_BINARY_DIR}/libadatest.a)

add_executable(main_ada main.c)
add_dependencies(main_ada AdaTestExternal)
target_link_libraries(main_ada ${AdaTestLib})
like image 140
Álex Avatar answered Sep 24 '22 07:09

Álex