I have a small project with cmake. I build a lib and an executable. on the development machine I want also an executable that cannot be build on other machines/environments.
e.g.:
<my-lib>
| -- CMakeLists.txt
|
+ -- src/ -> build the lib/archive
| |-- lib.c
| |-- lib.h
| |-- CMakeLists.txt
|
+ -- tool -> build the tool
| |-- tool.c
| |-- CMakeLists.txt
|
+ -- tests -> build the unit tests
| |-- tests.c
| |-- CMakeLists.txt
I added CMakeLists.txt to all directories. Also an add_executable to the tests. Now the unit-test executable is build by default. But I want to exclude it from default target.
CMakeLists.txt in tests:
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
Has anyone a hint how to handle this? I don't want to build unit-test always!
There is a property EXCLUDE_FROM_ALL for such task.
You can write:
set_target_properties(unit-test PROPERTIES EXCLUDE_FROM_ALL TRUE)
This is very simple: protect creation of executable by introducing an option/variable.
if (DEFINED WITH_UNIT_TEST)
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
endif ()
Now when invoking CMake, one would have to explicitly specify -DWITH_UNIT_TEST, so that unit-test target is built, while by default it will never be build. For alternative approach, see comments.
Related
CMake generates compile_commands.json in cmake build directory which means that my installation of YouCompleteMe or YCM cannot find it. For YCM to use it I need to move it from the build directory to the source or top level of the project.
Project
|- CMakeLists.txt
|- compile_commands.json (there is what i want)
|- build (this iw where i build my project)
|-- compile_commands.json (this is what i have)
|-- OtherCmakeGenerateStuff
|- src
|-- CMakeLists.txt
|-- main.cc (includes library not in project)
|-lib
|-- CMakeLists.txt
|-- math
|--- CMakeLists.txt
|--- math.cc
|--- math.hh
|-include
|-- globals.hh
|-- definitions.hh
There may be mistakes in these files as I just typed it and haven't tested it. however, my focus is on the top level CMakeLists.txt file.
CMakeLists.txt (Top level)
cmake_minimum_require(VERSION 3.8)
project(just_some_project LANGUAGES CXX VERSION 1.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(src)
add_subdirectory(lib)
include_directories(include)
src/CMakeLists.txt
cmake_minimum_require(VERSION 3.8)
project(just_some_project LANGUAGES CXX VERSION 1.0)
find_project(someotherlibrary REQUIRED)
add_executable(main main.cc)
target_include_directories(main PUBLIC math someotherlibraryfound)
lib/CMakeLists.txt (Top level)
cmake_minimum_require(VERSION 3.8)
file(GLOB Headers "*.hh")
file(GLOB Sources "*.cc")
add_library(math STATIC $Sources $Headers)
I have a small project with cmake. I build a lib and an executable. on the development machine I want also an executable that cannot be build on other machines/environments.
e.g.:
<my-lib>
| -- CMakeLists.txt
|
+ -- src/ -> build the lib/archive
| |-- lib.c
| |-- lib.h
| |-- CMakeLists.txt
|
+ -- tool -> build the tool
| |-- tool.c
| |-- CMakeLists.txt
|
+ -- tests -> build the unit tests
| |-- tests.c
| |-- CMakeLists.txt
I added CMakeLists.txt to all directories. Also an add_executable to the tests. Now the unit-test executable is build by default. But I want to exclude it from default target.
CMakeLists.txt in tests:
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
Has anyone a hint how to handle this? I don't want to build unit-test always!
There is a property EXCLUDE_FROM_ALL for such task.
You can write:
set_target_properties(unit-test PROPERTIES EXCLUDE_FROM_ALL TRUE)
This is very simple: protect creation of executable by introducing an option/variable.
if (DEFINED WITH_UNIT_TEST)
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
endif ()
Now when invoking CMake, one would have to explicitly specify -DWITH_UNIT_TEST, so that unit-test target is built, while by default it will never be build. For alternative approach, see comments.
I'm building a test project to learn libraries zeromq with cppmq, and I want to include both libraries as subdirectories. I currently have the following structure:
|-- CMakeLists.txt
|-- deps
| |-- cppzmq-4.3.0
| | |-- CMakeLists.txt
| | `-- rest of files
| |-- zeromq-4.3.1
| | |-- CMakeLists.txt
| | `-- rest of files
`-- main.cpp
I've tried with the following CMakeLists:
cmake_minimum_required(VERSION 3.14)
project(PruebaZeroMQ)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(deps/zeromq-4.3.1)
add_subdirectory(deps/cppzmq-4.3.0)
add_executable(PruebaZeroMQ main.cpp)
target_link_libraries(PruebaZeroMQ
libzmq
cppzmq)
When I run cmake, I get the following error:
-- Detected CPPZMQ Version - 4.3.0
-- CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)
CMake Error at deps/cppzmq-4.3.0/CMakeLists.txt:20 (message):
ZeroMQ was not found, neither as a CMake package nor via pkg-config
cppmq depends on zeromq, and looks like it tries to load it using find_package, so I tried to modify CMAKE_MODULE_PATH so it could find the ZeroMQConfig.cmake file, but it fails too, with the same error:
add_subdirectory(deps/zeromq-4.3.1)
list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps/zeromq-4.3.1 ")
add_subdirectory(deps/cppzmq-4.3.0)
Is there a way of achieving this? I'd rather not install the libraries system-wide.
After trying to manually find_package, CMake showed the following error message:
Add the installation prefix of "ZeroMQ" to CMAKE_PREFIX_PATH or set
"ZeroMQ_DIR" to a directory containing one of the above files.
So I tried that, using:
set(ZeroMQ_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/zeromq-4.3.1)
And it worked.
I have a line like this in my CMakeLists.txt
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "cmake")
This is so that some custom libraries can be found with a directory tree that looks like this:
CMakeLists.txt
cmake/
|-- FindSomeLibrary.cmake
|-- FindAnotherLibrary.cmake
Normally I build simply like this:
cmake .
Which works fine. However, I want to provide a debug and release build using a script like this:
mkdir release
cd release
cmake -DCMAKE_BUILD_TYPE=Release ../
However, now it cannot find the cmake modules.
Is there a way to set CMAKE_MODULE_PATH such that it works for both in-source and out-of-source builds?
As proposed in the comments:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
and always try to set all paths relative to some CMAKE_* directory. That way you will miss many errors. ; )
As CMAKE_MODULE_PATH is a list, so it's better to use:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
I have just added google-test source code to libs/gtest-1.6.4 directory in my project. There is a libs/gtest-1.6.4/CMakeLists.txt file. In the top-most CMakeLists.txt, I have added add_subdirectory('libs/gtest-1.6.4'). The structure of the project is
|- CMakeLists.txt
|- src
|- CMakeLists.txt
|- *.h and *.cc
|- libs
|- gtest-1.6.4
|- CMakeLists.txt
|- gtest source code etc.
|- other subdirectories
Now I add #include "gtest/gtest.h" in one of the header file. Compilation fails with
gtest/gtest.h: No such file or directory
compilation terminated.
Here is the snippet of my src/CMakeLists.txt file.
set( Boost_USE_STATIC_LIBS ON )
find_package( Boost COMPONENTS graph regex system filesystem thread REQUIRED)
.. Normal cmake stuff ...
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} )
# This line is added for google-test
INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS} ${COMMON_INCLUDES})
add_executable(Partitioner
print_function.cc
methods.cc
partitioner.cc
main.cc
)
TARGET_LINK_LIBRARIES(Partitioner ${Boost_LIBRARIES})
TARGET_LINK_LIBRARIES(Partitioner ${GTEST_LIBRARIES})
What am I missing?
Looking at GTest's CMakeLists.txt, it looks like their include path is ${gtest_SOURCE_DIR}/include. They also define the library as a CMake target called gtest (this is wrapped in a macro cxx_library(gtest ...) currently on line 70).
So it looks like you need to do:
...
# This line is added for google-test
INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS} ${COMMON_INCLUDES})
INCLUDE_DIRECTORIES(${gtest_SOURCE_DIR}/include ${COMMON_INCLUDES})
...
TARGET_LINK_LIBRARIES(Partitioner ${Boost_LIBRARIES})
TARGET_LINK_LIBRARIES(Partitioner ${GTEST_LIBRARIES})
TARGET_LINK_LIBRARIES(Partitioner ${Boost_LIBRARIES} gtest)
You'd also have to ensure that in your root CMakeLists.txt, you've called add_subdirectory(libs/gtest-1.6.4) before add_subdirectory(src) so that the GTest variables are correctly set when they're being used in "src/CMakeLists.txt".
As mentioned in accepted answer,
I did put my GoogleTest stuff up before my add_subdirectory() lines and it worked.
# The ROOT CMakeLists.txt
enable_testing()
include(CTest)
# https://google.github.io/googletest/quickstart-cmake.html
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/....zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
add_subdirectory(some)
add_subdirectory(other)
add_subdirectory(another)
And in one of those sub directory, I see tests work.
# A CMakeLists.txt in a sub directory
#enable_testing() # NOT REQUIRED, hence, commented out
#include(CTest) # NOT REQUIRED, hence, commented out
#include(GoogleTest) # NOT REQUIRED, hence, commented out
add_executable(
mytest
test/mytest.cpp
)
target_link_libraries(
mytest
gtest_main
)
gtest_discover_tests(
mytest
)