5

For a number of reasons I have to manually generate a static library through a custom command.

However, it seems that the custom command is only executed when a target specifically requests its output files.

If I try to link the generated static library with target_link_libraries, CMake complains that it cannot find a rule to generate it.

# Building library on the fly
add_custom_command(OUTPUT mylib.a
    COMMAND ...
)
add_executable(myexe main.cpp)                                                                                                                                                     
target_link_libraries(myexe mylib.a) # Fails miserably

I imagine I have to insert a target or dependency somehow between the add_custom_command call and the target_link_libraries one, but I cannot understand how to do so correctly.

Svalorzen
  • 5,353
  • 3
  • 30
  • 54

2 Answers2

1

For preserve dependency between executable and library file, you need to use full path to the library file when link with it:

target_link_libraries(my_exe ${CMAKE_CURRENT_BINARY_DIR}/mylib.a)

When use relative path, CMake expects library to be found by the linker (according to its rules), so CMake cannot adjust dependency with the library file in that case..

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • 2
    Hm, so CMake tracks only changing in the library file without binding to `add_custom_command`. Looks like you need to resort to IMPORTED library target, as described [in this question](http://stackoverflow.com/questions/31274577/custom-target-as-a-target-library-in-cmake). BTW that question looks like duplicate for yours. – Tsyvarev May 20 '17 at 10:19
  • Yeah it looks like it's the same problem, couldn't find it before. – Svalorzen May 20 '17 at 10:57
0

I've had to do this to invoke MATLAB's RTW to build DLLs for me. The function I used was add_custom_target.

add_custom_target(Name [ALL] [command1 [args1...]]
                  [COMMAND command2 [args2...] ...]
                  [DEPENDS depend depend depend ... ]
                  [BYPRODUCTS [files...]]
                  [WORKING_DIRECTORY dir]
                  [COMMENT comment]
                  [VERBATIM] [USES_TERMINAL]
                  [COMMAND_EXPAND_LISTS]
                  [SOURCES src1 [src2...]])

For you it may look like this:

add_custom_target(MyLib ALL 
                  <Put your command here>
                  COMMENT "Building MyLib"
                  )
add_executable(MyExe main.cpp)
target_link_libraries(MyExe MyLib)

If that doesn't work I've heard that you can use add_library() to create a dummy library. Then, use set_target_properties() to create an INTERFACE property for it.

Refences:

add_custom_target

Stewart
  • 4,356
  • 2
  • 27
  • 59