From the CMake Cookbook, I see that we can use the command add_custom_command
and add_custom_target
to run a custom command at build time. There is a toy example that I want to extract compressed files in subdirectory and link it to the final executable files. We have two CMakeLists.txt
files and the following one is in the subdirectory.
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
set(MATH_SRCS
${CMAKE_CURRENT_BINARY_DIR}/wrap_BLAS_LAPACK/CxxBLAS.cpp
${CMAKE_CURRENT_BINARY_DIR}/wrap_BLAS_LAPACK/CxxLAPACK.cpp
${CMAKE_CURRENT_BINARY_DIR}/wrap_BLAS_LAPACK/CxxBLAS.hpp
${CMAKE_CURRENT_BINARY_DIR}/wrap_BLAS_LAPACK/CxxLAPACK.hpp
)
add_custom_target(BLAS_LAPACK_wrappers
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${MATH_SRCS}
COMMENT
"Intermediate BLAS_LAPACK_wrappers target"
VERBATIM
)
add_custom_command(
OUTPUT
${MATH_SRCS}
COMMAND
${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMENT
"Unpacking C++ wrappers for BLAS/LAPACK"
)
add_library(math "")
target_sources(math
PRIVATE
${MATH_SRCS}
)
target_include_directories(math
INTERFACE
${CMAKE_CURRENT_BINARY_DIR}/wrap_BLAS_LAPACK
)
# BLAS_LIBRARIES are included in LAPACK_LIBRARIES
target_link_libraries(math
PUBLIC
${LAPACK_LIBRARIES}
)
The following CMakeLists.txt
is in the main directory.
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# Fortran needed to discover LAPACK with some compilers
project(recipe-04 LANGUAGES CXX Fortran)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(deps)
add_executable(linear-algebra linear-algebra.cpp)
target_link_libraries(linear-algebra
PRIVATE
math
)
I do not know why we need the add_custom_target
in this example.