3

I am using CMake on a linux environment using cmake 2.8.1. I also tried cmake 2.8.7 with the same results.

I need to do some special conditioning on an archive (static library). This is done as a cmake custom_command. The result is a new archive that should be used in the link of the executable. The input archive for the conditioning is also a cmake target.

What I need is a dependency between the conditioned version of the archive and the executable. Using add_dependencies doesn't work and I don't undestand why.

I created an example that shows that behaviour of cmake. The example contains 2 C Files, one for the archive and one containing main(). As simple archive conditioning I just make a copy of the previously generated archive.

Here are the 2 source files:

main.c:

int myPrint(void);

int main(void)
{
  myPrint();
}

mylib.c:

#include <stdio.h>

int myPrint(void)
{
  printf("Hello World\n");
}

This is the CMakeLists.txt I created:

cmake_minimum_required(VERSION 2.8)

project(cmake_dependency_test)

add_library(mylib STATIC mylib.c)

add_custom_command(OUTPUT libmylib_conditioned.a
                   COMMAND cp libmylib.a libmylib_conditioned.a
                   DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libmylib.a
                   COMMENT "Conditioning library")
add_custom_target(conditioning DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libmylib_conditioned.a)
add_dependencies(conditioning mylib)

add_executable(cmake_dependency_test main.c)
add_dependencies(cmake_dependency_test conditioning)
target_link_libraries(cmake_dependency_test -L. mylib_conditioned)

First I create the archive mylib. With add_custom_command I do the conditioning and add_custom_target provides a top level target for the conditioned archive. Since I need to update the input archive before the conditioned archive is built I added a dependency between the input archive top level target and the conditioned archive top level target. This works perfectly! When I touch mylib.c and run make conditioning the input archive is built and after that the conditioned archive.

Ok. Now I use the conditioned archive for linking. In order to have a dependency from the executable to the conditioned archive I used again add_dependencies. But touching the library source mylib.c and then running make will not update the executable as expected.

Where is the mistake in the CMakeLists.txt?

2 Answers 2

2

You can try to set the target property LINK_DEPENDS for the target cmake_dependency_test.

...
add_executable(cmake_dependency_test main.c )  
set_property(TARGET cmake_dependency_test PROPERTY LINK_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libmylib_conditioned.a)  
add_dependencies(cmake_dependency_test conditioning mylib)
target_link_libraries(cmake_dependency_test -L. mylib_conditioned)
Sign up to request clarification or add additional context in comments.

2 Comments

This could be an alternative for the depend. What is not working for me is the dependency of the executeable from the custom_command.
I edited the answer. I tested it on Windows, but I hope it works for you to.
0

tl;dr: No mistake, it now works.

There is no mistake in your CMakeLists.txt, just a bug or missing bit of implementation in CMake.

With more recent versions of CMake, it will work. I recommend setting the minimum required version as high as you can (since it's very easy to get a recent version of CMake - the distributed binaries run almost anywhere since they have almost no shared-lib dependencies.) - to get newer behavior, avoid deprecation warnings etc.

If I set:

cmake_minimum_required(VERSION 3.3)

and configure, I get:

-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/delme/build

and when I build (with GNU Make in my case), I get:

[ 20%] Building C object CMakeFiles/mylib.dir/mylib.c.o
[ 40%] Linking C static library libmylib.a
[ 40%] Built target mylib
[ 60%] Conditioning library
[ 60%] Built target conditioning
[ 80%] Building C object CMakeFiles/cmake_dependency_test.dir/main.c.o
[100%] Linking C executable cmake_dependency_test
[100%] Built target cmake_dependency_test

So, problem solved, and it only took 9 years :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.