0

So I have the following CMakeLists.txt file

cmake_minimum_required(VERSION 3.15)

include(FetchContent)
FetchContent_Declare(
    some_software
    GIT_REPOSITORY https://github.com/some_company/some_software
    GIT_TAG master
)
FetchContent_MakeAvailable(some_software)

set(CMAKE_TOOLCHAIN_FILE "${some_software_SOURCE_DIR}/toolchain.cmake")

project(my_software)

message("CMAKE_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE}")
message("CMAKE_C_COMPILER ${CMAKE_C_COMPILER}")
message("CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER}")

...

in which I first want to download and install some 3rd party library and then set the toolchain file to some toolchain.cmake file in the directory of the 3rd party library because I require cross-compiler tools.

For some reason, however, the set(CMAKE_TOOLCHAIN_FILE ...) after the FetchContent_MakeAvailable(some_software) is ignored. Actually, the CMAKE_TOOLCHAIN_FILE variable points to the correct toolchain.cmake file, but the CMAKE_C_COMPILER variables are not updated to the cross-compiler tools (when project(my_software) is called) but instead point to the standard tools. The message(...)s in the toolchain.cmake file are also not printed, as if the toolchain.cmake file is completely ignored by CMake.

When I remove the FetchContent, "manually" download the 3rd party library, and set the CMAKE_TOOLCHAIN_FILE to the manually downloaded copy of the 3rd party library with set(CMAKE_TOOLCHAIN_FILE "/path/to/toolchain.cmake") everything works as expected.

The interesting part is, that I can actually keep the FetchContent as long as I set the CMAKE_TOOLCHAIN_FILE before the FetchContent_MakeAvailable(some_software) with set(CMAKE_TOOLCHAIN_FILE "/path/to/toolchain.cmake"). Everything works just fine then. But obviously, this is not practical, as the set(CMAKE_TOOLCHAIN_FILE "${some_software_SOURCE_DIR}/toolchain.cmake") relies on the some_software_SOURCE_DIR variable which is only available after FetchContent_MakeAvailable(some_software).

It seems as if CMake is ignoring the set(CMAKE_TOOLCHAIN_FILE ...) or more specifically is not updating its internal tool variables once FetchContent_MakeAvailable(some_software) has been executed. How can I "force" CMake to update its tool variables?

Thanks in advance!

Ubuntu 18.04 cmake version 3.21.1

EDIT: I basically just want to download some 3rd party library at configure time so that the content is available immediately, e.g. the toolchain.cmake file. This appears to only be possible with FetchContent. However, as pointed out by Tsyvarev, with FetchContent, the 3rd party library becomes part of my project, and I am forced to use the same tools for both, as a single CMake project may use only a single compiler. ExternalProject could help here, but the problem is that it does not provide its contents at configure time, making it impractical for my purpose.

Fabian
  • 312
  • 3
  • 13
  • "I first want to download and install some 3rd party library and then set the toolchain file ..." - This is impossible to achieve by using `FetchContent`. All projects, included via `FetchContent`, become **part of your project**. During configuration and building, a single CMake project may use only the single compiler. See e.g. [that question](https://stackoverflow.com/questions/27168094/cmake-how-to-change-compiler-for-individual-target). For build some project with distinct complier, you could use `ExternalProject`, which configures and builds **separate** CMake project. – Tsyvarev Sep 16 '21 at 20:00
  • Ahh, I see. I will give `ExternalProject` a try and report back. Thank you! As far as I can see `ExternalProject` only gets "evaluated" at build time. But I already need the `toolchain.cmake` when running CMake? This is why chose `FetchContent`. – Fabian Sep 16 '21 at 20:08
  • The only other [solution](https://stackoverflow.com/questions/37845413/how-to-configure-externalproject-during-main-project-configuration) I found seems cumbersome as well. – Fabian Sep 16 '21 at 20:17
  • For building other project you could use `execute_process`. Like with `FetchContent` approach, such project will be immediately available, but you are not restricted in toolchain when building it. (But like with `ExternalProject` approach, CMake variables and targets provided by such project are not available for the main project.) – Tsyvarev Sep 16 '21 at 21:43

0 Answers0