Skip to content

Instantly share code, notes, and snippets.

@socantre
Created August 24, 2015 03:45
Show Gist options
  • Save socantre/7ee63133a0a3a08f3990 to your computer and use it in GitHub Desktop.
Save socantre/7ee63133a0a3a08f3990 to your computer and use it in GitHub Desktop.
Example of using add_custom_command and add_custom_target together in CMake to handle custom build steps with minimal rebuilding: This example untars library headers for an INTERFACE library target
set(LIBFOO_TAR_HEADERS
"${CMAKE_CURRENT_BINARY_DIR}/include/foo/foo.h"
"${CMAKE_CURRENT_BINARY_DIR}/include/foo/foo_utils.h"
)
add_custom_command(OUTPUT ${LIBFOO_TAR_HEADERS}
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CMAKE_CURRENT_SOURCE_DIR}/libfoo/foo.tar"
COMMAND ${CMAKE_COMMAND} -E touch ${LIBFOO_TAR_HEADERS}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/foo"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/libfoo/foo.tar"
COMMENT "Unpacking foo.tar"
VERBATIM
)
add_custom_target(libfoo_untar DEPENDS ${LIBFOO_TAR_HEADERS})
add_library(foo INTERFACE)
target_include_directories(foo INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include/foo")
target_link_libraries(foo INTERFACE ${FOO_LIBRARIES})
@pranavb-ca
Copy link

pranavb-ca commented Oct 27, 2022

Thank you for posting this. I am perplexed about one thing though. add_library and add_executable know that source files are present in ${CMAKE_CURRENT_SOURCE_DIR} so we don't need to explicitly mention it. But, add_custom_command needs the full path to a file in the current source directory. So,

add_custom_command(OUTPUT cross_compile_file.o
${CXX_CROSS_COMPILER} -c cross_compiled_file.cpp
MAIN_DEPENDENCY cross_compiled_file.cpp
VERBATIM)

results in no input files: cannot find cross_compiled_file.cpp error from the compiler. The behavior of cmake seems inconsistent here.
I guess the reasoning is that the custom_command could be anything so cmake isn't going to assume anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment