Custom command generating library is removed/not emited even when referenced by target_link_libraries
Hi,
Let's consider this example:
You can create bar.zip
with libbar.a
and libbar.h
to make it full, but for this issue it is not really required, if we try to unpack it we are already good.
project(Test)
cmake_minimum_required(VERSION 3.24)
add_executable(foo main.c)
target_link_libraries(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/libbar.a)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libbar.a ${CMAKE_CURRENT_BINARY_DIR}/libbar.h
COMMAND ${CMAKE_COMMAND} -E tar -zxf ${CMAKE_CURRENT_SOURCE_DIR}/bar.zip
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
# Workaround 1
# add_custom_target(bar_extract EXCLUDE_FROM_ALL
# DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libbar.a)
# Works for Ninja without add_dependencies
# add_dependencies(foo bar_extract)
# Workaround 2
# target_sources(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/libbar.h)
We have some archive and custom command to extract library that is then linked (with full path to ensure file level dependency) into foo executable. Pretty simple, but for some reason CMake prunes this command and it fails:
ninja: error: 'libbar.a', needed by 'foo', missing and no known rule to make it
or
make[2]: *** No rule to make target 'libbar.a', needed by 'foo'. Stop.
...even though we clearly have command that would generate this file, but it is nowhere to be found in build_ninja
or Makefile
.
There are at least two workarounds to make it work. Either (1) add dummy target that depends on file generated to ensure that this command is produced. Or (2) where we just add header to sources of the foo
executable.
To my understanding none of those workarounds should be needed to make it work and for some reason target_link_libraries
doesn't wire file level dependency correctly. Maybe there are some conditions that I'm not aware off?
Thanks, Kacper