How can I pass git SHA1 to compiler as definition using cmake?

后端 未结 10 1844
梦毁少年i
梦毁少年i 2020-11-28 02:32

In a Makefile this would be done with something like:

g++ -DGIT_SHA1=\"`git log -1 | head -n 1`\" ...

This is very useful, because the bina

10条回答
  •  旧巷少年郎
    2020-11-28 02:37

    Here's my solution, which I think is reasonably short yet effective ;-)

    First, a file is needed in the source tree (I name it git-rev.h.in), it should looks something like this:

    #define STR_EXPAND(x) #x
    #define STR(x) STR_EXPAND(x)
    #define GIT_REV STR(GIT_REV_)
    #define GIT_REV_ \ 
     
    

    (Please never mind those macros, that's a little bit insane trick to make a string out of a raw value.) It is essential that this file has exactly one empty newline at the end so that value can be appended.

    And now this code goes in respective CMakeLists.txt file:

    # --- 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
    )
    

    This command ensuers that the git-rev.h.in is copied in the build tree as git-rev.h and git revision is appended at its end.

    So all you need to do next is include git-rev.h in one of your files and do whatever you want with the GIT_REV macro, which yields current git revision hash as a string value.

    The nice thing about this solution is that the git-rev.h is recreated each time you build the associated target, so you don't have to run cmake over and over again.

    It also should be pretty portable - no non-portable external tools were used and even the bloody stupid windows cmd supports the > and >> operators ;-)

提交回复
热议问题