跳至主要內容

MakeFile

LincZero大约 4 分钟

MakeFile

目录

比较 make、cmake、qmake、nmake

makefile

  • 其他语言关联编译的方法(与C/C++不同)
    • 如果熟悉UNIX的 “make”工具(或者是Windows中的“nmake”等工具),可以认为Java编译器内置了“make”功能
    • C++一般是使用makefile,即qmake (QT) 或 cmake (通用) 来辅助编译
  • 详细过程
    • 没有显式地编译Employee.java。然而,当Java编译器发现EmployeeTest.java使用了Employee类时会查找名为Employee.class的文件
    • 如果没有找到这个文件,就会自动地搜索Employee.java,然后,对它进行编译

qmake vs cmake

  • cmake获取:http://www.cmake.org
  • 选用比较
    • qmake 是为 Qt 量身打造的,使用起来非常方便
    • cmake 使用上不如qmake简单直接,但复杂换来的是强大的功能
  • 如何选择?
  • 项目区别
    • 需要创建一个CMakeLists.txt文件,该文件很像是一个qmake.pro文件

CMake

介绍与准备

资料

IDE的构建系统

平时使用的IDE大多都内置了构建系统,只是我们可能没有留意罢了。 他们都各有擅长的领域

  • .| GUN Make
  • .| Apache Ant
  • (万用)| Bazel| 能完成不同语言在不同环境的构建
  • (万用)| Buck| 能完成不同语言在不同环境的构建
  • C/C++较常用| CMake
  • Android| Gradle
  • .| Maven
  • VS| MSBuild
  • Qt| QMake

安装CMake

  • 官网
  • 操作系统自带的包管理工具(例如Linux的yum,winget的choco)
  • 其他包管理工具,笔者使用的是 cygwin

安装后cmd看一下

cmake --version

安装编译工具

CMake 自身不带编译工具,要另外下clang、gcc、g++这些

然后需要指定工具链

使用

VSCode 为例

配置

原理:编写CMakeList.txt,该文件可以用来自动生成各目标平台下的工程文件。该过程在CMake中叫 配置(Configure)

例如:

  • VS| *.sln
  • Makefile
  • *.xcodeproj
  • ...

配置方法:

项目根目录下创建 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)	# 指定所需最低的CMake版本

project(Example)						# 工程名,输入的可执行文件同该名称

add_executable(Example main.cpp)		# 构建一个可执行文件,并指定源文件(这里只编译单个文件)

VSCode打开项目时会自动提示你进行项目 “配置”

VSCode命令:Select a Kit for cmake,选择一个平台原生的C++构建工具然后等配置即可

构建

F7,或VSCode命令:cmake build

使用 - 较复杂的例子

cmake_minimum_required(VERSION 2.7)		# 指定所需最低的CMake版本

project(Blackhole)						# 工程名,输入的可执行文件同该名称

# 寻找第三方库
find_package(imgui REQUIRED)
find_package(glfw3 REQUIRED)
find_package(GLEW REQUIRED)
find_package(glm REQUIRED)

# 匹配所有的源文件,存放于变量 SRC_FILES 中
file(GLOB SRC_FILES
	"${PROJECT_SOURCE_DIR}/src/*.h",
    "${PROJECT_SOURCE_DIR}/src/*.cpp",
    "${PROJECT_SOURCE_DIR}/src/*.c",
    "${PROJECT_SOURCE_DIR}/src/*.cc")

# 构建可执行文件,用之前匹配到的源文件来构建
add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES})

# 第三方库
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE imgui::imgui)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE glfw)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE GLEW::GLEW)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE glm)

# 支持C++17
target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE cxx_std_17)

add_custom_command(
	TARGET ${CMAKE_PROJECT_NAME}
	POST_BUILD							# 构建以后要做的事,这里将 <项目根目录>/assets 拷贝到 <项目根目录>/build/Debug/assets
	COMMAND ${CMAKE_COMMAND} -E copy_directory
			"${PROJECT_SOUREC_DIR}/assets"
			"$<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>/assets")

第三方库的安装

常见的安装方式

  1. 手动下载库的源文件。 然后手动构建并指定CMake库的路径,cd glfw+cmake -S . -B build

  2. 对于Linux和Mac,可以使用包管理工具安装 例如 sudo apt-get install libpng-dev

    另外推荐:微软的开源工具:vcpkg(用于在Windows、Linux、MacOS上管理C和C++库)

一些其他常用的指令

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} DIR_SRCS)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/core/src DIR_CORE)

用于在指定的目录中查找所有的源文件,并将文件名列表存储在变量中

list(APPEND DIR_SRCS ${DIR_CORE})
list(APPEND DIR_SRCS ${DIR_UTILS})
list(APPEND DIR_SRCS ${DIR_ZIP})
list(APPEND DIR_SRCS ${DIR_IXWS})
list(APPEND DIR_SRCS ${DIR_ICMP})
list(APPEND DIR_SRCS ${DIR_UDP})
list(APPEND DIR_SRCS ${DIR_TRACEROUTE})
add_executable(${PROJECT_NAME} ${DIR_SRCS})

这是一个CMake命令,用于向一个列表变量中追加元素

CMAKE_SOURCE_DIR # 源代码树的顶层目录,即包含顶层CMakeLists.txt文件的目录。
CMAKE_CURRENT_SOURCE_DIR # 当前处理的CMakeLists.txt文件所在的目录。(用得最多的)
CMAKE_BINARY_DIR # 构建树的顶层目录,即运行cmake命令的目录。
CMAKE_CURRENT_BINARY_DIR # 当前处理的CMakeLists.txt文件对应的构建目录。
PROJECT_SOURCE_DIR # 当前项目的源代码树的顶层目录,即包含project命令的CMakeLists.txt文件所在的目录。
projectName_SOURCE_DIR # 指定项目名(projectName)的源代码树的顶层目录。

一些路径的宏,这里还有更多:https://johnnado.com/cmake-directory-variables/