Setup: modern(ish) CMake 3.31.6, main CMakeLists.txt below.
As you can see, I'm generating a version.h at cmake time.
This all works fine when I run
cmake -S . -B /tmp/build
from the project directory but, and that's problematic because it's such a common usage pattern even (and especially) in Linux distro packaging scripts,
mkdir build
cd build
cmake ..
fails, with output further down.
The problem seems to be that I can't use target_sources's FILE_SET feature if parts of the files are in CMAKE_CURRENT_BINARY_DIR if that is under the project's source root; if it's outside, everything seems fine.
Question now is:
How can I enable my users to build in a build/ directory made within the source directory in this situation?
Exhibit A: CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(
libsigf
VERSION 0.1.0
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
add_library(sigf SHARED src/libsigf.cc)
add_library(SigF::sigf ALIAS sigf)
configure_file(include/sigf/version.h.in include/sigf/version.h)
target_sources(
sigf
PUBLIC FILE_SET HEADERS BASE_DIRS
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> FILES
include/sigf/sigf.h)
target_sources(
sigf
PUBLIC FILE_SET HEADERS BASE_DIRS
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> FILES
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/sigf/version.h>)
target_include_directories(
sigf
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>)
# Installation targets
install(
TARGETS sigf
EXPORT SigFTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES
DESTINATION include
FILE_SET HEADERS)
Exhibit 2: cmake .. output
-- The CXX compiler identification is GNU 15.2.1
-- 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 (0.1s)
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
Base directories in file set cannot be subdirectories of each other:
/home/marcus/src/libsigf
/home/marcus/src/libsigf/build
CMake Error at CMakeLists.txt:12 (target_sources):
File:
/home/marcus/src/libsigf/include/sigf/sigf.h
must be in one of the file set's base directories:
CMake Error at CMakeLists.txt:17 (target_sources):
File:
/home/marcus/src/libsigf/build/include/sigf/version.h
must be in one of the file set's base directories:
-- Generating done (0.0s)
CMake Generate step failed. Build files cannot be regenerated correctly.