CLion configurate and test library project - c++

Let's say I wanted to develop a simple library with the following structure:
My CMakeLists.txt then looks like this:
cmake_minimum_required(VERSION 3.17)
set(CMAKE_CXX_STANDARD 14)
set(INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
file(GLOB INCLUDES "${INC_DIR}/httplib/*.hpp")
file(GLOB SOURCES "${SRC_DIR}/*.cpp")
project(httplib)
add_library(httplib STATIC ${INCLUDES} ${SOURCES})
include_directories(${INC_DIR})
This works fine but what is the usual way to configure CLion projects and CMake in order to test a library effectively ?

Related

How to include properly all files with CMake

I want to build my C++ project with CMake and I want to include automatically every new file on "cmake ." my project structure is:
Application/ Graphics/ CMakeLists.txt CMakeLists.txt.user main.cpp
./Application:
CMakeLists.txt Logger/ Recovery/ application.cpp application.hpp firstclass.cpp firstclass.hpp singleton.hpp
./Application/Logger:
CMakeLists.txt logger.cpp logger.hpp
./Application/Recovery:
CMakeLists.txt recovery.cpp recovery.hpp
./Graphics:
CMakeLists.txt drawableobject.cpp drawableobject.hpp graphics.cpp graphics.hpp
Each folder has own CMakeLists.txt
I did so far this in master CMake:
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Asteri VERSION 1.0)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
message("Source dir: ${SOURCE_DIR}")
#file(GLOB_RECURSE SRC_FILES ${SOURCE_DIR}/*.cpp)
#file(GLOB_RECURSE HEADER_FILES ${HEADER_DIR}/*.hpp)
set(PROJECT_NAME "Asteri")
macro(SUBDIRLIST result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
foreach(child ${children})
if(IS_DIRECTORY ${curdir}/${child})
list(APPEND dirlist ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR})
foreach(subdir ${SUBDIRS})
message("Subdirectory: ${subdir}")
add_subdirectory(${subdir})
endforeach()
add_executable(${Asteri} main.cpp)
The question is how to connect all pieces together?
What I need in other CMakeLists.txt?
How to communicate children -> parent or I misunderstood the concept of CMake?
No need for other CMakeLists.
I guess you want something like this in top CMakeLists:
cmake_minimum_required(VERSION 3.12)
project(Asteri VERSION 1.0)
file(GLOB_RECURSE ASTERI_SRC_FILES CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/Application/*.cpp"
"${PROJECT_SOURCE_DIR}/Graphics/*.cpp"
)
add_executable(Asteri main.cpp ${ASTERI_SRC_FILES})
It's worth noting that GLOB/GLOB_RECURSE -even with CONFIGURE_DEPENDS- is bad practice: it's slow, specially on Windows from my experience, and may not work as expected depending on generator used.
I found out the answer to my problems.
set(SOURCES "${PROJECT_DIR}/main.cpp" CACHE INTERNAL STRINGS)
add_subdirectory(application)
FOREACH(it ${SOURCES})
message("source file: ${it}")
ENDFOREACH()
add_executable(Asteri ${SOURCES})
In this way I store main.cpp path into variable SOURCES
You can see your variables after 'make' in CMakeCache.txt.
After this is done, my variable SOURCES looks like:
/STRINGS
SOURCES:INTERNAL=/home/default/cpp_testing_project/cmake_project/source/main.cpp;
After that in application subdirectory I have CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
# Get source files
file(GLOB CPP_LIST "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
set(SOURCES ${SOURCES} ${CPP_LIST} CACHE INTERNAL STRINGS)
And now SOURCES looks like:
SOURCES:INTERNAL=/home/default/cpp_testing_project/cmake_project/source/main.cpp;/home/default/cpp_testing_project/cmake_project/source/application/application.cpp;/home/default/cpp_testing_project/cmake_project/source/application/drawableobject.cpp;/home/default/cpp_testing_project/cmake_project/source/application/firstclass.cpp;/home/default/cpp_testing_project/cmake_project/source/application/graphics.cpp;/home/default/cpp_testing_project/cmake_project/source/application/application.hpp;/home/default/cpp_testing_project/cmake_project/source/application/drawableobject.hpp;/home/default/cpp_testing_project/cmake_project/source/application/firstclass.hpp;/home/default/cpp_testing_project/cmake_project/source/application/graphics.hpp;

CMake Library issue for header-only library [duplicate]

How to make a project in cmake that collects all c++ files into one header?
I have this project structure.
/
project/
folder1/
file.cpp
file.hpp
folder2/
...etc
CMakeLists.txt
tests/
test.cpp
CMakeLists.txt
CMakeList.txt
root cmakelists.txt
cmake_minimum_required (VERSION 3.8)
project ("CMakeProject"
LANGUAGES C CXX)
set(CMAKE_EXECUTABLE_SUFFIX ".exe")
include(GNUInstallDirs)
add_subdirectory ("project")
option(ENABLE_TESTING OFF)
if (ENABLE_TESTING)
enable_testing()
add_subdirectory("tests")
endif()
CMakeLists.txt in project
cmake_minimum_required (VERSION 3.8)
file(GLOB projectSRC
"*/*.cpp"
"*/*.hpp"
"*.cpp"
"*.hpp"
)
add_library(project INTERFACE)
message(STATUS "CMake inatall directory: " ${CMAKE_INSTALL_INCLUDEDIR})
target_include_directories(project
INTERFACE
$<BUILD_INTERFACE:${PROJECT_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
and test cmakelist.txt
cmake_minimum_required (VERSION 3.8)
# install Catch2 testing library
# (https://github.com/catchorg/Catch2/blob/master/docs/cmake-integration.md#installing-catch2-from-git-repository or use packet manager)
find_package(Catch2 REQUIRED)
file(GLOB testSRC
"*.cpp"
)
add_executable(tests ${testSRC})
target_link_libraries(tests
Catch2::Catch2
project)
include(CTest)
include(Catch)
catch_discover_tests(tests)
How to generate one header and use it (in tests or other projects) or make this library able to have templates? The first is better.
How to make a header-only library with cmake?
Like this:
add_library(project INTERFACE)
target_include_directories(project INTERFACE .)
Then in the target that uses the library:
target_link_libraries(dependee
PUBLIC/INTERFACE/PRIVATE # pick one
project)
and include the header like this:
#include <project/folder1/file.hpp>

How to make a header-only library with cmake?

How to make a project in cmake that collects all c++ files into one header?
I have this project structure.
/
project/
folder1/
file.cpp
file.hpp
folder2/
...etc
CMakeLists.txt
tests/
test.cpp
CMakeLists.txt
CMakeList.txt
root cmakelists.txt
cmake_minimum_required (VERSION 3.8)
project ("CMakeProject"
LANGUAGES C CXX)
set(CMAKE_EXECUTABLE_SUFFIX ".exe")
include(GNUInstallDirs)
add_subdirectory ("project")
option(ENABLE_TESTING OFF)
if (ENABLE_TESTING)
enable_testing()
add_subdirectory("tests")
endif()
CMakeLists.txt in project
cmake_minimum_required (VERSION 3.8)
file(GLOB projectSRC
"*/*.cpp"
"*/*.hpp"
"*.cpp"
"*.hpp"
)
add_library(project INTERFACE)
message(STATUS "CMake inatall directory: " ${CMAKE_INSTALL_INCLUDEDIR})
target_include_directories(project
INTERFACE
$<BUILD_INTERFACE:${PROJECT_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
and test cmakelist.txt
cmake_minimum_required (VERSION 3.8)
# install Catch2 testing library
# (https://github.com/catchorg/Catch2/blob/master/docs/cmake-integration.md#installing-catch2-from-git-repository or use packet manager)
find_package(Catch2 REQUIRED)
file(GLOB testSRC
"*.cpp"
)
add_executable(tests ${testSRC})
target_link_libraries(tests
Catch2::Catch2
project)
include(CTest)
include(Catch)
catch_discover_tests(tests)
How to generate one header and use it (in tests or other projects) or make this library able to have templates? The first is better.
How to make a header-only library with cmake?
Like this:
add_library(project INTERFACE)
target_include_directories(project INTERFACE .)
Then in the target that uses the library:
target_link_libraries(dependee
PUBLIC/INTERFACE/PRIVATE # pick one
project)
and include the header like this:
#include <project/folder1/file.hpp>

How do I link a library using CMake?

I'm trying to add a new library to a project built using CMake and am having trouble. I'm trying to follow this. I've made a test project that looks like this:
cmake_test/
test.cpp
CMakeLists.txt
liblsl/
include/
lsl_cpp.h
CMakeLists.txt
liblsl64.dll
liblsl64.so
build/
the CMakeLists.txt in cmake_test looks like this:
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(Tutorial test.cpp)
add_subdirectory(liblsl)
target_link_libraries(Tutorial PUBLIC ${LSL_LIBRARY})
and the CMakeLists.txt in liblsl looks like this:
find_path(LSL_INCLUDE_DIR lsl_cpp.h)
find_library(LSL_LIBRARY liblsl64)
include_directories(${LSL_INCLUDE_DIR})
But I keep getting the error No rule to make target '.../liblsl64.lib', needed by 'Tutorial.exe'. Stop.
Any idea what I'm doing wrong?
I'm on Windows 10 using mingw-w64 v5.4.0 if that makes any difference.
CMakeLists.txt in cmake_test:
cmake_minimum_required(VERSION 3.10)
project(Tutorial VERSION 1.0)
add_subdirectory(liblsl)
add_executable(Tutorial test.cpp)
target_compile_features(Tutorial PUBLIC cxx_std_11)
target_link_libraries(Tutorial PUBLIC liblsl)
CMakeLists.txt in liblsl:
add_library(liblsl SHARED IMPORTED GLOBAL)
set_target_properties(liblsl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/include")
set_target_properties(liblsl PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/liblsl64.so")
For Windows use:
set_target_properties(liblsl PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/liblsl64.dll")
set_target_properties(liblsl PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/liblsl64.lib")
In add_library, you say SHARED because your library is a shared one (so/dll), you say IMPORTED because you don't want to build the library, and you say GLOBAL because you want it to be visible outside liblsl.

How to use PJSIP library with CMake?

I know how the basic Makefile for a simple project using pjsip library looks like. But what does the equivalent CMake file look like?
project(myapp)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
include (FindPkgConfig)
if (PKG_CONFIG_FOUND) # true if pkg-config works on the system
pkg_check_modules(PJSIP REQUIRED libpjproject)
endif()
include_directories(${PJSIP_INCLUDE_DIRS})
link_directories(${PJSIP_LIBRARY_DIRS})
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${PJSIP_LIBRARIES})