cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-09 LANGUAGES CXX)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(animals
SHARED
Animal.cpp
Animal.hpp
Cat.cpp
Cat.hpp
Dog.cpp
Dog.hpp
Factory.hpp
)
//这里为指定的目标(即库文件)设定语言标准
//这里就是对象的某些特定属性,这里是对对象的PROPERTIES进行设置,
//其实和我们在第一章节的第一部分中对库文件的输出文件名的设置没有什么格式/命令上的区别
//只不过当时我们设置的是OUTPUT_NAME属性,这里我们设置的属性和语言相关
set_target_properties(animals
PROPERTIES
CXX_STANDARD 14 //C++14标准
CXX_EXTENSIONS OFF //只启用 ISO C++ 标准的编译器标志,而不使用特定编译器的扩展。
CXX_STANDARD_REQUIRED ON //指定所选标准版本,如果版本不可用,则向前寻找最新的可用版本
//即如果C++14不可用则搜寻C++11,如果再不可用随后是C++98...(实际上会先从最新的C++20版本开始寻找)
POSITION_INDEPENDENT_CODE 1//暂不解释
)
add_executable(animal-farm animal-farm.cpp)
set_target_properties(animal-farm
PROPERTIES
CXX_STANDARD 14
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
)//与之上同理,不过这里我们的对象是可执行文件而非库文件
target_link_libraries(animal-farm animals)
之前我们使用if-else-elseif-endif语句对编译进行了一些控制:【Learning CMake Cookbook】第一章–第二部分
其实和大多数语言一样,除了这种分支语句,CMake中也提供了创建循环的语句,说道循环语句,无非就是for循环和while循环:
1、foreach() -- endforeach()
2、while() -- endwhile()
以上的二者都可以结合**break()语句以及continue()**语句来使用
下面我们来看使用示例:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-10 LANGUAGES CXX)
add_library(geometry
STATIC
geometry_circle.cpp
geometry_circle.hpp
geometry_polygon.cpp
geometry_polygon.hpp
geometry_rhombus.cpp
geometry_rhombus.hpp
geometry_square.cpp
geometry_square.hpp
)
target_compile_options(geometry
PRIVATE
-O3
)//编译选项,编译器优化级别-O3来优化对库的编译
//注意这里的优化等级是O3
list(
APPEND sources_with_lower_optimization
geometry_circle.cpp
geometry_rhombus.cpp
)//我们为其中的两个源文件创建一个列表,之后对列表中的文件有单独的处理
message(STATUS "Setting source properties using IN LISTS syntax:")
foreach(_source IN LISTS sources_with_lower_optimization)
set_source_files_properties(${_source} PROPERTIES COMPILE_FLAGS -O2)
//对列表中的文件,使用foreach的方式进行遍历,对其中的每个源文件设置一个更低的优化等级
message(STATUS "Appending -O2 flag for ${_source}")
endforeach()
message(STATUS "Querying sources properties using plain syntax:")
foreach(_source ${sources_with_lower_optimization})
get_source_file_property(_flags ${_source} COMPILE_FLAGS)
message(STATUS "Source ${_source} has the following extra COMPILE_FLAGS: ${_flags}")
//这个for循环用于打印验证,看看我们是否真的为列表选中的文件实施了更低的优化等级
endforeach()
add_executable(compute-areas compute-areas.cpp)
target_link_libraries(compute-areas geometry)
对于以上情况的猜想以及验证:
对于除了我们设定list中的两个源文件,其他的文件的优化级别应该都是-O3,我们也可以通过foreach循环的方式对其进行查看。于是我们修改代码,将所有的文件汇入一个global列表,依次对其进行查看:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-10 LANGUAGES CXX)
list(
APPEND global_sources
geometry_circle.cpp
geometry_circle.hpp
geometry_polygon.cpp
geometry_polygon.hpp
geometry_rhombus.cpp
geometry_rhombus.hpp
geometry_square.cpp
geometry_square.hpp
)
add_library(geometry
STATIC
${global_sources}
)
target_compile_options(geometry
PRIVATE
-O3
)
list(
APPEND sources_with_lower_optimization
geometry_circle.cpp
geometry_rhombus.cpp
)
message(STATUS "Setting source properties using IN LISTS syntax:")
foreach(_source IN LISTS sources_with_lower_optimization)
set_source_files_properties(${_source} PROPERTIES COMPILE_FLAGS -O2)
message(STATUS "Appending -O2 flag for ${_source}")
endforeach()
message(STATUS "Querying sources properties using plain syntax:")
foreach(_source ${global_sources})
get_source_file_property(_flags ${_source} COMPILE_FLAGS)
message(STATUS "Source ${_source} has the following extra COMPILE_FLAGS: ${_flags}")
endforeach()
add_executable(compute-areas compute-areas.cpp)
target_link_libraries(compute-areas geometry)
发现执行 cmake…后输出的是如下的结果:
... lots of output ...
-- Source geometry_circle.cpp has the following extra COMPILE_FLAGS: -O2
-- Source geometry_circle.hpp has the following extra COMPILE_FLAGS: NOTFOUND
-- Source geometry_polygon.cpp has the following extra COMPILE_FLAGS: NOTFOUND
-- Source geometry_polygon.hpp has the following extra COMPILE_FLAGS: NOTFOUND
-- Source geometry_rhombus.cpp has the following extra COMPILE_FLAGS: -O2
-- Source geometry_rhombus.hpp has the following extra COMPILE_FLAGS: NOTFOUND
-- Source geometry_square.cpp has the following extra COMPILE_FLAGS: NOTFOUND
-- Source geometry_square.hpp has the following extra COMPILE_FLAGS: NOTFOUND
... lots of output ...
即,除了我们设置的两个文件外,其他的编译优化标志都是NOTFOUND。于是我们选择使用在build阶段查看并验证结果:同样输出之前提到过的指令:cmake --build . – VERBOSE=1,得到验证结果如下:
... lots of output ...
/usr/bin/c++ -O3 -O2 -MD -MT CMakeFiles/geometry.dir/geometry_circle.cpp.o
... lots of output ...
/usr/bin/c++ -O3 -MD -MT CMakeFiles/geometry.dir/geometry_polygon.cpp.o
... lots of output ...
可见验证成功,之后的-O2应该会覆盖之前的-O3的优化等级,但具体为何在cmake的configure阶段的命令行输出没有得到验证结果,可能是因为没有使用正确的指令对编译标志进行查看,在之后的学习阶段可能会遇到,再来进行补充。