How to check for internet connection with CMake? (automatically prevent fails if there is non)

Viewed 1046

For example, when using the ExternalProject or FetchContent module additional data can be downloaded and used within CMake. If there is no internet connection these modules fail and CMake does not finish configuration no matter if downloading was done successful once. There are flags like FETCHCONTENT_FULLY_DISCONNECTED or FETCHCONTENT_UPDATES_DISCONNECTED to prevent checks and therefore prevent failing. But these have to be set manually. (related question: cmake: external project update and a work offline).

Is it possible to check if there is a connection to afterwards set FETCHCONTENT_FULLY_DISCONNECTED automatically? How to do that? Or are there alternative ways to prevent failing of CMake if there is no internet connection?

In our case we are downloading libraries with FetchContent and than use for example find_package to make them available. Our workflow does currently not include manual adjusting of CMake Options/Variables and we do not want to add that. CMake gets all needed options by the IDEs we use, e.g. CMAKE_BUILD_TYPE or custom flags. We would need to double the targets to have a non-connection version for each existing combination. Therefore this semi-manual approach is also not feasible.

2 Answers

I found a workaround to check for a connection. Although it will not work all the time its good enough for us. I'ts based on CMake's execute_process and the questions https://stackoverflow.com/a/27590444/9909548, https://stackoverflow.com/a/6357629/9909548 and https://superuser.com/q/1406089.

execute_process(
    COMMAND ping www.google.com -n 2 -w 1000
    RESULT_VARIABLE NO_CONNECTION
)
if(NO_CONNECTION GREATER 0)
    set(FETCHCONTENT_FULLY_DISCONNECTED ON)
else()
    set(FETCHCONTENT_FULLY_DISCONNECTED OFF)
endif()

Hope its correct to add this as an answer although I will not accept it, rather than adding it to the question as a research result.

Modified answer that works with recent cmake and more platforms:

if(MSVC)
    execute_process(
        COMMAND ping www.google.com -n 2
        ERROR_QUIET
        RESULT_VARIABLE NO_CONNECTION
    )
else()
    execute_process(
        COMMAND ping www.google.com -c 2
        ERROR_QUIET
        RESULT_VARIABLE NO_CONNECTION
    )
endif()

if(NOT NO_CONNECTION EQUAL 0)
    set(FETCHCONTENT_FULLY_DISCONNECTED ON)
    message(WARNING "Fetch offline mode: requires already populated _deps")
else()
    set(FETCHCONTENT_FULLY_DISCONNECTED OFF)
endif()
Related