FetchContent_Declare() via a remote ssh git command

We have a backend service node which cannot access the internet, but a CMake script which uses FetchContent_Declare() to grab submodules from GitHub. I tried to run git on a front-end server which does have access:

#!/bin/bash

# Developers to use this to provide their preferred host
if [[ -z $GIT_SSH_HOSTNAME  ]]
then
  GIT_SSH_HOSTNAME=<my server name>
fi
#Execute git on a host with remote host with internet access
SSH_CMD="ssh ${USER}@${GIT_SSH_HOSTNAME} \"cd $PWD; module load git; git $@\""
eval ${SSH_CMD}
exit_code=$?
# Works around issue with NFS cache not being up to date on the original node
# Without this CMake fails on chdir on subsequent steps
fsync $PWD &> /dev/null
exit $exit_code

with this simple test CMakeList.txt:

set(GIT_EXECUTABLE /apps_si/dev/shared/jmoellm/git-fetch/git)
 
include(FetchContent)
FetchContent_Declare(empimb
    GIT_REPOSITORY <my repos URL>
    GIT_PROGRESS   TRUE)
FetchContent_Populate(empimb)

I get this error:

bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd /apps_si/dev/shared/jmoellm/git-fetch/build/_deps/empimb-src; module load git; git for-each-ref --format=%(upstream:short) refs/heads/master'
CMake Error at /apps_si/dev/shared/jmoellm/git-fetch/build/_deps/empimb-subbuild/empimb-populate-prefix/tmp/empimb-populate-gitupdate.cmake:130 (execute_process):
  execute_process failed command indexes:

    1: "Child return code: 1"

It seems like CMake is forgetting to quote the git for-each-ref --format command properly:

cd /apps_si/dev/shared/jmoellm/git-fetch/build/_deps/empimb-src; module load git; git for-each-ref --format=%(upstream:short) refs/heads/master

CMake geneates:

--format=%(upstream:short)'

But it should be:

--format="%(upstream:short)"

Any ideas how to fix this would be much appreciated.

Thanks!

1 Like

I want to report I found the fix to this issue. The issue is the FetchContent_Declare() needs to have a minimum version of GIT_VERSION_STRING set inside of it. For example:

include(FetchContent)
FetchContent_Declare(empimb
    # Runs on frontend
    GIT_VERSION_STRING = '1.6' 
    GIT_REPOSITORY <repo ulr>
    GIT_PROGRESS   TRUE
)
1 Like

There’s something strange going on with that. There is no GIT_VERSION_STRING keyword for FetchContent_Declare(), so it’s hard to see how that could be having an effect.

I think the problem may actually be in your script where you forward the call to git. The expression $@ on its own doesn’t handle quoting properly in bash. You probably want "$@", which should do the right thing, although I’m not sure if that will be easy to get right given the way you have it embedded in an already quoted string. For more detail, see this StackOverflow Q&A: linux - How can I preserve quotes in printing a bash script's arguments - Stack Overflow