makefile与CMake

CMake是一种跨平台的编译管理工具,常用于管理C/C++项目。在Linux上,它生成makefile来配合gcc/g++进行编译。CMakeLists.txt文件包含了项目配置指令,如设置编译选项、源文件路径和链接库。通过configure生成CMakeLists.txt,然后执行CMake和make命令来构建项目。

        我们在Windows机器上编译和调试C/C++程序时可以使用Visual Studio,在Linux机器上编译 C/C++程序时最终使用的是 gcc/g++,当然,在调试时使用gdb。我们一般使用makefile文件组织大型C/C++或者含有多个C/C++文件的项目,有人认为makefile不太方便,于是发明了CMake。CMake将含有CMake指令的文件生成makefile文件,含有CMake指令的文件的名称一般是CMakeLists.txt,使用CMake是在实际开发中组织和管理C/C++项目的常用方式,也适用于大多数C/C++开源项目。

        对 Linux 下的一些 C/C++开源项目,执行 configure 命令后一般会生成CMakeLists.txt文件,接着执行CMake命令会生成makefile文件,然后执行make命令利用gcc/g++对项目进行编译。

CMakeLists.txt的样例如下。

样例一:

cmake_minimum_required(VERSION 2.6)

project (FLAMGINGO_SERVER)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g -Wall -o0 
-Wno-unused-variable -pthread")

link_directories(
    ${PROJECT_SOURCE_DIR}/lib
    /usr/lib64/mysql/
)

set(net_srcs
base/AsyncLog.cpp
base/ConfigFileReader.cpp
base/Platform.cpp

net/Acceptor.cpp
net/ByteBuffer.cpp
net/Channel.cpp
)

set(mysglapi_srcs
mysqlapi/DatabaseMysql.cpp
mysqlapi/Field.cpp
mysglapi/QueryResult.cpp
)

set(chatserver_srcs
chatserversrc/main.cpp
chatserversrc/ChatServer.cpp
chatserversrc/ChatSession.cpp
)

set(fileserver_srcs
fileserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserversrc/FileSession.cpp
)

set(imgserver_sres
imgserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserversrc/FileSession.cpp
)

add_executable(chatserver ${net_srcs} ${chatserver_srcs} ${mysqlapi_srcs})
#只包含库目录是没用的,还必须使用TARGET LINK LIBRARIES 链接该库
TARGET_LINK_LIBRARIES(chatserver mysqlclient)

add_executable(fileserver ${net_srcs} ${fileserver srcs})
TARGET_LINK_LIBRARIES(fileserver)

add_executable(imgserver ${net_srcs} ${imgserver srcs})
TARGET_LINK_LIBRARIES (imgserver)

样例二:

PROJECT(TRADE)

AUX_SOURCE_DIRECTORY(./ SRC_LIST)
SET(EXECUTABLE_OUTPUT_PATH ../bin)

ADD_DEFINITIONS(-g -00 -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 
-DAC_HAS_WARNING -DAC_HAS-ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 
-DHAVE_CXX_STDHEADERS -Wno-deprecated ${CMAKE_CXX_FLAGS})


INCLUDE_DIRECTORIES(
./
/usr/local/include/commonlib/json2
/usr/local/include/commonlib/mysql
)

LINK_DIRECTORIES(
./
/usr/local/lib/commonlib
)

ADD_EXECUTABLE(trade ${SRC_LIST})

TARGET_LINK_LIBRARIES(trade pthread netutil json2 mysqlclient dbapi )

注:

(1)首行的 cmake_minimum_required 指令指定支持该 CMakeLists.txt 文件的CMake最低版本号。

(2)project 指令指定该项目的名称,注意,项目名称不是最终生成的二进制程序名,在一个项目下面可以生成多个二进制程序名。

(3)set定义和设置各种变量,set括号后的第1个名称是定义的变量名称,其后是变量的值,例如上述文件定义了CMAKE_CXX_FLAGS、net_srcs、mysqlapi_src、chatserver_srcs、fileserver_srcs、imgserver_srcs共6个变量,之后可以使用${变量名}引用这些变量。这些变量可以是内置的变量,例如CMAKE_CXX_FLAGS指定g++编译选项,EXECUTABLE_OUTPUT_PATH 指定输出的二进制文件路径,也可以是自定义变量如 chatserver_srcs、fileserver_srcs等。

(4)CMake使用aux_source_directory指令指定源码目录,使用include_directories指令指定include目录,使用link_directories指定lib目录。

(5)CMake使用指令指定生成的动态库或静态库的名称.

add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] sourcel source2 ... sourceN)
add_library(hello hello1.cpp hello2.cpp)

类型有如下三种。

◎ SHARED:动态库(扩展名为.so)。

◎ STATIC:静态库(扩展名为.a)。

◎ MODULE:在使用dyld的系统中有效,若不支持dyld,则被当作SHARED对待。

EXCLUDE_FROM_ALL参数的意思是这个库不会被默认构建,除非有其他组件依赖或者手工构建。

(6)TARGET_LINK_LIBRARIES指定生成的二进制文件依赖的其他库。

编写完CMakeLists.txt文件后,进入CMakeLists.txt文件所在的目录,依次执行如下命令即可生成最终的二进制文件:

#利用cmake生成makefile
cmake.
#执行make命令,利用gcc/g++编译生成最终的二进制文件
make

### Makefile CMake 的使用区别和适用场景 #### 1. 基本概念 - **Makefile**: 是一种传统的构建脚本文件,主要用于描述如何编译和链接源代码。它依赖于 GNU `make` 工具来执行命令并管理项目构建过程[^3]。 - **CMake**: 不是一个直接的构建工具,而是一种跨平台的元构建系统。它的主要作用是生成适合特定环境的本地构建文件(如 Makefile 或 Visual Studio 解决方案),从而简化复杂项目的配置和构建流程[^4]。 --- #### 2. 使用方式的区别 - **Makefile**: - 用户需要手动编写规则,定义目标、依赖项以及具体的编译指令。 - 对于简单的项目来说,这种方式直观且高效;但对于复杂的多模块或多平台项目,则显得繁琐且难以维护。 - **CMake**: - 提供了一种更高层次的语言(即 CMakeLists.txt 文件中的语法)用于声明项目的结构及其依赖关系。 - 它会自动生成底层的构建文件(例如 Makefile 或 Ninja 构建文件)。这使得开发者可以专注于高层次逻辑而不必关心不同操作系统之间的差异[^1]。 --- #### 3. 功能对比 | 特性 | Makefile | CMake | |---------------------|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------| | 平台兼容性 | 只能针对当前系统的特性工作,在其他平台上可能无法正常运行 | 支持多种操作系统,并能够自动检测环境变量及库位置 | | 自动化程度 | 较低,需手工指定每一步操作 | 更高,内置许多宏函数可减少重复劳动 | | 复杂项目的支持 | 当面对大型工程时容易变得混乱 | 能很好地处理分层目录结构的大规模软件开发 | | 插件扩展能力 | 几乎没有 | 提供丰富的插件机制允许第三方贡献者为其增加新功能 | --- #### 4. 优点分析 - **Makefile的优点** - 简洁明了,对于小型或者单一架构的应用程序非常合适; - 学习曲线较平缓,初学者易于上手。 - **CMake的优势** - 强大的跨平台支持,无论是在 Windows, macOS 还是 Linux 上都能轻松切换; - 内置了许多高级特性比如查找外部库、设置测试框架等,极大地方便了现代软件工程项目的需求^。 --- #### 5. 缺点剖析 - **Makefile的局限性** - 如果涉及到多个子目录或不同的编译选项组合时,维护起来相当麻烦; - 很难做到完全移植性的解决方案因为某些特殊标志只存在于特定版本的编译器里。 - **CMake潜在不足之处** - 初期配置相对耗时费力,特别是当团队成员不熟悉该工具的时候可能会遇到一些困难; - 生产出来的中间产物(如Makefiles)有时不够优化可能导致性能损失[^2]。 --- ```python # 示例:简单Python脚本来展示两种方法创建相同效果的过程 (仅作示意) # Using Makefile directly print(""" all: \tg++ main.cpp -o program """) # Equivalent using CMakeLists.txt file instead with open('CMakeLists.txt', 'w') as f: content = """ cmake_minimum_required(VERSION 3.0) project(MyProject) add_executable(program main.cpp) """ f.write(content) ``` --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值