CMakeLists基本教程

本文介绍了CMake的基本用法,包括PROJECT指令定义工程、ADD_EXECUTABLE创建可执行文件、SET和MESSAGE指令的使用、ADD_SUBDIRECTORY管理子目录以及如何构建静态库和动态库,以及如何通过TARGET_LINK_LIBRARIES和LINK_DIRECTORIES解决链接问题。
摘要由CSDN通过智能技术生成

主要内容整理自《Cmake实践》一书

 最简单的CMakeLists.txt:

PROJECT (HELLO) 
ADD_EXECUTABLE(hello main.cpp)
PROJECT 指令

        定义工程名称HELLO,并可指定工程支持的语言(支持语言可忽略,默认支持所有语言)

        指令隐式的定义了两个 cmake 变量:

        <projectname>_BINARY_DIR  和 <projectname>_SOURCE_DIR,如上面的HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR。但是,cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIRPROJECT_SOURCE_DIR 变量,建议直接使用,不用根据工程名称修改。例如:

ADD_EXECUTABLE指令

        生成一个文件名为 hello 的可执行文件

复杂一点: 

PROJECT (HELLO) 
SET(SRC_LIST main.c) 
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR}) 
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR}) 
ADD_EXECUTABLE(hello ${SRC_LIST})

        SET、MESSAGE、ADD_EXECUTABLE等属于“指令”,指令不区分大小写

        指令后的括号里可以有参数变量,参数和变量区分大小写

SET(set)指令

        SET 指令可以用来显式的定义变量

SET(SRC_LIST main.c t1.c t2.c)
MESSAGE 指令

        用于向终端输出用户定义的信息,包含了三种类型:

        SEND_ERROR、SATUS、FATAL_ERROR,常用SATUS

MESSAGE(STATUS "This is SOURCE dir is" ${HELLO_SOURCE_DIR})
变量

        变量使用 ${ } 方式取值,但是在 IF 控制语句中是直接使用变量名

将源代码添加到子目录src

TEST下的CMakeLists.txt:

project(HELLO)
add_subdirectory(src bin)

src内的CMakeLists.txt:

add_executable(hello main.cpp)
ADD_SUBDIRECTORY 指令

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

可以指定编译输出(包含编译中间结果)的路径,如:上面的add_subdirectory(src bin),则编译后有:

还可以通过SET 指令重新定义最终的目标二进制的位置(指最终生成的 hello 或者最终的共享库,不包含编译生成的中间文件)

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

该语句和 ADD_EXECUTABLE 或 ADD_LIBRARY放在同一CMakeLists下。

静态库与动态库构建

TEST下的CMakeLists.txt:

PROJECT(HELLOLIB) 
ADD_SUBDIRECTORY(lib)

lib下CMakeLists.txt:

SET(LIBHELLO_SRC hello.cpp) 

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

lib下hello.cpp:

#include "hello.h" 

void HelloFunc() 
{ 
    std::cout << "helloworld!" << std::endl;
}

lib下hello.h:

#ifndef HELLO_H 
#define HELLO_H 

#include <iostream> 
void HelloFunc(); 

#endif
ADD_LIBRARY指令
ADD_LIBRARY (libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 
             source2 ... sourceN) 

SHARED:动态库    STATIC:静态库

动态库文件拓展名是.so,静态库文件拓展名是.a

如构建静态库:

ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

如果想要名字相同的静态库和动态库,则需要SET_TARGET_PROPERTIES指令:

SET(LIBHELLO_SRC hello.cpp) 
# 生成动态库
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
# 生成静态库
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
# 将生成的静态库hello_static.a重命名为hello.a
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

结果:

用外部共享库和头文件

        即使有了include_directories(../lib),不会报:“error: hello.h: 没有那个文件或目录”,但是还会报错:main.cpp:(.text+0x9): undefined reference to `HelloFunc()'

        这是因为并没有 link 到共享库 libhello 上。

LINK_DIRECTORIES指令 
TARGET_LINK_LIBRARIES指令

为了解决上述问题,需要将目标文件链接到 libhello 。

LINK_DIRECTORIES(directory1 directory2 ...),可以添加非标准的共享库搜索路径

TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ...),用来为 target 添加需要链接的共享库,即将共享库链接到target上

为了解决前面遇到的 HelloFunc 未定义错误,需要做的是向 src/CMakeLists.txt 中添加如下指令: TARGET_LINK_LIBRARIES(main hello) 或者 TARGET_LINK_LIBRARIES(main libhello.so)

相同,链接到静态库上:TARGET_LINK_LIBRARIES(main libhello.a)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值