Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FetchContent failure when using CPM on multiple projects with cmake < 3.17 #192

Closed
xmuller opened this issue Feb 6, 2021 · 1 comment · Fixed by #193
Closed

FetchContent failure when using CPM on multiple projects with cmake < 3.17 #192

xmuller opened this issue Feb 6, 2021 · 1 comment · Fixed by #193

Comments

@xmuller
Copy link
Contributor

xmuller commented Feb 6, 2021

To reproduce the bug with at least CPM >= 0.27.5:

Minimal structure:

.
├── CMakeLists.txt
├── libA
│   ├── CMakeLists.txt
│   └── CPM.cmake
└── libB
    ├── CMakeLists.txt
    └── CPM.cmake

CMakeLists.txt:

cmake_minimum_required(VERSION 3.16.3)
project(minimal_bug_cpm)

add_subdirectory(libA)
add_subdirectory(libB)

libA/CMakeLists.txt:

cmake_minimum_required(VERSION 3.16.3)
project(libA)

include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake)
CPMFindPackage(
  NAME doctest
  GITHUB_REPOSITORY onqtam/doctest
  GIT_TAG 2.4.4
)

libB/CMakeLists.txt:

cmake_minimum_required(VERSION 3.16.3)
project(libB)

include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake)
CPMFindPackage(
  NAME fmt
  GITHUB_REPOSITORY fmtlib/fmt
  GIT_TAG 6.2.1
)

ERROR:

-- Detecting CXX compile features - done
-- CPM: adding package doctest@2.4.4 (2.4.4)
--  adding package fmt@6.2.1 (6.2.1)
CMake Error: File /CMakeLists.cmake.in does not exist.
CMake Error at /usr/share/cmake-3.16/Modules/FetchContent.cmake:891 (configure_file):
  configure_file Problem configuring file
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/FetchContent.cmake:1006 (__FetchContent_directPopulate)
  /usr/share/cmake-3.16/Modules/FetchContent.cmake:1047 (FetchContent_Populate)
  libA/CPM.cmake:561 (FetchContent_MakeAvailable)
  libA/CPM.cmake:425 (cpm_fetch_package)
  libA/CPM.cmake:196 (CPMAddPackage)
  libB/CMakeLists.txt:6 (CPMFindPackage)


-- Configuring incomplete, errors occurred!

Solution

include(FetchContent) need to be call inside each subdirectory (cmake < 3.17) else it's not working.
So before the return() in CPM.cmake line 44 we can add include(FetchContent) which fix the issue.

Also, CPM_INDENT is locally defined that why there is no CPM: in front of adding package fmt@6.2.1 (6.2.1) in the given example.
An (ugly ?) way to keep the prefix is to also add the following line:

if(NOT CPM_INDENT)
  set(CPM_INDENT "CPM:")
endif()

Unless I missed something or something seems wrong to you, if the fix sound nice to you I can create a pull request.
Best regards,
Xavier

@TheLartians
Copy link
Member

Hey, thanks for the report! Yeah, I've assumed CPM.cmake would be included in the outermost CMakeLists, but in case like this, the outer variables go out of scope before the second subdirectory is included.

  • About the indent, a simpler fix might be to cache the variable at the declaration in line 133: set(CPM_INDENT "CPM:" CACHE INTERNAL ""), that way it would always be set to CPM: in the global scope.
  • About outer includes, how would you feel about lazily including the modules each time a functions using it? That way we couldn't pollute the outer scope and in the cached case we would have a better performance. Otherwise your solution of moving them to the top sounds like a good idea. Also I'm not sure about the performance overhead of the include so it might be negligible anyways.

I'm always be happy to receive a PR, where we could discuss the exact implementation details anyways!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants