Реальная проблема
Я хочу применить форматирование исходного кода уровня проекта ко всем измененным файлам
Текущий подход
Использовать add_custom_target
вМой файл верхнего уровня CMakeLists.txt
для вызова сценария, который применяет правила форматирования ко всем файлам, которые инструмент SCM сообщает об изменениях:
add_custom_target(Name ALL ${PROJECT_SOURCE_DIR}/../cmake/format_files.bash
)
Это правило перед любыми вызовами add_subdirectory
, потому что необходимо выполнить переформатированиедо все компиляция.
Согласно документации :
ALL
Укажите, что эта цель должна бытьдобавляется к цели сборки по умолчанию, так что она будет выполняться каждый раз (команда не может быть вызвана ALL
).
Когда запускается сам CMake
(как любая модификация файлов CMakeLists.txt
), все хорошо.
Симптом
Предположим, я выполняю некоторые изменения, связанные с пробелами, для файла Foo.hh
(мои правила, например, заменяют табуляции пробелами).Моя сборка, скорее всего, будет содержать что-то вроде этого:
Scanning dependencies of target Foo
make[2]: Warning: File `projects/foo/src/Foo.hh' has modification time 8.7 s in the future
...
make[2]: warning: Clock skew detected. Your build may be incomplete.
Я почти уверен, что это исходный скрипт форматирования, который каким-то образом запускает после сканирования зависимостей (или что-то в этом роде), изменяет Foo.hh
, и создает иллюзию перекоса часов.
Я думаю, что вопрос заключается в
Как правильно заставить мой процесс сборки утверждать стандарты проекта для стиля исходного кодадо сборки, без потенциальных проблем с зависимостями?
Есть ли лучший способ ввести форматирование в процесс сборки?
Red Herrings
Сначала ядумал, что имею дело с настоящей проблемой перекоса часов ;моя среда разработки работает на виртуальной машине VMware, и в прошлом у нас были некоторые проблемы со временем, но теперь я на 99% уверен, что все виртуальные машины используют время хоста.Более того, простой тест, подобный этому (в той же файловой системе, что и мои сборки), доказывает, что нет внутреннего отклонения тактовой частоты:
$ date ; touch foo ; ls --time-style=+%H:%M:%S -l foo ; date
Thu Jan 17 12:48:59 MST 2019
-rw-rw-r--. 1 1001 1001 0 12:48:59 foo
Thu Jan 17 12:48:59 MST 2019
Ключевым аспектом процесса форматирования исходного кода является отсутствие детерминированного способазнать, какие файлы могут быть изменены в сценарии, а какие нет.Файлы, которые соответствуют стандартам проекта, не затрагиваются.
Для полноты, вот сценарий:
#!/bin/bash
# This script is intended to format any modified files to project standards
# Change to the project root
cd $(dirname $0)/..
outfile=format.log
file_list=$( git status --short --untracked-files=all src \
| awk '/^( M|\?\?) .*\.(cpp|hh)/ {print $2}' )
# If we haven't changed any files, exit gracefully
[[ -z $file_list ]] && exit 0
# Format the current working set
echo >> ${outfile}
date '+%Y-%m-%dT%H:%M:%S.%N: ' >> ${outfile}
astyle --project $file_list >>${outfile} 2>&1
Этот сценарий добавляет к выходному файлу (я, вероятно, удалю его в какой-то момент) это выглядит так:
2019-01-17T18:54:20.641765133:
Unchanged src/Foo.cpp
Formatted src/Foo.hh
Unchanged src/Bar.cpp