Вы можете установить свойство RULE_LAUNCH_COMPILE цели CMake, чтобы CMake вызывал сценарий оболочки, который преобразует путь к исходному файлу в относительный путь проекта, прежде чем вызывать gcc.Используйте функцию CMake configure_file для генерации сценария оболочки, который знает о 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")
Следующий шаблонный скрипт оболочки gcc_debug_fix.sh.in
должен перейти в корневой каталог проекта CMake:
#!/bin/sh
PROJECT_BINARY_DIR="@PROJECT_BINARY_DIR@"
PROJECT_SOURCE_DIR="@PROJECT_SOURCE_DIR@"
# 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}"
Скрипт оболочки использует информацию из переменных PROJECT_BINARY_DIR
и PROJECT_SOURCE_DIR
для преобразования пути исходного файла в путь относительно корня проекта и путь объектного файла к абсолютному пути.Поскольку gcc теперь проходит относительный путь проекта, .debug_str
также должен использовать этот путь.
Применяются следующие предостережения:
- Обязательно установите исполняемый бит
gcc_debug_fix.sh.in
. - Для работы сценария
CMAKE_USE_RELATIVE_PATHS
должен установить значениеOFF
снова. - Сценарий делает предположения о расположении путей к файлам в командной строке.Это может не сработать, если CMake использует другое правило для вызова компилятора.Более надежным решением будет сканирование аргументов скрипта для флагов
-o
и -c
.