First, modify the CMakeLists.txt
file to use the project()
command to set the project name and version number.
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
The easiest way to enable support for a specific C++ standard in CMake is by using the CMAKE_CXX_STANDARD
variable. For this tutorial, set the CMAKE_CXX_STANDARD
variable in the CMakeLists.txt
file to 11
and CMAKE_CXX_STANDARD_REQUIRED
to True
. Make sure to add the CMAKE_CXX_STANDARD
declarations above the call to add_executable
.
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 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(COMPILE_OPTIONS -std=c++11)
add executable files
add_executable (Tutorial "testCmake.cpp" "testCmake.h" "A.h" "A.cpp")
#the output or target of build is Tutorial
once you change the version of standard c++ to 20 you can use execution library
#include <iostream>
#include <algorithm>
#include <vector>
#include <execution>
int main(int argc, char* argv[])
{
std::vector<uint16_t> vec{ 34,545,23,56,565,54,24,54,6,7,4,5334,5,65,7,5 };
std::for_each(std::execution::par, vec.begin(), vec.end(), [](uint16_t v) {std::cout << v << std::endl; });
std::cout << "!\n";
}
toolchain
CMake uses a toolchain of utilities to compile, link libraries and create archives, and other tasks to drive the build.
there are two ways to add it inside cmakeLists
set( CMAKE_TOOLCHAIN_FILE "C:/vcpkg/scripts/buildsystems/vcpkg.cmake" )
or by command line
cmake -DCMAKE_TOOLCHAIN_FILE=/foo/bar.cmake <other args>
prefix path used to help cmake for commands like find_package or find_path
cmake -DCMAKE_PREFIX_PATH=~/deliveries/hiphop
include files and libraries
after you add CMAKE_TOOLCHAIN_FILE OR CMAKE_PREFIX_PATH to your project actually you can looking for path or library or package and add them to your cmakelist file lets start with find_path
how to add include path
#looking for path of boost/coroutine/all.hpp and save it in variable
LIBS_PATH
find_path(LIBS_PATH boost/coroutine/all.hpp)
#then add it to executable target project in our situation is Tutorial
#private is mean all directories added to this target cannot access by other target
target_include_directories(Tutorial PRIVATE
${LIBS_PATH}
)
#the difference between target_include_directories and include_directories
#the first one affect on the target only and the second one affect on the all targets in cmakelist
include_directories(${LIBS_PATH})
Packages and Libraries
Packages provide dependency information to CMake based buildsystems. Packages are found with the find_package() command. The result of using find_package() is either a set of IMPORTED targets, or a set of variables corresponding to build-relevant information.
Imagine you want to use zlib in your project, you need to find the header file zlib.h
, and the library libz.so
(on Linux). You can use the low-level cmake commands find_path
and find_library
to find them, or you can use find_package(ZLIB)
. The later command will try to find out all what is necessary to use zlib. It can be extra macro definitions, or dependencies.find_package
: when the CMake command find_package(SomeThing)
is called, as says the documentation, there are two possibility: the module mode (that searches for a file FindSomeThing.cmake
), or the config mode (that searches for a file named SomeThingConfig.cmake
).
#add zlib
find_package (ZLIB REQUIRED)
if (ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries (Tutorial ${ZLIB_LIBRARIES})
endif (ZLIB_FOUND)
#add opencv
# Find Package
find_package( OpenCV REQUIRED )
if( OpenCV_FOUND )
# Additional Include Directories
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( project ${OpenCV_LIBS} )
endif()
#add coroutine library from boost
find_package(Boost REQUIRED COMPONENTS coroutine)
target_link_libraries(testCmake PRIVATE Boost::coroutine)
#if is there no dependencies like zlib you can use
find_library(ZLIB_LIB zlib)
target_link_libraries (testCmake ${ZLIB_LIB})
Qt With Cmake
cmake_minimum_required(VERSION 3.1.0)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_PREFIX_PATH "/home/rip/Qt/5.12.1/gcc_64/lib/cmake")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
find_package(Qt5 COMPONENTS Widgets REQUIRED)
add_executable(helloworld
mainwindow.ui
mainwindow.cpp
main.cpp
resources.qrc
)
target_link_libraries(helloworld Qt5::Widgets)
if you never add toolchain or prefix path
cmake_minimum_required (VERSION 3.9)
project ("testCmake" VERSION 1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(testCmake "src/main.cpp")
include_directories("C:/dev/vcpkg/installed/x64-windows")
find_path(ZLIB_PATH "zlib.h")
include_directories(${ZLIB_PATH})
link_directories("C:/dev/vcpkg/installed/x64-windows/lib/")
FIND_LIBRARY(mylib zlib)
message("zlib in ${mylib}")
TARGET_LINK_LIBRARIES(testCmake ${mylib})
How To Create library and attach it to our project
create subdirectory and add CMakeLists.txt to it
ADD_LIBRARY(MyLib STATIC|SHARED MyLib.cpp MyLib.h)
then back to main CmakeLists and add the folder as asubdirectory and link to it library dont warry cmake automaticly add .lib or .a to file and the last thing you can add directory as include directory
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/MyLib)
target_link_libraries(Tutorial PRIVATE MyLib)
target_include_directories(Tutorial PRIVATE MyLib)
#or
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/MyLib)
target_link_libraries(Tutorial PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/MyLib/MyLib.lib)
target_include_directories(Tutorial PRIVATE MyLib)
cpack
#add this to end of CMakeLists
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "2")
include(CPack)
after finished from build project you can call cpack command inside build directory
Miscellaneous
example Add all files in the project to executable
set(FORMS_DIR "${CMAKE_SOURCE_DIR}/forms")
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
set(SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
include_directories(${FORMS_DIR})
include_directories(${INCLUDE_DIR})
include_directories(${SOURCE_DIR})
file(GLOB_RECURSE SOURCES
"${FORMS_DIR}/*.ui"
"${FORMS_DIR}/*.qrc"
"${INCLUDE_DIR}/*.h"
"${SOURCE_DIR}/*.cpp"
)
add_executable(MY_PROJECT ${SOURCES})
if (system)
if (WIN32)
#do something
elseif (UNIX)
#do something
endif ()
#other example
if(UNIX AND NOT APPLE)
# for Linux, BSD, Solaris, Minix
endif()
#other example
if (MSVC)
#do something
endif (MSVC)
copy files to binary folder
set(QML_FOLDER "qmls")
file(GLOB_RECURSE QMLS "${QML_FOLDER}/*.qml")
file(COPY ${QMLS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${QML_FOLDER})
check compiler
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# using GCC
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel C++
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# using Visual Studio C++
endif()
set compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -DNO_DEBUG")
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")