cmake-templates
Some CMake Templates.
1. Overview
Conventions
😄 means tested okay/good😡 means test result not sufficiently good❓ means not tested yet
Project | Linux + GCC 4.8+ | Win + VS2010 | Win + VS2015 | macOS |
---|---|---|---|---|
c | ||||
c++ | ||||
c++11 | ||||
c++11vs2010 | ||||
module | ||||
opencv | ||||
opencv3 | ||||
boost | ||||
qt4-console | ||||
qt4-gui | ||||
qt4-project | ||||
qt5-project |
2. Usage
2.1. Windows
Use CMake-GUI
to generate Visual Studio 2010 project, then use Visual Studio to compile & run.
Here is a Tutorial: HOWTO: Win + CMake + Visual Studio 2010 · Issue #1 · district10/cmake-templates.
2.2. Linux
Most commonly, we build Makefile project:
# cd source dir (there should be a CMakeLists.txt)
mkdir build && cd build
cmake .. # want a release build? try `cmake -DCMAKE_BUILD_TYPE=Release ..'
make
# then checkout the generated binary files
But we can build CodeBlocks projects too, see my tutorial: HOWTO: Linux + CMake + CodeBlocks + GNU Make · Issue #2 · district10/cmake-templates, or use qt-creator to open CMakeLists.txt directly, see my tutorial: HOWTO: Use Qt creator to Open CMakeLists.txt directly (will generate proper project files) · Issue #5 · district10/cmake-templates.
3. Examples
3.1. C Example
Simple C project.
project( C )
cmake_minimum_required( VERSION 2.6 )
add_executable( ${PROJECT_NAME} main.c )
cmake_minimum_required( ... )
is needed in root CMakeLists.txt, always.
The ${PROJECT_NAME}
is variable with value C
,
which is set by the project( C )
.
See c.
3.2. C++ Example
Simple C++ project.
project( CPP )
make_minimum_required( VERSION 2.6 )
file( GLOB SRCS *.c *.cpp *.cc *.h *.hpp ) # a variable called SRCS with all files whose path match "*.c *.cpp..."
add_executable( ${PROJECT_NAME} ${SRCS} )
See cpp.
3.3. C++11 Example
C++11 project.
include( CheckCXXCompilerFlag )
check_cxx_compiler_flag( "-std=c++11" COMPILER_SUPPORTS_CXX11 )
check_cxx_compiler_flag( "-std=c++0x" COMPILER_SUPPORTS_CXX0X )
if( COMPILER_SUPPORTS_CXX11 )
if( CMAKE_COMPILER_IS_GNUCXX )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11" )
else()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
endif()
elseif( COMPILER_SUPPORTS_CXX0X)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x" )
else()
# MSVC, On by default (if available)
endif()
See cpp11.
I recommend Visual Studio 2015 Community Edition.
3.4. Example to Show How to Modualize Your Project
# root cmakelists.txt
project( MODULES )
cmake_minimum_required( VERSION 2.8.3 )
include_directories( ${CMAKE_SOURCE_DIR}/includes )
add_subdirectory( src )
add_subdirectory( demo )
# src dir
add_subdirectory( cubic )
add_subdirectory( extras )
add_subdirectory( square )
# cubic
add_library( LibCubic ${CUBICS} cubic.c )
# demo
project( CALC )
cmake_minimum_required( VERSION 2.6 )
set( EXTRA_LIBS ${EXTRA_LIBS} LibSquare )
set( EXTRA_LIBS ${EXTRA_LIBS} LibExtras )
set( EXTRA_LIBS ${EXTRA_LIBS} LibCubic )
add_executable( Calc calc.c )
target_link_libraries( Calc ${EXTRA_LIBS} )
See modules.
3.5. Example with Support of Boost
project( BOOST )
cmake_minimum_required( VERSION 2.6 )
find_package( Boost REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
LINK_DIRECTORIES( ${Boost_LIBRARY_DIRS} )
set( Boost_USE_STATIC_LIBS OFF )
set( Boost_USE_MULTITHREADED ON )
set( Boost_USE_STATIC_RUNTIME OFF )
set( BOOST_ALL_DYN_LINK ON ) # force dynamic linking for all libraries
add_executable( ${PROJECT_NAME} main.cpp )
target_link_libraries( ${PROJECT_NAME} ${Boost_LIBRARIES} )
Ubuntu install: sudo apt-get install libboost-all-dev
.
See boost.
3.6. Example with Support of OpenCV
Want to how to configure both opencv 2 & 3 on your system? Checkout my tutorial: HOWTO: OpenCV 2 & OpenCV 3 · Issue #4 · district10/cmake-templates.
opencv 2 or less
project( OPENCV )
cmake_minimum_required( VERSION 2.6 )
include( $ENV{OpenCV2_DIR}/OpenCVConfig.cmake ) # find_package( OpenCV REQUIRED )
message( STATUS "OpenCV library status:" )
message( STATUS " version: ${OpenCV_VERSION}" )
message( STATUS " libraries: ${OpenCV_LIBS}" )
message( STATUS " include path: ${OpenCV_INCLUDE_DIRS}" )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( ${PROJECT_NAME} minarea.c )
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} )
opencv 3
project( OPENCV3 )
cmake_minimum_required( VERSION 2.8 )
include( $ENV{OpenCV3_DIR}/OpenCVConfig.cmake ) # find_package( OpenCV REQUIRED )
message( STATUS "OpenCV library status:" )
message( STATUS " version: ${OpenCV_VERSION}" )
message( STATUS " libraries: ${OpenCV_LIBS}" )
message( STATUS " include path: ${OpenCV_INCLUDE_DIRS}" )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( ${PROJECT_NAME} example.cpp )
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} )
See
3.7. Example with Support of Qt4
Be sure to make qmake
caught by CMake, put it in your $PATH
.
qt4 console
find_package( Qt4 REQUIRED )
include( ${QT_USE_FILE} )
set( QT_DONT_USE_QTGUI TRUE )
add_executable( ${PROJECT_NAME} main.cpp )
target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )
configure file
configure_file(
"${PROJECT_SOURCE_DIR}/Configs.h.in"
"${PROJECT_BINARY_DIR}/Configs.h" )
moc, uic
file( GLOB_RECURSE HDRS_FILES *.h *.hpp )
file( GLOB_RECURSE SRCS_FILES *.cpp )
file( GLOB_RECURSE UI_FILES *.ui )
qt4_wrap_cpp( MOC_SRCS ${HDRS_FILES} )
qt4_wrap_ui( UI_HDRS ${UI_FILES} )
source_group( "UI Files" FILES ${UI_FILES} )
source_group( "Generated Files" FILES ${MOC_SRCS} ${UI_HDRS} )
add_library( ${PROJECT_NAME} STATIC ${SRCS_FILES} ${UI_FILES} ${HDRS_FILES} ${MOC_SRCS} ${UI_HDRS} )
target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )
Works like qmake -project
, one ring to rule them all:
project( QT4 )
cmake_minimum_required( VERSION 2.6 )
find_package( Qt4 REQUIRED )
include( ${QT_USE_FILE} )
include_directories( ${CMAKE_SOURCE_DIR}/ )
include_directories( ${CMAKE_BINARY_DIR}/ )
# based on: https://cmake.org/Wiki/CMakeMacroFilterOut
macro( filter_out FILTERS INPUTS OUTPUTS )
set( FOUT "" )
foreach( INP ${INPUTS} )
set( FILTERED 0 )
foreach( FILT ${FILTERS} )
if( ${FILTERED} EQUAL 0 )
if( "${FILT}" STREQUAL "${INP}" )
set( FILTERED 1 )
endif( "${FILT}" STREQUAL "${INP}" )
if( ${INP} MATCHES ${FILT} )
set( FILTERED 1 )
endif( ${INP} MATCHES ${FILT} )
endif( ${FILTERED} EQUAL 0 )
endforeach( FILT ${FILTERS} )
if( ${FILTERED} EQUAL 0 )
set( FOUT ${FOUT} ${INP} )
endif( ${FILTERED} EQUAL 0 )
endforeach( INP ${INPUTS} )
set( ${OUTPUTS} ${FOUT} )
endmacro( filter_out FILTERS INPUTS OUTPUTS )
file( GLOB_RECURSE UI_FILES *.ui )
file( GLOB_RECURSE HDRS_FILES *.h *.hpp )
file( GLOB_RECURSE SRCS_FILES *.cpp *.c )
file( GLOB_RECURSE RCS_FILES *.qrc )
set( FILTERS ".*CompilerId.*" )
set( FILTERS ".*CMakeFiles/.*" )
filter_out("${FILTERS}" "${SRCS_FILES}" SRCS_FILES )
qt4_wrap_cpp( MOC_SRCS ${HDRS_FILES} )
qt4_wrap_ui( UI_HDRS ${UI_FILES} )
qt4_add_resources( RCS ${RCS_FILES} )
source_group( "UI Files" FILES ${UI_FILES} )
source_group( "Generated Files" FILES ${MOC_SRCS} ${UI_HDRS} )
source_group( "All Resource Files" FILES ${RCS} )
add_executable( ${PROJECT_NAME}
${MOC_SRCS}
${HDRS_FILES}
${SRCS_FILES}
${UI_FILES}
${UI_HDRS} ${RCS} )
target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )
See
- qt4 console application (VS2010
😄 , Linux😄 ) - qt4 GUI application (check out the configs.h.in file) (VS2010
😄 , Linux😄 ) - qt4 application for lazy people, works like
qmake -project && qmake && make
on Linux (VS2010😄 , Linux😄 )
3.8. Example with Support of Qt5
project( Qt5Project )
cmake_minimum_required( VERSION 2.8.11 )
# root of your msvc14 x64 prebuild
set( CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Qt/Qt5-msvc14/5.6/msvc2015_64" )
set( CMAKE_INCLUDE_CURRENT_DIR ON )
set( CMAKE_AUTOMOC ON )
find_package( Qt5Widgets REQUIRED )
qt5_wrap_ui( UI_HEADERS mainwindow.ui )
qt5_add_resources( QRCS resources.qrc )
add_executable( ${PROJECT_NAME} main.cpp mainwindow.cpp ${UI_HEADERS} ${QRCS} )
target_link_libraries( ${PROJECT_NAME} Qt5::Widgets )
See qt5 project.
3.9. Get'em Together (advanced examples)
This part is called CMake in Action.
- ToyAuthor/luapp: Using lua in C++ style. Build system is CMake.
- a great cmake wrapper for lua, a great c++ wrapper for lua
- I forked it, and annotated (in chinese), it's really great! My fork: 4ker/luapp: Using lua in C++ style. Build system is CMake..
- district10/algo: 重复造轮子。
- Libs
- google test (gmock), for testing and benchmarking, etc
- cppformat, the missing string formating lib
- modulized
- advanced linking style
- Libs
- https://github.com/district10/bcp/tree/standalone
4. TODO
- More documentation
- More elegant & illustrative examples
- Planned Examples
- for Windows, link
*.lib
files - for Linux, link
*.a
,*.so
files, setrpath
- etc.
- for Windows, link
5. Snippets & Helper Functions
cpp -> exe
file( GLOB SRCS src/*.cpp)
foreach( src ${SRCS} )
string( REGEX REPLACE "(^.*/|.cpp$)" "" exe ${src} )
message( STATUS "${exe} <-- ${src}" )
add_executable( ${exe} ${src} )
endforeach( src )
There are some utility functions in utilities.cmake
, use include(utilities.cmake)
to include, then use
print_include_directories()
to print all included directories,print_all_linked_libraries(your_exe_or_lib)
to print all linked libs,print_all_variables()
to print all variables
Tip, use cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=YES ..
to generate compile commands (a json file).
6. ReadingList
These links may be useful:
- Search · cmake templates
- giddie/qt-cmake-template: Project template using CMake / Qt / NSIS or WiX / MinGW or MSVS combined in easy-to-use form
- cginternals/cmake-init: Template for reliable, cross-platform C++ project setup using cmake.
7. Koan
- CMake's documentation is not for human. It really smells
- Adapt to various standards is by no means easy, it's kind of brain fucking