C++ 编译与构建工具
主要用于将 C++ 源代码转换为可执行程序。它们可以分为以下几类:
1.编译器: 将 C++ 源代码转换为机器代码。 常用的编译器包括: GCC(GNU Compiler Collection):支持多种平台,开源免费。 Clang(C Language Family Compiler):LLVM 项目的一部分,支持多种平台,开源免费。 Visual Studio:微软开发的编译器,支持 Windows 平台。
2.链接器: 将编译后的目标文件链接在一起,形成可执行程序。 常用的链接器包括: GNU ld:GCC 的链接器。 lld:LLVM 项目的链接器。 Link:Visual Studio 的链接器。
3.构建工具: 自动化编译和链接的过程。 常用的构建工具包括: Make:GNU 的构建工具,使用 Makefile 文件描述构建规则。 CMake:跨平台构建工具,使用 CMakeLists.txt 文件描述构建规则。 Ninja:快速构建工具,支持多平台和多核编译。
选择合适的 C++ 编译与构建工具取决于项目的具体需求。 以下是一些建议:
GCC(全称GNU Compiler Collection):是一种多平台编译器,由GNU开发,最初用于编译C语言(GNU C Compiler)。
gcc可以将C语言源程序编译、链接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件(g++类似,是编译C++程序的)。
gcc hello.c
gcc hello.c -include /root/pianopan.h //包含include
gcc hello.c -lcurses //包含lib
g++ hello.cpp
gdb又称GNU调试器,是Unix下的调试工具,可以用于:
gcc hello.c -d
make工具相当于一个批处理工具,本身没有编译和链接的功能,而是用类似于批处理的方式通过调用makefile文件中用户指定的编译命令(如gcc、g++)来进行编译和链接(当作批处理工具用就行)。
makefile相当于用户将要执行的一系列命令,make根据makefile中的命令对相应的源文件进行编译和链接。
makefile文件在github源码安装程序中很常见,下载一个源码包,通常在readme中会有这样的一句:
make all
make install
make all即编译所有,当然这个源码包中必须有makefile文件才行,执行make all这个命令后make会根据makefile中的命令进行编译。
在大型工程的编译时,一版使用cmake,对应的编译文件是CMakeList.txt。
如果要自己编译很多源文件的时候就需要cmake工具,可以更加方便地生成makefile文件给make用。cmake还可以跨平台生成对应平台可用的makefile,无需自己根据每个平台的不同特性修改。
cmake根据CMakeList.txt文件生成makefile,在IDE中会由IDE自动生成CMakeLists.txt。
同样在开源工程中很常见,对源码的编译通常是:
mkdir build && cd build
cmake ..
make
make install
CMake通过CMakeLists.txt文件来描述项目的构建过程,其中包含项目名称、源文件列表、目标类型、依赖项等信息。CMake可以生成Makefile或Visual Studio项目文件等,使开发人员可以在不同的平台和编译器上使用相同的配置文件进行构建。
官网:https://cmake.org/
Windows版本下载链接:https://github.com/Kitware/CMake/releases/download/v3.26.3/cmake-3.26.3-windows-x86_64.msi
Linux安装cmake:
# 安装
sudo apt-get install cmake
# 验证版本
cmake --version
常用命令:
可以指定的构建类型有:Debug、Release、MinSizeRel、RelWithDebInfo
。使用示例:
cmake -DCMAKE_BUILD_TYPE=Debug
注释用#
,大小写不分,用message
来输出信息,用set()
来定义变量,用math()
来进行数学计算。
指定项目名称:project(Main)
指定需要的CMake的最低版本:cmake_minimum_required(VERSION 2.8)
用于设定变量 variable 的值为 value。如果指定了 CACHE 变量将被放入 Cache(缓存)中:set(ProjectName Main)
用于移除变量 variable。如果指定了 CACHE 变量将被从 Cache 中移除:unset(VAR CACHE)
载入预定义的 cmake 模块:INCLUDE(module [OPTIONAL])
用于设定目录, 这些设定的目录将被编译器用来查找 include 文件:include_directories(${PROJECT_SOURCE_DIR}/lib)
用于将 dir 目录下的所有源文件的名字保存在变量 variable 中:aux_source_directory(. DIR_SRCS)
自定义搜索规则: file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp") add_library(demo ${SRC_LIST})
用于指定从一组源文件 source1 source2 … sourceN 编译出一个可执行文件且命名为 name:add_executable(Main ${DIR_SRCS})
用于指定从一组源文件 source1 source2 … sourceN 编译出一个库文件且命名为name:add_library(Lib ${DIR_SRCS})
用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须add_executable、 add_library、 add_custom_target 命令创建的目标:add_dependencies(target-name depend-target1 depend-target2 …)
用于添加一个需要进行构建的子目录:add_subdirectory(Lib)
用于指定 target 需要链接 item1 item2 …。这里 target 必须已经被创建, 链接的item 可以是已经存在的 target(依赖关系会自动添加):target_link_libraries(Main Lib)
常用变量:
PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置
CMakeLists.txt示例:
示例一:
project(HELLO)
set(SRC_LIST main.c hello.c)
add_executable(hello ${SRC_LIST})
示例二:
project(HELLO)
set(LIB_SRC hello.c)
set(APP_SRC main.c)
add_library(libhello ${LIB_SRC})
add_executable(hello ${APP_SRC})
target_link_libraries(hello libhello)
Bazel 是一个构建和测试软件项目的开源构建工具,由 Google 开发并开源。它旨在提供高效、可扩展和可靠的构建系统,适用于大型项目和分布式代码库。
环境配置:
# 添加apt源
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
# 安装bazel
sudo apt update && sudo apt install bazel
一个简单的c++编译构建示例:
main.cc
#include <iostream>
int main() {
std::cout << "Hello, Bazel C++!" << std::endl;
return 0;
}
BUILD
cc_binary(
name = "hello",
srcs = ["main.cc"],
)
构建与运行:
bazel build //:hello
bazel run //:hello
更多应用实例可以参考这位博主:http://t.csdnimg.cn/Qj3ZT