Synopsis: On standalone workstation, child project is not re-pulled by FetchContent unless it changes, whereas under Gitlab CI it is re-pulled every pipeline run, even if unchanged.
I have two projects, Parent and Child, each living in separate Git repos, and each built with a CMakeLists.txt (‘CML’). Child is a library, a dependency of many other projects including this Parent. Child is declared a dependency in Parent’s CML using FetchContent, pointing to GIT_REPOSITORY url (a cmake cache variable) and referencing an SHA1 commit as GIT_TAG.
Parent and Child both build successfully on standalone workstation using CMake 3.16. By ‘success’ I also mean that changes to Child’s GIT_TAG imply that re-building the Parent will trigger rebuild of Child. And for unchanged Child GIT_TAG but changes to Parent, Parent re-builds will not trigger re-builds nor re-pulls of Child.
I’m replicating my setups under Gitlab in CI pipeline, each for Parent and Child. The CI build stage invokes (cmake 3.28) cmake -G… and cmake --build…, just as in standalone workstation. The pipeline in each case caches the build and install directories for incremental re-use. FetchContent (ExternalProject) works fine pulling into the pipeline from Gitlab repository.
All works fine EXCEPT that for the pipeline which builds Parent, the Child is repeatedly re-built, even though its referenced GIT_TAG (SHA1) remains unchanged.
Attempting diagnosis, even though (I believe) file timestamps shouldn’t matter, since the Child’s GIT_TAG is an SHA1, I see upon re-running the CI pipeline, that the cached/retrieved build folder timestamps have not been otherwise altered, but…:
- The unchanged Parent’s source files pulled in from Gitlab repo have timestamps of the repo’s creation on Gitlab.
- the Parent’s object file (.o) timestamps (in the cached/retrieved build folder) remain fixed to its first/recent build, and its source is not repeatedly re-built, which is correct behavior.
- The Child’s source and object file timestamps show the time of the most recent Parent pipeline run, indicating the Child is being re-Fetched/cloned/checked-out each time. This is confirmed by unquieting the FetchContent_Quiet flag.
- If I build the Child as top-level project (its own separate pipeline), it behaves like the Parent above: its source timestamps reflect its repo creation on Gitlab.
Can anyone suggest what/why is happening and/or any diagnostic ideas?