CMake - get cmake variable value from the subdirectory [duplicate] - cmake

This question already has an answer here:
cmake variable scope, add_subdirectory
(1 answer)
Closed 7 months ago.
I have two projects - the first one contains the second one as a subdirectory. in the second project I add the path to the my cmake modules in CMAKE_MODULE_PATH, and in the first project I add the second one using the add_subdirectory command. Then I try to include the module in the first project, but cmake saying me:
CMake Error at tests/CMakeLists.txt:7 (include):
include could not find requested file
and the CMAKE_MODULE_PATH is empty.
How I can save value of CMAKE_MODULE_PATH to then use in the first project?
that's my CMakeLists:
2nd project:
cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
set(UTILS_PROJECT_NAME "utils")
set(UTILS_LIB_NAME "utils")
set(UTILS_VERSION_MAJOR 0)
set(UTILS_VERSION_MINOR 0)
set(UTILS_VERSION_PATCH 1)
set(UTILS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
if(${CMAKE_SOURCE_DIR} STREQUAL ${UTILS_SOURCE_DIR})
set(UTILS_STANDALONE ON)
message(STATUS "utils standalone")
endif()
option(UTILS_BUILD_DOCS "Build the utils documentation" OFF)
option(UTILS_BUILD_TESTS "Guild the utils tests and examples" ${UTILS_STANDALONE})
project(${UTILS_PROJECT_NAME}
VERSION ${UTILS_VERSION_MAJOR}.${UTILS_VERSION_MINOR}.${UTILS_VERSION_PATCH}
LANGUAGES CXX
)
...
setup library target
...
if(NOT "${UTILS_SOURCE_DIR}/cmake" IN_LIST CMAKE_MODULE_PATH)
list(APPEND CMAKE_MODULE_PATH "${UTILS_SOURCE_DIR}/cmake")
endif()
if (${UTILS_BUILD_DOCS})
add_subdirectory(docs)
endif()
if(${UTILS_BUILD_TESTS})
add_subdirectory(tests)
endif()
1st project:
cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
set(ENGINE_PROJECT_NAME "engine")
set(ENGINE_LIB_NAME "engine")
set(ENGINE_VERSION_MAJOR 0)
set(ENGINE_VERSION_MINOR 0)
set(ENGINE_VERSION_PATCH 1)
set(ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
if(${CMAKE_SOURCE_DIR} STREQUAL ${ENGINE_SOURCE_DIR})
set(ENGINE_STANDALONE ON)
message(STATUS "engine standalone")
endif()
option(ENGINE_BUILD_TESTS "Build the tests and examples" ${ENGINE_STANDALONE})
project(${ENGINE_PROJECT_NAME}
VERSION ${ENGINE_VERSION_MAJOR}.${ENGINE_VERSION_MINOR}.${ENGINE_VERSION_PATCH}
LANGUAGES CXX
)
# bad way
list(APPEND CMAKE_MODULE_PATH "${ENGINE_SOURCE_DIR}/src/ext/utils/cmake")
add_subdirectory(src) # add_subdirectory(path/to/utils)
if(${ENGINE_BUILD_TESTS})
add_subdirectory(tests) # use utils cmake modules (utils_add_tests)
endif()

In first project, you can use set(CMAKE_MODULE_PATH "/path/to/the/second/project") to set CMAKE_MODULE_PATH, or else CMAKE_MODULE_PATH is empty by default.
Could you show more cmakefile's details for positioning problem?

Related

how to split 'header', 'src', 'test' dir in cmake?(and donot add cmakelist.txt in each dir)

when building a project stucture like following:
LinearAlgebra
|---HEADER
|-----|---Linear.h
|---SRC
|-----|---Linear.cpp
|---TEST
|-----|---hello_test.cc
here is my CMakeList.txt:
cmake_minimum_required(VERSION 3.10)
project(LinearAlgebra )
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_library(LA_HEADER INTERFACE header/Linear.h)
add_library(LA_SRC INTERFACE src/Linear.cpp)
target_include_directories(LA_HEADER INTERFACE "${PROJECT_SOURCE_DIR}/header" "${PROJECT_SOURCE_DIR}/src")
enable_testing()
add_executable(
hello_test
test/hello_test.cc
)
target_link_libraries(
hello_test
gtest_main
LA_HEADER
LA_SRC
)
include(GoogleTest)
gtest_discover_tests(hello_test)
it works fine with cmake -S . -B build, but when it comes to cmake --build build following error occured:
Undefined symbols for architecture x86_64:
"Linear::Linear()", referenced from:
HelloTest_BasicAssertions_Test::TestBody() in hello_test.cc.o
it seems something wrong with my cmake file that didn't tell Linear.h where Linear.cpp located. So how to fix it ?? thanks for your help...
seems i misunderstand add_library, change three lines and it works out:
cmake_minimum_required(VERSION 3.10)
project(LinearAlgebra )
include_directories(header) # include_directories instead of add_library for .h files
add_library(LA_LIB src/Linear.cpp) # use add_library for .cpp files only!!!
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(
hello_test
test/hello_test.cc
)
target_link_libraries(
hello_test
gtest_main
LA_LIB # link LA_LIB only..
)
include(GoogleTest)
gtest_discover_tests(hello_test)
leave it here for anyone have the same requirements.

Hot do I link MPFR in CMake?

I'm totally new to cmake, I'm on MacOs and I'm trying to build a c++ library and I need to link my executables to mpfr in order to make it work
This is my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.19)
project(my_project)
set(CMAKE_CXX_STANDARD 14)
add_executable(my_project main.cpp)
find_package(GSL REQUIRED)
target_link_libraries(my_project GSL::gsl GSL::gslcblas)
find_package(Boost REQUIRED)
target_link_libraries(my_project Boost::boost)
find_package(MPFR REQUIRED) # <- It fails here!
target_link_libraries(my_project MPFR::mpfr)
When I try to build my project with CLion I get the following error:
CMake Error at CMakeLists.txt:13 (find_package):
By not providing "FindMPFR.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "MPFR", but
CMake did not find one.
Could not find a package configuration file provided by "MPFR" with any of
the following names:
MPFRConfig.cmake
mpfr-config.cmake
Add the installation prefix of "MPFR" to CMAKE_PREFIX_PATH or set
"MPFR_DIR" to a directory containing one of the above files. If "MPFR"
provides a separate development package or SDK, be sure it has been
installed.
After some research I found out that Cmake was linking correctly both GSL and Boost because there are both a /usr/local/share/cmake/Modules/FindGSL.cmake and a /usr/local/share/cmake/Modules/FindBoost.cmake file, So I looked online for a FindMPFR.cmake file to insert into the /usr/local/share/cmake/Modules/ directory, I tried with this one but the error remains the same. What am I doing wrong?
Edit:
Ok now my CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 3.19)
project(my_project)
set(CMAKE_CXX_STANDARD 14)
add_executable(my_project main.cpp )
# Append the cmake/ directory to the CMAKE_MODULE_PATH
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(GSL REQUIRED)
message(STATUS "GSL Found: ${GSL_FOUND}")
target_link_libraries(my_project GSL::gsl GSL::gslcblas)
find_package(Boost REQUIRED)
message(STATUS "Boost Found: ${Boost_FOUND}")
target_link_libraries(my_project Boost::boost)
find_package(MPFR REQUIRED)
message(STATUS "MPFR Found: ${MPFR_FOUND}")
target_link_libraries(my_project ${MPFR_LIBRARIES})
And it works fine :)

cmake cannot include custom module

I'm trying to include my custom cmake module.
My folder hierarchy is like so:
- project
- cmake
- add_FetchContent_MakeAvailable.cmake
- CMakeLists.txt
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12.0)
project(proj
VERSION 1.0.0
LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(FetchContent)
if(${CMAKE_VERSION} VERSION_LESS 3.14)
include(add_FetchContent_MakeAvailable)
endif()
But I get the following error:
include could not find load file:
add_FetchContent_MakeAvailable
Any ideas?

CLion parses GCC errors?

I have a few CMake targets in my project that calls makefiles, which will call gcc.
When there is a build error it shows up on Messages>Build:
my_dir/my_file.c: In function 'my_func':
my_dir/my_file.c.c:52:5: error: expected ';' before '}' token
I wanted to click on it and go straight to my_dir/my_file.c.c:52:5, is that possible?
My Cmakelists.txt only has symbols and include folders for indexing purposes, no C build configuration since all of that is made in the makefiles.
EDIT
This is my CMakeLists.txt structure:
cmake_minimum_required(VERSION 3.7)
project(myexec)
set(CMAKE_CXX_STANDARD 99)
set(MakefileDir ${CMAKE_CURRENT_SOURCE_DIR}/make)
add_custom_target(
mytarget
ALL
WORKING_DIRECTORY ${MakefileDir}
COMMAND make all)
file(GLOB_RECURSE SRCS *.c)
file(GLOB_RECURSE HDRS *.h)
include_directories(
sometthing/inc
(...)
)
add_definitions(
-DMY_SYM=1
(...)
)
add_executable(myexec EXCLUDE_FROM_ALL ${SRCS} ${HDRS})

Building GLFW3 Application with CMAKE - GLFW_LIBRARIES doesnt set

I'm attempting to build a small project using glfw3 but no matter what I do I can't get pkgconfig to set GLFW_LIBRARIES.
Here is my CMakeList.txt
cmake_minimum_required(VERSION 3.3)
project(LearnGLSL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if (CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE Debug)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/debug")
set(PROJECT_BINARY_DIR "${CMAKE_SOURCE_DIR}/build/debug")
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
find_package(OpenGL REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLFW REQUIRED glfw3)
include_directories(
${OPENGL_INCLUDE_DIR}
${GLFW_INCLUDE_DIRS}
)
set(SOURCE_FILES main.cpp gl_core_4_3.cpp)
message(WARNING "${GLFW_LIBRARIES}")
add_executable(LearnGLSL ${SOURCE_FILES})
target_link_libraries(LearnGLSL ${OPENGL_gl_LIBRARY} ${GLFW_LIBRARIES})
add_custom_command(TARGET LearnGLSL POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets
${PROJECT_BINARY_DIR}
COMMENT "Copy resources to build tree")
Here is where glfw3 is installed
-- Installing: /usr/local/include/GLFW
-- Installing: /usr/local/include/GLFW/glfw3native.h
-- Installing: /usr/local/include/GLFW/glfw3.h
-- Installing: /usr/local/lib/cmake/glfw/glfw3Config.cmake
-- Installing: /usr/local/lib/cmake/glfw/glfw3ConfigVersion.cmake
-- Installing: /usr/local/lib/cmake/glfw/glfwTargets.cmake
-- Installing: /usr/local/lib/cmake/glfw/glfwTargets-noconfig.cmake
-- Installing: /usr/local/lib/pkgconfig/glfw3.pc
-- Installing: /usr/local/lib/libglfw3.a
I'll be the first to admit I'm not super comfortable with CMAKE but this seems simple enough and I've done everything I can google to find. maybe its a typo i'm not noticing. Any help is appreciated thanks
Oh i forgot to mention I get undefined references to the glfw functions when building this project. I assumed this is a result of GLFW_LIBRARIES not properly getting set tho.
I don't know about finding GLFW with pkgconfig but I don't think you need pkgconfig in this case. Since GLFW itself builds with CMake it should install a native CMake config module, which it does.
Well, almost. The official GLFW CMake config-module support is a bit buggy as of v3.1.2. Instead, use shaxbee's fork or the adasworks fork (based on shaxbee's but newer)
With that GLFW all you need to find it is just 2 lines:
find_package(glfw3 REQUIRED)
...
target_link_libraries(LearnGLSL ... glfw)
I also found a few other problems in your CMakeLists.txt so I repeat the whole script, revised:
cmake_minimum_required(VERSION 3.3)
project(LearnGLSL)
set(CMAKE_CXX_STANDARD 11) # no explicit compiler flags if possible
# don't read CMAKE_BUILD_TYPE, it has no meaning with multiconfig
# generators
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_SOURCE_DIR}/build/debug")
# PROJECT_BINARY_DIR should not be set at all
# You establish the BINARY_DIR with the initial cmake command
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
add_executable(LearnGLSL main.cpp gl_core_4_3.cpp)
target_link_libraries(LearnGLSL ${OPENGL_gl_LIBRARY} glfw)
add_custom_command(TARGET LearnGLSL POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets
${PROJECT_BINARY_DIR}
COMMENT "Copy resources to build tree")
Since CMake 3.1 pkg_check_modules uses additional paths from CMAKE_PREFIX_PATH variable for search .pc files. Searching is performed in similar manner as in command find_library, but additional subdirectory pkgconfig/ is added to the resulted path. Specifically, for each <prefix> in CMAKE_PREFIX_PATH, .pc file is searched in next directory:
<prefix>/lib[64]/[<arch>/]pkgconfig
(suffix 64 and arhitecture-specific subdirectory is added when appropriate).
So having file /usr/local/lib/pkgconfig/glfw3.pc, you need to set CMAKE_PREFIX_PATH to /usr/local for pkg_check_modules is able to find it. Variable can be set either:
1) In the CMakeLists.txt script itself, or
2) In the command line
cmake -DCMAKE_PREFIX_PATH=<...> <source-dir>
3) As environment one (OS-dependent).
Before CMake 3.1 (and after it) additional search directory can be specified via PKG_CONFIG_PATH environment variable.
E.g. with file /usr/local/lib/pkgconfig/glfw3.pc variable PKG_CONFIG_PATH should contain /usr/local/lib/pkgconfig.