How do you add external libraries to 'self-made' libraries using CMake? - c++

I'm not able to link external libraries with the libraries I wrote using CMake. I'm wondering if there's something that is needed to be added to my CMakeLists.txt? Or if I need to add another CMakeLists.txt in a lower level (inside src) and what would that need to contain?
I have the following project structure:
ProjectFolder
│   ├── CMakeLists.txt
│   ├── build
│   │   └──
│   ├── include
│   │   └── helper.h
│   └── src
│   ├── helper.cpp
   └── main.cpp
My CMakeList.txt is:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(object_detection)
find_package(PCL 1.5 REQUIRED)
find_package(OpenCV REQUIRED)
file(GLOB SOURCES src/*.cpp)
file(GLOB INCLUDE include/*.h)
include_directories(${PCL_INCLUDE_DIRS} ${INCLUDE})
link_directories(${PROJECT_NAME} ${PCL_LIBRARY_DIRS} ${SOURCES} )
add_definitions(${PCL_DEFINITIONS})
add_executable (${PROJECT_NAME} src/main.cpp)
target_link_libraries (${PROJECT_NAME} ${OpenCV_LIBS} ${PCL_LIBRARIES} ${SOURCES})
In my file helper.cpp I have:
#include <pcl/io/pcd_io.h>
Which gives the error:
fatal error: 'pcl/io/pcd_io.h' file not found
#include <pcl/io/pcd_io.h>
^~~~~~~~~~~~~~~~~
However I have the same include in main.cpp with no errors.
I would be very grateful for any help, please let me know if I need to clarify my question or error.
Thank you.

There are several errors in the CMakeLists.txt with the following changes the project loads appropriate libraries and builds properly. Another note is that before, to include helper.h I needed to write:
#include "../include/helper.h".
Now it works as expected with #include "helper.h".
Here is the modified CMakeLists.txt:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(object_detection)
find_package(PCL 1.5 REQUIRED)
find_package(OpenCV REQUIRED)
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)
include_directories(${PCL_INCLUDE_DIRS} include)
link_directories(${PROJECT_NAME} ${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
#add_executable (${PROJECT_NAME} src/helper.cpp src/main.cpp )
add_executable (${PROJECT_NAME} ${SRC_FILES} )
target_link_libraries (object_detection ${PCL_LIBRARIES} ${OpenCV_LIBS})

Related

CMake header files can't be found (fatal error: file not found)

I'm working on a CMake project but Im getting this error and I don't understand why. Im using VS Code on MacOS and I'm using Clang as the compiler.
Here is the structure of my folder project:
tree
.
├─ app
│ ├── CMakeLists.txt
│ └── src
│ └── main.cpp
├─ CMakeLists.txt
├─ build
└─ engine
├── CMakeLists.txt
├── external
├── include
│ └── project_engine
│ └── engine.h
└── src
└── engine.cpp
The root CMakeLists.txt is
cmake_minimum_required(VERSION 3.5)
project(vulkanEngine_developement_env VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
add_subdirectory(app)
add_subdirectory(engine)
The CMakeLists.txt in the app folder:
cmake_minimum_required(VERSION 3.5)
project(vulkanEngine VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} vulkanEngine_engine)
target_include_directories(${PROJECT_NAME} PRIVATE vulkanEngine_engine)
and the one in engine is:
cmake_minimum_required(VERSION 3.5)
project(vulkanEngine_engine VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
add_library(${PROJECT_NAME} src/engine.cpp)
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
)
target_link_libraries(${PROJECT_NAME}
PUBLIC
PRIVATE
)
Whenever I try to include the header file in both cpp files I get the error "file not found", I tried using both
#include <project_engine/engine.h>
and
#include "project_engine/engine.h"
I also tried linking the path to the header in the vs code include path setting but it didn't work, I added include_directories to the engine CMake file but that didn't work either.

Importing header files and linking .a file in CMake

Trying to put Skia in my CMake project. How do I tell CMake to link my executable against libskia.a and use the header files inside ext/skia so that I can include them like so?
#include <skia/subdirectory/headerfile.h>
My project structure is currently the following:
.
├── CMakeLists.txt
├── CMakeLists.txt.user
├── ext
│   ├── libskia.a
│   └── skia
│   └── <subdirectories>
│      └── <header files>.h
└── src
└── main.cpp
and my CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(project LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
add_executable(project src/main.cpp)
In your primary CMakeLists.txt file you would simply add the following:
target_link_libraries(project skia)
If CMake cannot find the library, you can either do:
target_link_libraries(project /full/path/to/libskia.a)
or:
link_directories(/path/to/libraries)
target_link_libraries(project skia)

'torch/torch.h' file not found in header file

I'm new in Linux C++ programming. I have to use libtorch (pytorch C++ version), but I kept struggling with C++ and cmake problems. These problems really make me mad, and I need some help.
Here is a simple C++ project:
.
├── build.sh
├── CMakeLists.txt
├── load_data
│   ├── CMakeLists.txt
│   ├── include
│   │   └── load_data
│   │   └── load_data.hpp
│   └── src
│   └── load_data.cpp
└── src
└── main.cpp
But I can't build it because load_data/include/load_data/load_data.hpp cannot #include <torch/torch.h>.
The build error message:
[build] /my/path/load_data/include/load_data/load_data.hpp:4:10: fatal error: 'torch/torch.h' file not found
[build] #include <torch/torch.h>
[build] ^~~~~~~~~~~~~~~
However, if I move the #include <torch/torch.h> from the header file to the corresponding source file, the error message goes away. It makes me confused.
Files' contents:
load_data/include/load_data/load_data.hpp
#pragma once
#include <torch/torch.h>
namespace load_data
{
void try_torch();
// torch::Tensor rand_tensor();
}
load_data/src/load_data.cpp
# include "load_data/load_data.hpp"
// If I remove it from load_data.hpp and use it here, the error goes away.
// #include <torch/torch.h>
namespace load_data {
void try_torch(){
torch::Tensor tensor = torch::rand({2, 3});
std::cout << tensor << std::endl;
}
}
src/main.cpp
#include <string>
#include "load_data/load_data.hpp"
int main(int argc, char **argv)
{
load_data::try_torch();
return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.21)
set(CMAKE_CXX_COMPILER clang++-13)
project(ldt-cpp-experiments VERSION 1.0.0 LANGUAGES CXX)
find_package(Torch REQUIRED)
message(STATUS "Torch_FOUND: ${Torch_FOUND}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_subdirectory("load_data")
set(EXECUTABLE_NAME main)
add_executable(${EXECUTABLE_NAME} src/main.cpp)
target_link_libraries(${EXECUTABLE_NAME}
PRIVATE load_data
)
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
)
load_data/CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project (load_data VERSION 1.0.0 LANGUAGES CXX)
find_package(Torch REQUIRED)
message(STATUS "Torch_FOUND: ${Torch_FOUND}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
set(LIB_NAME "load_data")
add_library(${LIB_NAME}
SHARED
)
target_sources(${LIB_NAME}
PRIVATE
${PROJECT_SOURCE_DIR}/src/load_data.cpp
)
target_sources(${LIB_NAME}
PRIVATE
${PROJECT_SOURCE_DIR}/src/load_data.cpp
${PROJECT_SOURCE_DIR}/include/load_data/load_data.hpp
)
target_include_directories(${LIB_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(${LIB_NAME}
PRIVATE
${TORCH_LIBRARIES}
)
set_target_properties(${LIB_NAME} PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
)
build.sh
cmake -S . -B build

Creating and using a static library with CMake

I am trying to first create a static library and then link it to an executable using CMake. My project file structure looks like this:
├── CMakeLists.txt
├── build
├── lib
│   ├── CMakeLists.txt
│   ├── build
│   ├── include
│   │   └── Point.hpp
│   └── src
│   └── Point.cpp
└── mainApp.cpp
I first build the library like so.
cmake_minimum_required(VERSION 2.8.9)
project(CAST3)
set(CMAKE_BUILD_TYPE Release)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_library(CAST3 STATIC ${SOURCES})
However, when i try to link the library to my executable I get an error.
This is my executable
#include"Point.hpp"
int main(int argc, char *argv[]){
Point p = Point(1,2,3);
return 0;
}
This is my CMake file to link the library to the executable.
cmake_minimum_required(VERSION 2.8.9)
project (CAST3)
set ( PROJECT_LINK_LIBS libCAST3.a )
link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/lib/build)
add_executable(libtest mainApp.cpp)
target_link_libraries(libtest ${PROJECT_LINK_LIBS} )
When I run that I get the this error
/mainApp.cpp:1:9: fatal error: 'Point.hpp' file not found
#include"Point.hpp"
^~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/libtest.dir/mainApp.cpp.o] Error 1
make[1]: *** [CMakeFiles/libtest.dir/all] Error 2
make: *** [all] Error 2
What am I missing?
What am I missing?
You are missing target_include_directories(CAST3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) inside lib/CMakeLists.txt.
You are missing add_subdirectory(lib) from root CMakeLists.txt.
The set ( PROJECT_LINK_LIBS libCAST3.a ) and target_link_libraries(libtest ${PROJECT_LINK_LIBS} ) and link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/lib/build) could be removed. Then you are missing just target_link_libraries(libtest PUBLIC CAST3). Cmake will automatically find the proper .a file and propagate include paths with target_link_libraries.
So your lib/CMakeLists.txt could look like this:
cmake_minimum_required(VERSION 3.0) # I would advise to update
project(CAST3)
include_directories(include)
file(GLOB sources src/*.cpp) # upper case variable names reserved for exported variables by convention
add_library(CAST3 ${sources}) # STATIC by default
target_include_directories(CAST3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
And root CMakeLists.txt could look like this:
cmake_minimum_required(VERSION 3.0) # I would advise to update
project(CAST3)
add_subdirectory(lib)
add_executable(libtest mainApp.cpp)
target_link_libraries(libtest CAST3)

CMake + Qt + GTest files linking

I have a simple CMake + Qt + GTest project:
.
├── CMakeLists.txt
├── src
│   ├── CMakeLists.txt
│   ├── main.cpp
│   └── utils
│   ├── calculator.cpp
│   └── calculator.h
└── tests
├── calculator_test.cpp
└── CMakeLists.txt
Root CMakeFiles.txt
cmake_minimum_required(VERSION 3.5)
project(random_project)
# Place binaries and libraries according to GNU standards.
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
# Add source folder.
add_subdirectory(src)
# Add GTest.
include(cmake/googletest.cmake)
fetch_googletest(
${PROJECT_SOURCE_DIR}/cmake
${PROJECT_BINARY_DIR}/googletest
)
enable_testing()
# Add tests folder.
add_subdirectory(tests)
And I want to reach calculator.h in calculator_test.cpp which uses GTest:
#include <gtest/gtest.h>
#include "utils/calculator.h" // <- Want to reach this in that path format.
TEST(example, add)
{
EXPECT_EQ(8, Calculator::sum(3, 5));
}
I have tried to link but then test is not found and the path is releative:
tests/CMakeFiles.txt
# Find the Qt libraries.
find_package(Qt5Widgets REQUIRED)
# Qt5 libraries.
set(QT5_LIBRARIES
Qt5::Widgets)
# Source files.
set(SOURCE_FILES
calculator_test.cpp
../src/utils/calculator.cpp
../src/utils/calculator.h
../src/main.cpp) # If I link like this, test is not found.
# Tell CMake to create the executable.
add_executable(unit_tests ${SOURCE_FILES})
# Use the Widgets module from Qt5.
target_link_libraries(unit_tests ${QT5_LIBRARIES} gtest_main)
# Add tests.
add_test(
NAME unit_tests
COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/unit_tests
)
How to link calculator.h in calculator_test.cpp test with CMakeLists.txt?
My Qt project with CMake project file cannot resolve the path to
"someHeader.h". What can I do to fix it?
You can specify the include path:
include_directories("${PROJECT_SOURCE_DIR}/relativePathToHeader")
and likely the path needed:
include_directories("${PROJECT_SOURCE_DIR}/src/utils") or maybe
include_directories("${PROJECT_SOURCE_DIR}/utils") depending on where the source directory actually is.
You need to re-run CMake, of course.