Getting cmake to run before building after pulling

2019-01-15 16:54发布

问题:

There is this project kept in a git repository, which we build with cmake and ninja. We are using globbing expressions/functions to collect all the source files to be compiled. That means that every time a file is added/removed, cmake has to be called to re-parse the directories.

We have seen this is bringing some time loss when somebody pulls after somebody has pushed some new file, without modifications to any of the cmake files. I say this last thing because a modification to any of the cmake files would trigger a call to cmake (by ninja), and everything would be fine.

How can I obtain that cmake is called before/when I start building again my project after pulling? (Note: it does not matter if cmake is run a little bit more than necessary, as long as it is not always)

I am building out of source, furthermore using several build directory where for example I test different compilers.

I am exploring some solutions. One using git hooks script, namely post-merge (but how can I guarantee I will retrieve the path to source/CMakeLists.txt to touch it? Can I commit the script so that it runs for everybody? It is not a public project). I don't know if it is relevant, we mainly use git through graphic interface (TortoiseGit).

The other possible solution would be using in cmake a custom target dependent on the content of .git\refs\heads directory, but I cannot think of a combination that could really work...

Some links:

  1. http://git-scm.com/book/en/Customizing-Git-Git-Hooks
  2. https://www.kernel.org/pub/software/scm/git/docs/githooks.html

CMake commands: http://www.cmake.org/cmake/help/v2.8.11/cmake.html

回答1:

Putting a post-merge script file in .git/hooks seems to do the trick:

#!/bin/sh
#

touch source/CMakeLists.txt

The execution path is apparently the root directory of the project, which is ideal for this kind of operation. I tested this by calling "pull" in the TartoiseGit context menu from one "random" subfolder of the project. Here are some instructions on how one could test the script.

Drawback: if somebody is modifying the CMakeLists.txt in his editor, with some unsaved modifications, he might lose some work if too quick in answering to the prompt "the file has changed on the disk..."


Then, to make this script part of the repository, I found the following solution that seems to be good for our (non-public) project.

1) Create a folder (e.g. zz_gitHookScripts) for git hook scripts and put the files everybody should be using. Add it to the repository.
2) Add something like this to the CMakeLists.txt, so that the files will be put in the effective directory first time cmake will be run (and, given the above, this will happen the first time we build after pulling, also the first time because CMakeLists.txt gets modified through this edit):

file(GLOB HOOK_SCRIPTS zz_gitHookScripts/*)
if (HOOK_SCRIPTS)
    file(COPY ${HOOK_SCRIPTS} DESTINATION ${CMAKE_SOURCE_DIR}/../.git/hooks) 
endif (HOOK_SCRIPTS)

In case of patches, an equivalent post-applypatch hook might be used.

Drawbacks:

  • it is not triggered in case of stash (a user stashing a change which adds/removes files, must still remember to manually run cmake), or in case of a patch
  • users cannot personalize the hook scripts
  • removing some hook script we don't want to use anymore might be complicated
  • in general all branches will have to share the same hooks

Anyway, like this it's good for our needs.



标签: git cmake ninja