平台的选择
linux 上编写 GUI 程序,C 语言是比较好的选择,而且 GTK 已经移植到了 MAC 和 Windows 上
make cmake makefile
make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
make 工具就根据 makefile 中的命令进行编译和链接的。makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
cmake就可以更加简单的生成makefile文件给上面那个make用。当然cmake还有其他更牛X功能,就是可以跨平台生成对应平台能用的makefile,我们就不用再自己去修改了。
CMAKE
微软、Google 以及 Facebook 这三家公司都有自己的 C++ 构建系统,他们开源的项目仍支持使用 CMake 构建;并且 CMake 是除了官方构建系统之外的推荐构建系统。
CMake 是函数申明式语法,使用最为广泛的构建工具之一,几乎能成为模块描述工具了,但肯定不是最好的构建工具。
其缺点是生成了大量中间文件,语法丑陋不堪,构建效率一般;编写过程痛苦,需要查询很多文档(文档质量水平不够),如果有特殊需求会痛苦得无以复加,诸如特殊外部依赖(譬如使用某个其它位置的 boost 库)会很痛苦。
Debug
message(STATUS ${PROJECT_BINARY_DIR})
打印出相关变量
Hello CMake
├── CMakeLists.txt
├── main.cpp
- CMakeLists.txt - 包含了 CMake 命令
- main.cpp - 源代码
CMakeLists.txt是存储所有CMake命令的文件。当cmake运行在一个文件夹中,它将寻找这个文件,如果它不存在,cmake将退出与一个错误。
cmake 版本
cmake_minimum_required(VERSION 3.5)
当使用CMake创建项目时,您可以指定你的 cmake 语句所支持的CMake的最小版本。
添加执行文件
add_executable(hello_cmake main.cpp)
add_executable() 函数的第一个参数是要构建的可执行文件的名称,第二个参数是要编译的源文件列表。
项目宏
cmake_minimum_required(VERSION 2.6)
project (hello_cmake)
add_executable(${PROJECT_NAME} main.cpp)
project()函数将创建一个值为 hello_cmake 的变量 ${PROJECT_NAME}。
Variable | Info |
---|---|
CMAKE_SOURCE_DIR | The root source directory |
CMAKE_CURRENT_SOURCE_DIR | The current source directory if using sub-projects and directories. |
PROJECT_SOURCE_DIR | The source directory of the current cmake project. |
CMAKE_BINARY_DIR | The root binary / build directory. This is the directory where you ran the cmake command. |
CMAKE_CURRENT_BINARY_DIR | The build directory you are currently in. |
PROJECT_BINARY_DIR | The build directory for the current project. |
编译含有 include 的项目
├── CMakeLists.txt
├── include
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
cmake_minimum_required(VERSION 3.5)
project (hello_headers)
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(hello_headers ${SOURCES}) // 编译出来是一个可执行文件
target_include_directories(hello_headers
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
main 用到了 hello 中的函数,所以 main 文件中含有 hello 的头文件,只是代码分块,不代表 hello 文件是一个库。
设置源代码变量
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
创建源代码文件变量会让你的项目看起来更加清晰,也可以通过文件通配符来选定源文件
file(GLOB SOURCES "src/*.cpp")
target_include_directories 函数
target_include_directories(hello_headers
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
编译给定目标时使用的包含目录,第一个参数是 target,必须是由 add_executable() 或 add_library() 等命令创建的,并且不能是ALIAS目标。
target_include_directories 函数的作用,是将 target 用到的 include 文件标记出来。
编译静态库
├── CMakeLists.txt
├── include
│ └── static
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
cmake_minimum_required(VERSION 3.5)
project(hello_library)
############################################################
# Create a library
############################################################
#Generate the static library from the library sources
add_library(hello_library STATIC
src/Hello.cpp
)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
############################################################
# Create an executable
############################################################
# Add an executable with the above sources
add_executable(hello_binary
src/main.cpp
)
# link the new hello_library target with the hello_binary target
target_link_libraries(hello_binary
PRIVATE
hello_library
)
这是一个简化的示例,显示了同一个文件夹中的库和二进制文件。
Add_library() 函数用于从一些源文件创建库,第一个参数是名字,第二个是源文件。
target_include_directories 函数的 scope 设置为了 PUBLIC ,因为这个头文件被编译在了,这个库文件,已经所有用到改库的地方。
- PRIVATE - 只用在了 target 文件的
- INTERFACE - 用在了任何链接该库的 target 文件中
- PUBLIC - 两者都有
传递给 target_include_directories 的目录将是包含目录树的根目录,你的 c 文件应该包含从那里到头文件的路径。
#include "static/Hello.h"
当创建一个将使用库的可执行文件时,必须告诉编译器有关库的信息。这可以使用 target_link_libraries() 函数来完成。
编译动态库
add_library(hello_library SHARED
src/Hello.cpp
)
区别在于 STATIC 变成了 SHARED
add_library(hello::library ALIAS hello_library)
add_library ALIAS 可以将库名变成一个别称
install
将项目生成的库文件、头文件、可执行文件或相关文件等安装到指定位置(系统目录,或发行包目录)。在cmake中,这主要是通过install方法在CMakeLists.txt中配置,make install命令安装相关文件来实现的。
基本安装路径由变量 CMAKE_INSTALL_PREFIX 控制,该变量可以通过 ccmake 设置或通过 cmake .. -DCMAKE_INSTALL_PREFIX=/install/location
命令来设置。
install (TARGETS cmake_examples_inst_bin DESTINATION bin)
将 add_executable() 或 add_library() 等命令创建的目标文件安装到 ${CMAKE_INSTALL_PREFIX}/bin
# Binaries
install (TARGETS cmake_examples_inst_bin
DESTINATION bin)
# Library
install (TARGETS cmake_examples_inst
LIBRARY DESTINATION lib)
# Header files
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION include)
# Config
install (FILES cmake-examples.conf
DESTINATION etc)
构建级别
CMake具有许多内置的构建配置,可用于编译工程。 这些配置指定了代码优化的级别,以及调试信息是否包含在二进制文件中。这些优化级别,主要有:
Release —— 不可以打断点调试,程序开发完成后发行使用的版本,占的体积小。 它对代码做了优化,因此速度会非常快, 在编译器中使用命令: -O3 -DNDEBUG 可选择此版本。、
Debug ——调试的版本,体积大。 在编译器中使用命令: -g 可选择此版本。
MinSizeRel—— 最小体积版本 在编译器中使用命令:-Os -DNDEBUG可选择此版本。
RelWithDebInfo—— 既优化又能调试。 在编译器中使用命令:-O2 -g -DNDEBUG可选择此版本。
第三方库
几乎所有项目都将要求包含第三方库,标头或程序。 CMake 支持使用 find_package() 函数查找这些工具的路径。 这将从 CMAKE_MODULE_PATH 中的文件夹列表中搜索格式为“ FindXXX.cmake”的 CMake 模块。 在linux上,默认搜索路径将包括/ usr / share / cmake / Modules。 在我的系统上,这包括对大约142个通用第三方库的支持。