本CMake系列是依據github上的cmake-examples進行翻譯總結。同時對於不懂的地方進行總結與標註。希望本系列能節省你學習CMake的時間。
學習方式是在實踐中利用github上的example學習,同時對於不懂的地方主要通過翻譯官方手冊學習,其次是查找博客上的私人理解。
因爲每一個example都是一個工程,所以講解時會利用文件樹解釋每一個文件裏的語法。
英文github地址:https://github.com/ttroy50/cmake-examples
CMake英文官方教程: https://cmake.org/cmake/help/latest/guide/tutorial/index.html
文章目錄
首先說一下什麼是編譯標誌(或者 叫編譯選項)。可執行文件的生成離不開編譯和鏈接,那麼如何編譯,比如編譯時使用C++的哪一個標準?這些編譯設置都在CMAKE_CXX_FLAGS變量中。(C語言編譯選項是CMAKE_C_FLAGS)
設置的方法總共有三種,分別爲本文2.1、2.2、以及2.3
一 文件樹
├── CMakeLists.txt
├── main.cpp
1.1 main.cpp
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Hello Compile Flags!" << std::endl;
// only print if compile flag set
#ifdef EX2
std::cout << "Hello Compile Flag EX2!" << std::endl;
#endif
#ifdef EX3
std::cout << "Hello Compile Flag EX3!" << std::endl;
#endif
return 0;
}
1.2 CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
#強制設置默認C++編譯標誌變量爲緩存變量,如CMake(五) build type所說,該緩存變量被定義在文件中,相當於全局變量,源文件中也可以使用這個變量
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
project (compile_flags)
add_executable(cmake_examples_compile_flags main.cpp)
#爲可執行文件添加私有編譯定義
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
#命令的具體解釋在二 CMake解析中,這裏的註釋只說明註釋後每一句的作用
二 CMake解析
2.1 設置每個目標編譯標誌
在現代CMake中設置C ++標誌的推薦方法是專門針對某個目標(target)設置標誌,可以通過target_compile_definitions()函數設置某個目標的編譯標誌。
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
如果這個目標是一個庫(cmake_examples_compile_flags),編譯器在編譯目標時添加定義-DEX3 ,並且選擇了範圍PUBLIC或INTERFACE,該定義-DEX3也將包含在鏈接此目標(cmake_examples_compile_flags)的所有可執行文件中。 注意,本語句使用了PRIVATE,所以編譯選項不會傳遞。
對於編譯器選項,還可以使用target_compile_options()函數。
target_compile_definitions(<target>
2 <INTERFACE|PUBLIC|PRIVATE> [items1...]
3 [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
是給 target
添加編譯選項, target
指的是由 add_executable()
產生的可執行文件或 add_library()
添加進來的庫。<INTERFACE|PUBLIC|PRIVATE>
指的是[items...]
選項可以傳播的範圍, PUBLIC and INTERFACE
會傳播 <target>
的 INTERFACE_COMPILE_DEFINITIONS 屬性, PRIVATE and PUBLIC
會傳播 target
的 COMPILE_DEFINITIONS 屬性。
2.2 設置默認編譯標誌
默認的CMAKE_CXX_FLAGS爲空或包含適用於構建類型的標誌。 要設置其他默認編譯標誌,如下使用:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
強制設置默認C++編譯標誌變量爲緩存變量,如CMake(五) build type所說,該緩存變量被定義在文件中,相當於全局變量,源文件中也可以使用這個變量。這個變量原本包含的參數仍然存在,只是添加了EX2。
CACHE STRING "Set C++ Compiler Flags" FORCE
命令是爲了強制將CMAKE_CXX_FLAGS變量 放到CMakeCache.txt文件中
"${CMAKE_CXX_FLAGS} -DEX2"
這個字符串可以保留原有的CMAKE_CXX_FLAGS中的參數,額外添加了一個EX2參數。注意寫法:空格,並且參數前加了-D
類似設置CMAKE_CXX_FLAGS,還可以設置其他選項:
- 設置C編譯標誌: CMAKE_C_FLAGS
- 設置鏈接標誌:CMAKE_LINKER_FLAGS.
2.3 設置CMake標誌
與構建類型類似,可以使用以下方法設置全局C 編譯器標誌。
-
利用ccmake或者gui
-
在cmake命令行中:
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
2.4 區別
- 2.2方法的設置CMAKE_C_FLAGS和CMAKE_CXX_FLAGS將爲該目錄或所有包含的子目錄中的所有目標全局設置一個編譯器標誌。 現在不建議使用該方法,首選使用target_compile_definitions函數。
- 2.1方法是被建議的,只爲這個目標設置編譯選項 。
- 2.3設置的也是全局編譯器選項。
三 構建示例
$ mkdir build
$ cd build/
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build
$ make VERBOSE=1
/usr/bin/cmake -H/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags -B/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/depend
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
cd /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake --color=
Dependee "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Dependee "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Scanning dependencies of target cmake_examples_compile_flags
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/build
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 1
[100%] Building CXX object CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o
/usr/bin/c++ -DEX2 -o CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/main.cpp
Linking CXX executable cmake_examples_compile_flags
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_examples_compile_flags.dir/link.txt --verbose=1
/usr/bin/c++ -DEX2 CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -o cmake_examples_compile_flags -rdynamic
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 1
[100%] Built target cmake_examples_compile_flags
make[1]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 0
微信公衆號
歡迎大家關注我的個人公衆號,現階段主要總結Robomaster相關的計算機視覺知識:Qt,C++,CMake,OpenCV等等
公衆號名稱:三豐雜貨鋪