Feature Request: CURL_EXECUTABLE

I was wondering if it would be possible to add to FindCURL.cmake the ability to return CURL_EXECUTABLE much like FindWget.cmake returns WGET_EXECUTABLE.

I found myself recently having to figure out how to detect if I am on an AWS EC2 system. As the preferred method is to query a URL, I wrote something like:

   find_package(CURL)
   if (CURL_FOUND)
      execute_process(
         COMMAND curl --connect-timeout 0.1 http://169.254.169.254/latest/meta-data/instance-id
         TIMEOUT 1.0
         OUTPUT_QUIET ERROR_QUIET
         RESULT_VARIABLE STATUS
         )
      if(STATUS AND NOT STATUS EQUAL 0)
         set (DETECTED_SITE ${BUILD_SITE})
      else ()
         set (DETECTED_SITE "AWS")
      endif ()

Not pretty, but it works. My only fear is that maybe (?) it is possible for CURL_FOUND to be true but curl not be in the PATH? Maybe not, but using ${CURL_EXECUTABLE} seems more “right” to me.

(Note: The URL is a bit different because the AWS Guru where I work says he uses that. I follow his lead. :smile:)

At the moment, FindCURL does not search for the curl executable. This could be searched for, and provide both a variable and an imported target.

However, there’s an easier way in your case. CMake includes file download capabilities through the file(DOWNLOAD) command (it even uses libcurl under the hood!)

@kyle.edwards Hmm. Interesting. I guess I can give that a try. I mainly went with “call curl directly” because I know looking for that URL on a non-AWS system can “lock up” as it retries. But file(DOWNLOAD) does provide TIMEOUTand INACTIVITY_TIMEOUT…

One question: what happens if you are on a system without cURL? Does it fall over to wget?

No. CMake requires libcurl to build in the first place, so it always has cURL code in the CMake executable - no curl command required!

1 Like

How very cool :slight_smile:

I’ve now switched to:

   file(DOWNLOAD http://169.254.169.254/latest/meta-data/instance-id instance-id
      INACTIVITY_TIMEOUT 1.0
      TIMEOUT 1.0
      STATUS DOWNLOAD_STATUS
      )
   list(GET DOWNLOAD_STATUS 0 RETURN_CODE)

   if (RETURN_CODE EQUAL 0)
      set (DETECTED_SITE "AWS")
   else ()
      set (DETECTED_SITE ${BUILD_SITE})
   endif ()

which seems to work. I’m debating whether I should file(REMOVE) the output. It’s 19 bytes if it exists and I wonder if some day it’ll be useful…

FYI to those who find this some day, note that if you do use file(DOWNLOAD) as I did the correct way to do so is:

   file(DOWNLOAD http://169.254.169.254/latest/meta-data/instance-id ${CMAKE_CURRENT_BINARY_DIR}/instance-id
...

or the like with a full path. Trying to use this with an Ubuntu image on CircleCI showed this.