I have the following directory structure for my app. The libraries in the external directory all use fetchcontent command.
myapp
│
│ CMakeLists.txt
│
├───data
│ data.csv
│
├───external
│ ├───csv-parser
│ │ CMakeLists.txt
│ │
│ ├───eigen
│ │ CMakeLists.txt
│ │
│ └───fmt
│ CMakeLists.txt
│
├───include
│ myapp.h
│
├───out
│ └───build
│
├───src
│ main.cpp
│
└───tests
The CMakeLists.txt in the csv-parser folder is as follows.
cmake_minimum_required(VERSION 3.24)
project(libcsvparser VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
include(CMakePrintHelpers)
FetchContent_Declare(csv_parser
GIT_REPOSITORY https://github.com/ben-strasser/fast-cpp-csv-parser.git)
FetchContent_MakeAvailable(csv_parser)
cmake_print_variables(csv_parser_SOURCE_DIR csv_parser_BINARY_DIR)
The CMakeLists.txt in the fmt folder is as follows.
cmake_minimum_required(VERSION 3.24)
project(libfmt VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
include(CMakePrintHelpers)
FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt)
FetchContent_MakeAvailable(fmt)
cmake_print_variables(fmt_SOURCE_DIR fmt_BINARY_DIR)
The CMakeLists.txt in the eigen folder is as follows.
cmake_minimum_required(VERSION 3.24)
project(libeigen VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
include(CMakePrintHelpers)
FetchContent_Declare(eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git)
FetchContent_MakeAvailable(eigen)
cmake_print_variables(eigen_SOURCE_DIR eigen_BINARY_DIR)
For all the external libraries, I get the correct ???_SOURCE_DIR and ???_BINARY_DIR printed during the build.
The main CMakeLists.txt is as follows.
cmake_minimum_required(VERSION 3.24)
project(myapp VERSION 1.0.0)
include(FetchContent)
include(CMakePrintHelpers)
cmake_print_variables(CMAKE_CXX_FLAGS)
set(CMAKE_CXX_STANDARD 20)
add_subdirectory(external/csv-parser)
add_subdirectory(external/eigen)
add_subdirectory(external/fmt)
cmake_print_variables(csv_parser_SOURCE_DIR)
cmake_print_variables(eigen_SOURCE_DIR)
cmake_print_variables(fmt_SOURCE_DIR)
add_executable(myapp)
target_sources(myapp PRIVATE src/main.cpp)
target_include_directories(myapp PUBLIC include)
target_include_directories(myapp PUBLIC csv_parser_SOURCE_DIR)
target_include_directories(myapp PUBLIC eigen_SOURCE_DIR)
target_include_directories(myapp PUBLIC fmt_SOURCE_DIR)
I am having trouble accessing the external libraries in the main CMakeLists.txt and during its build the following commands will print empty as if the add_subdirectory did not work correctly.:
csv_parser_SOURCE_DIR=""
eigen_SOURCE_DIR=""
fmt_SOURCE_DIR=""
Because of this my Visual Studio does not recognize where the following include files are and I can't build the myapp target.
#include "Eigen/Dense"
#include "fmt/core.h"
#include <csv.h>
The most simplest way is to set the variable, {project}_SROUCE_DIR, to PARENT_SCOPE.
For example, you can add below code in your CMakeLists.txt of the fmt directory.
The reason why main CMakeLists could not access that variable is the variable scope related problem.
{project}_SOURCE_DIR variable is valid while configuring {project} subdirectory.