Ответ 1
Вы можете установить свойство RULE_LAUNCH_COMPILE цели CMake, чтобы CMake вызывал оболочку script, которая преобразует путь исходного файла к относительный путь проекта до вызова gcc. Используйте функцию CMake configure_file для создания оболочки script, которая знает о PROJECT_SOURCE_DIR
и PROJECT_BINARY_DIR
вашего проекта.
В своем внешнем CMakeLists.txt
добавьте следующий код:
configure_file(
"${PROJECT_SOURCE_DIR}/gcc_debug_fix.sh.in"
"${PROJECT_BINARY_DIR}/gcc_debug_fix.sh"
@ONLY)
add_executable (MyExecutable ...)
set_target_properties(MyExecutable PROPERTIES
RULE_LAUNCH_COMPILE "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh")
Следующая оболочка шаблона script gcc_debug_fix.sh.in
должна перейти в корневую директорию проекта CMake:
#!/bin/sh
PROJECT_BINARY_DIR="@[email protected]"
PROJECT_SOURCE_DIR="@[email protected]"
# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE
# extract parameters
SOURCE_FILE="${@: -1:1}"
OBJECT_FILE="${@: -3:1}"
COMPILER_AND_FLAGS=${@:1:$#-4}
# make source file path relative to project source dir
SOURCE_FILE_RELATIVE="${SOURCE_FILE:${#PROJECT_SOURCE_DIR} + 1}"
# make object file path absolute
OBJECT_FILE_ABSOLUTE="$PROJECT_BINARY_DIR/$OBJECT_FILE"
cd "$PROJECT_SOURCE_DIR"
# invoke compiler
exec $COMPILER_AND_FLAGS -c "${SOURCE_FILE_RELATIVE}" -o "${OBJECT_FILE_ABSOLUTE}"
В оболочке script используется информация из переменных PROJECT_BINARY_DIR
и PROJECT_SOURCE_DIR
, чтобы преобразовать путь исходного файла к пути относительно корня проекта и пути к файлу объекта к абсолютному пути. Поскольку gcc получает относительный путь проекта, .debug_str
также должен использовать этот путь.
Применяются следующие оговорки:
- Обязательно установите исполняемый бит
gcc_debug_fix.sh.in
. - Для работы script
CMAKE_USE_RELATIVE_PATHS
необходимо снова установить наOFF
. - script делает предположения о расположении путей файла в командной строке. Это может не работать, если CMake использует другое правило для вызова компилятора. Более надежным решением было бы сканирование аргументов script для флагов
-o
и-c
.