# Adding Curl library with Fetchcontent

**URL:** <https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269>\
**Category:** Code\
**Tags:** os:windows\
**Created:** [March 3, 2024, 12:20am UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269 "2024-03-03T00:20:45Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Saviz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/saviz/32/6194_2.png) [@Saviz](https://discourse.cmake.org/u/Saviz)\
**Post date:** [March 3, 2024, 12:20am UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/1 "2024-03-03T00:20:45Z")

</div>

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:

```auto
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.

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [March 3, 2024, 10:40am UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/2 "2024-03-03T10:40:50Z")

</div>

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()](https://cmake.org/cmake/help/latest/command/target_include_directories.html) 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](https://cmake.org/cmake/help/latest/module/FetchContent.html#integrating-with-find-package), what I would probably do is provide `OVERRIDE_FIND_PACKAGE` and then do the usual:

```auto
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.

---

<div class="post-metadata">

**Author:** ![Saviz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/saviz/32/6194_2.png) [@Saviz](https://discourse.cmake.org/u/Saviz)\
**Post date:** [March 3, 2024, 3:59pm UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/3 "2024-03-03T15:59:27Z")

</div>

> [@retif](#):
>
> But while we are here, I’d recommend you to use [target\_include\_directories()](https://cmake.org/cmake/help/latest/command/target_include_directories.html) instead (_this won’t help with your problem, it’s just a note for the future_).

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.

  

> [@retif](#):
>
> ```auto
> 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
> )
> 
> ```

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:

  

```auto
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`.

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [March 3, 2024, 4:11pm UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/4 "2024-03-03T16:11:20Z")

</div>

> I modified the keyword from `PRIVATE` to `INTERFACE`

That made those headers “unavailable” to your executable 🙂  
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:

```auto
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.

---

<div class="post-metadata">

**Author:** ![Saviz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/saviz/32/6194_2.png) [@Saviz](https://discourse.cmake.org/u/Saviz)\
**Post date:** [March 3, 2024, 5:24pm UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/5 "2024-03-03T17:24:11Z")

</div>

> [@retif](#):
>
> That made those headers “unavailable” to your executable 🙂  
> 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.

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](https://discourse.cmake.org/uploads/default/original/2X/8/8179ae179fb7800b046670af5ad1019b877d3efc.png)

---

<div class="post-metadata">

**Author:** ![Saviz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/saviz/32/6194_2.png) [@Saviz](https://discourse.cmake.org/u/Saviz)\
**Post date:** [March 3, 2024, 5:32pm UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/6 "2024-03-03T17:32:32Z")

</div>

Never mind I found the issue.

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [March 3, 2024, 6:54pm UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/7 "2024-03-03T18:54:39Z")

</div>

> found the issue

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

---

<div class="post-metadata">

**Author:** ![Saviz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/saviz/32/6194_2.png) [@Saviz](https://discourse.cmake.org/u/Saviz)\
**Post date:** [March 5, 2024, 6:33am UTC](https://discourse.cmake.org/t/adding-curl-library-with-fetchcontent/10269/8 "2024-03-05T06:33:28Z")

</div>

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.
