Вот мое решение, которое я считаю достаточно коротким, но эффективным; -)
Во-первых, в исходном дереве необходим файл (я называю его git-rev.h.in
), он должен выглядеть примерно так:
#define STR_EXPAND(x) #x
#define STR(x) STR_EXPAND(x)
#define GIT_REV STR(GIT_REV_)
#define GIT_REV_ \
(Пожалуйста, не берите в голову эти макросы, это немного безумный трюк, чтобы сделать строку из необработанного значения.)
Крайне важно, чтобы в конце этого файла была точно одна пустая новая строка, чтобы можно было добавить значение.
А теперь этот код идет в соответствующем CMakeLists.txt
файле:
# --- Git revision ---
add_dependencies(your_awesome_target gitrev) #put name of your target here
include_directories(${CMAKE_CURRENT_BINARY_DIR}) #so that the include file is found
set(gitrev_in git-rev.h.in) #just filenames, feel free to change them...
set(gitrev git-rev.h)
add_custom_target(gitrev
${CMAKE_COMMAND} -E remove -f ${CMAKE_CURRENT_BINARY_DIR}/${gitrev}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${gitrev_in} ${CMAKE_CURRENT_BINARY_DIR}/${gitrev}
COMMAND git rev-parse HEAD >> ${CMAKE_CURRENT_BINARY_DIR}/${gitrev}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} #very important, otherwise git repo might not be found in shadow build
VERBATIM #portability wanted
)
Эта команда приводит к тому, что git-rev.h.in
копируется в дерево сборки как git-rev.h
, а в его конце добавляется ревизия git.
Итак, все, что вам нужно сделать дальше, это включить git-rev.h
в один из ваших файлов и делать все, что вы хотите с макросом GIT_REV
, который возвращает текущий хэш редакции git в виде строкового значения.
Приятной особенностью этого решения является то, что git-rev.h
воссоздается каждый раз, когда вы создаете связанную цель, поэтому вам не нужно запускать cmake
снова и снова.
Он также должен быть довольно переносимым - никакие непереносимые внешние инструменты не использовались, и даже чертовски тупой windows cmd поддерживает операторы >
и >>
; -)