Adding Curl library with Fetchcontent

I am attempting to include the third-party Curl library as a dependency in my C++ project using CMake. I searched for instructions on how to accomplish this using the FetchContent command, and I found the following:

include(FetchContent)

FetchContent_Declare(curl
	URL https://curl.se/download/curl-8.5.0.tar.gz
	DOWNLOAD_EXTRACT_TIMESTAMP true
)

FetchContent_MakeAvailable(curl)

include_directories(${CURL_INCLUDE_DIRS})

target_link_libraries(${EXECUTABLE_NAME} ${CURL_LIBRARIES})

However, upon attempting to build my project, I encounter the following error:

"Fatal error: curl/curl.h no such file or directory"

This clearly indicates that it cannot find the header file. However, I am honestly out of options as I have no clue why the following command does not resolve the issue:

include_directories(${CURL_INCLUDE_DIRS})

Any help is highly appreciated.

If you print CURL_INCLUDE_DIRS with message(), you will most likely see that it’s empty, which would explain why include_directories() has no effect. But while we are here, I’d recommend you to use target_include_directories() instead (this won’t help with your problem, it’s just a note for the future).

So, what happens here, I am not exactly sure, as I’ve never used FetchContent myself before, but looks like it doesn’t populate CURL_INCLUDE_DIRS variable (I see only curl_SOURCE_DIR and curl_BINARY_DIR being populated).

Looking at the documentation, what I would probably do is provide OVERRIDE_FIND_PACKAGE and then do the usual:

FetchContent_Declare(curl
    URL https://curl.se/download/curl-8.5.0.tar.gz
    DOWNLOAD_EXTRACT_TIMESTAMP true
    OVERRIDE_FIND_PACKAGE # this one
)

FetchContent_MakeAvailable(curl)

find_package(curl) # probably with CONFIG REQUIRED
target_link_libraries(${EXECUTABLE_NAME}
    PRIVATE
        CURL::libcurl # or CURL::libcurl_shared, or whatever is the target name
)

As a bonus, in this case setting the include directories will (should) be taken care of, so you won’t need to do that yourself.

1 Like

You are absolutely right, and I actually observed the same thing. I was simply exhausted and opted not to delve into details that wouldn’t have mattered at the time. Nevertheless, I appreciate your input.


I attempted to implement your solution, but unfortunately, I encountered the same error indicating that it couldn’t locate the file or directory named (curl/curl.h). Here is the code I used:


FetchContent_Declare(curl
	URL https://curl.se/download/curl-8.5.0.tar.gz
	DOWNLOAD_EXTRACT_TIMESTAMP true
	OVERRIDE_FIND_PACKAGE
)

FetchContent_MakeAvailable(curl)

find_package(curl)

target_link_libraries(${EXECUTABLE_NAME}
	INTERFACE
	CURL::libcurl CURL::curl
)

Please note that I modified the keyword from PRIVATE to INTERFACE because I’m unable to directly link against an executable with PRIVATE.

I modified the keyword from PRIVATE to INTERFACE

That made those headers “unavailable” to your executable :slight_smile:
Only PRIVATE or PUBLIC would make them “available” for your target. If you can’t use PRIVATE (why not?), perhaps you could try with PUBLIC then.

If neither works (that would be surprising), as the last resort you could perhaps try this abomination:

target_include_directories(${EXECUTABLE_NAME}
    PRIVATE
        "${curl_SOURCE_DIR}/include"
)

and something similar for target_link_libraries().

But I feel like I might be missing something here (like I said, I don’t know much about FetchContent), so it would make sense to wait for a reply from someone with an actual experience.

This is what the error says and as far as I can tell the only simple way to resolve it is to use INTERFACE keyword:

Error

Never mind I found the issue.

found the issue

Imagine the face of someone who’ll end up here from googling the same problem :slight_smile:

The situation is quite funny and hard to believe. I accidentally used:

target_link_libraries(${EXECUTABLE_NAME} PRIVATE CURL::curl CURL::libcurl)

Instead of simply using:

target_link_libraries(${EXECUTABLE_NAME} PRIVATE CURL::libcurl)

Basically, it seems like the module CURL::curl either doesn’t exist or was written incorrectly.

1 Like