CMakeLists.txt生成makefile

2023-05-16

# 本CMakeLists.txt的project名称
# 会自动创建两个变量,PROJECT_SOURCE_DIR和PROJECT_NAME
# ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的文件夹路径
# ${PROJECT_NAME}:本CMakeLists.txt的project名称
project(xxx)

# 获取路径下所有的.cpp/.c/.cc文件,并赋值给变量中
aux_source_directory(路径 变量)

# 给文件名/路径名或其他字符串起别名,用${变量}获取变量内容
set(变量 文件名/路径/...)

# 添加编译选项
add_definitions(编译选项)

# 打印消息
message(消息)

# 编译子文件夹的CMakeLists.txt
add_subdirectory(子文件夹名称)

# 将.cpp/.c/.cc文件生成.a静态库
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
add_library(库文件名称 STATIC 文件)

# 将.cpp/.c/.cc文件生成可执行文件
add_executable(可执行文件名称 文件)

# 规定.h头文件路径
include_directories(路径)

# 规定.so/.a库文件路径
link_directories(路径)

# 对add_library或add_executable生成的文件进行链接操作
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
target_link_libraries(库文件名称/可执行文件名称 链接的库文件名称)
 


 

1 单个源文件编译

main.c 

#include <stdio.h>
int main()
{
    printf("Hello World Test!\n");
    return 0;
}


CMakeLists.txt:

project(hello)
set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)
message(${PROJECT_SOURCE_DIR})


解释代码:

第一行project非强制性,会引入两个变量:

HELLO_BINARY_DIR, HELLO_SOURCE_DIR

同时也会定义两个等价的变量:

PROJECT_BINARY_DIR, PROJECT_SOURCE_DIR

外部编译要时刻区分这两个变量对应的目录

可以通过message进行输出

message(${PROJECT_SOURCE_DIR})

set 命令用来设置变量

add_exectuable 告诉工程生成一个可执行文件。

add_library 则告诉生成一个库文件。

CMakeList.txt 文件中,命令名字是不区分大小写的,而参数和变量是大小写相关的。


  

aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件

add_library(demo ${SRC_LIST})


file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
file(GLOB_RECURSE SRC_LIST "*.cpp") #递归搜索
FILE(GLOB SRC_PROTOCOL RELATIVE "protocol" "*.cpp") # 相对protocol目录下搜索
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})


设置包含目录  

include_directories(

${CMAKE_CURRENT_SOURCE_DIR}

${CMAKE_CURRENT_BINARY_DIR}

${CMAKE_CURRENT_SOURCE_DIR}/include

)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")

#设置链接库搜索目录

link_directories(

${CMAKE_CURRENT_SOURCE_DIR}/libs

)

或set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")

#设置target需要链接的库

target_link_libraries(demo libface.a) # 链接libface.a

target_link_libraries(demo libface.so) # 链接libface.so

#链接多个库

target_link_libraries(demo

${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a

boost_system.a

boost_thread

pthread)

1. 预定义变量
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:重新定义目标链接库文件的存放位置

 

2. 系统信息
­CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
­CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
­CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
­CMAKE_SYSTEM:系统名称,比如 Linux-­2.6.22
­CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
­CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
­CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686
­UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
­WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin

3. 主要开关选项
BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加

add_definitions(-DENABLE_DEBUG -DABC) # 参数之间用空格分隔
 

将main.c和CMakeList.txt放在同一目录,

mkdir build

cd build

cmake ../

//此时会生成makefile文件
make

//此时生成相应的可执行程序。

2多个源文件编译


hello.h

#ifndef BUJIHELLO
#define BUJIHELLO
void hello(const char* name);
#endif


hello.c

#include <stdio.h>
#include "hello.h"
 
void hello(const char* name)
{
    printf("Hello my name is %s\n",name);
}


main.c

#include <stdio.h>
#include "hello.h"
 
int main()
{
    printf("Hello World Test!\n");
    hello("buji");
    return 0;
}


CMakeLists.txt

project(hello_buji)
set(APP_SRC main.c hello.c)
add_executable(${PROJECT_NAME} ${SRC_LIST})
 
#print message
message(${PROJECT_SOURCE_DIR})

执行cmake和make,就可以生成需要的可执行文件

3、hello.c生成库


如果将hello生成成一个库来调用,只需要在第2节基础上修改CMakeLists.txt

project(hello)
set(LIB_SRC hello.c)
set(APP_SRC main.c)

# 搜索当前目录下的所有.cpp文件

aux_source_directory(. SRC_LIST)

#默认生成静态库
add_library(hello ${LIB_SRC})

#指定包含哪些源文件

#add_library(hello hello.cpp test.cpp)

# 生成可执行文件
add_executable(${PROJECT_NAME} ${APP_SRC})   

# 生成静态库

#add_library(hello STATIC hello.cpp)

# 生成动态库或共享库

#add_library(hello SHARED hello.cpp)

target_link_libraries(${PROJECT_NAME} hello)
 
#print message
message(${PROJECT_NAME})
相比之下,我们只是添加了一个新的目标hello库,并将其链接到我们的demo程序

执行cmake和make

4、工程分类文件夹编译


大型项目有多个目录,此处我们创建3个目录 app,build,libso和 CMakeLists.txt文件。main.c程序放在app目录,hello.c hello.h放在libso目录,app和libso目录各自都有CMakeLists.txt文件。

app/CMakeLists.txt

project(hello_buji)
include_directories(${PROJECT_SOURCE_DIR}/../libso)
 
set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} helloso)
 
message(${PROJECT_SOURCE_DIR})


libso/CMakeLists.txt

其中SHARED 表示是生成的动态库,如果把SHARED去掉的话就是生成静态库

project(helloso)
 
set(LIB_SRC hello.c)
add_library(${PROJECT_NAME} SHARED ${LIB_SRC})

/CMakeLists.txt

#指定cmake最低版本

cmake_minimum_required (VERSION 3.2)
project(buji_cmake)
 
add_subdirectory(./app)
add_subdirectory(./libso)
其表示我们要到./app和./libso文件夹下面去寻找Cmake文件然后进行编译

cd build

cmake ../
make


5 Cmake的install简单使用


cmake中的install将编译好的可执行文件或库文件安装到系统对应的位置,/usr/bin,/usr/lib


app/CMakeLists.txt:在之前的基础上加了最后install一行

project(hello_buji)
include_directories(${PROJECT_SOURCE_DIR}/../libso)
 
set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} helloso)
 
message(${PROJECT_SOURCE_DIR})
 
install(TARGETS ${PROJECT_NAME} DESTINATION bin)


libso/CMakeLists.txt:在之前的基础上加了最后install一行

project(helloso)
 
set(LIB_SRC hello.c)
add_library(${PROJECT_NAME} SHARED ${LIB_SRC})
 
install(TARGETS ${PROJECT_NAME} DESTINATION ../lib)


install(TARGETS ${PROJECT_NAME} DESTINATION bin)意思是安装TARGERS hello_buji这个可执行文件到${CMAKE_INSTALL_PREFIX}/bin目录下面,

可执行文件安装的路径是:

/usr/local/bin/

so库文件的安装路径是:

/usr/local/../lib/

#cmake ../
#make
#make install

此时可以在Linux任何目录执行./hello_buji

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMakeLists.txt生成makefile 的相关文章

  • 构建 gcc 4.6 时遇到问题:对“yylex”的未定义引用

    我正在尝试构建 gcc 4 6 但我收到一些链接器错误 看起来这意味着 bison 或 flex 没有链接到 当 makefile 发出此命令时 gcc g fkeep inline functions DIN GCC W Wall Wwr
  • 在 OS X 下将 ImageMagick 编译为 64 位?

    我正在尝试安装moddims http code google com p moddims 在 OS X 上 请参阅上一个问题 https stackoverflow com questions 1185106 how do i confi
  • rm -rf 与 -rm -rf

    在 Makefile 中 我读到 rm rf 而不是 rm rf Makefile 行开头的第一个 是什么意思 代表着make本身将忽略来自的任何错误代码rm In a makefile 如果任何命令失败 则make进程本身会停止处理 通过
  • 使用 GCC 和 autotools 为各个源文件设置编译标志的最佳方法是什么?

    我需要使用自动工具禁用单个文件的优化标志 最好的方法是什么 您是指单个源文件还是单个可执行文件 禁用可执行文件的优化很简单 bin PROGRAMS myprog myprog SOURCES foo c bar c myprog CFLA
  • Makefile 依赖项,什么是依赖项?

    我有一个关于 makefile 依赖关系的概念性问题 这是因为我在网上看到了关于此的不一致之处 假设我有以下文件 main cpp uses gt my math cpp and my strings cpp my math cpp use
  • mingw32-make 尝试创建子文件夹 .lib 为非法名称

    我正在尝试编译一个需要 freetype 库的项目 所以我正在弄清楚如何将 freetype 安装到 mingw32 更安全的方法是编译它 无论如何 问题是编译 freetype 2 4 11 我进入了msys中提供的bash 我做到了 c
  • 有没有比“手表制造”更明智的替代方案?

    我遇到了这个有用的提示 如果您经常处理文件并且希望它们自动构建 则可以运行 手表品牌 每隔几秒钟它就会重新运行一次 一切都会构建完成 然而 它似乎一直在吞噬所有的输出 我认为它可能更聪明 也许显示输出流 但抑制 全部 不做任何事情 这样如果
  • 在 Linux 上的 makefile 和 Makefile 之间进行选择

    我想在一个目录中同时使用 Makefile 和 makefile 进行 make 默认情况下 它将执行makefile 我可以选择执行 Makefile 吗 提前致谢 最简单的选择是使用 f make f Makefile From man
  • Makefile 头依赖项

    我是使用 make 的新手 并且一直在通过以下方式学习基础知识本教程 http www cs colby edu maxwell courses tutorials maketutor 这是本教程中的最后一个 makefile 示例 IDI
  • make: *** 没有规则可以创建“all”所需的目标“gcc”。停止

    我正在通过一个eg pgm 来创建一个make 文件 http mrbook org tutorials make http mrbook org tutorials make 我的文件夹eg make creation包含以下文件 des
  • bash:PWD 和 CURDIR 有什么区别?

    我的问题 我使用 Makefile 来运行docker runtarget 需要当前工作目录作为其参数之一 我使用任一 PWD or CURDIR build Dockerfile docker run lt PWD or CURDIR g
  • 在 PATH 中找不到程序“make”

    我在 Eclipse 中遇到 程序 make 未在 PATH 中找到 错误 我检查了路径变量 C cygwin bin JAVA HOME bin ANT HOME bin ANDROID SDK tools ANDROID SDK pla
  • 如何在 makefile 中针对特定目标使用 include 指令

    我只想将 include 指令用于特定目标 当不需要目标时 我不想运行其他 makefile 因为这意味着 makefile 是不必要生成的 那么有没有一种方法可以有条件地使用 include 指令 该指令以目标为条件 或者以某种方式使 i
  • 检查 makefile 中的文件大小,如果文件太短则停止

    有没有办法检查特定文件的大小是否小于某个常量 我在 makefile 中假设有关大小的事情 并希望确保如果不满足我的假设 我会收到错误 类似于断言 但在 makefile 中 if filesize file gt C then error
  • GNU Make 与 patsubst:需要两次替换

    我需要在变量替换的替换中引用词干两次 O23 OROOTS ODIR overx 2wk 3wk mlb 我需要使用相同的词干执行两次替换 但是替换使用patsubst这只做第一个 我们怎样才能同时实现这两点呢 事实上 杰克几乎猜对了 fo
  • 我怎样才能强制Make一直执行一个菜谱

    当前的 Makefile 有这样的内容 target1 lib1 a lib2 a target2 lib1 a lib3 a target3 lib3 a lib1 a MAKE C sub dir all 我想更改此 Makefile
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • Makefile:对子目录中的所有文件进行操作?

    我正在使用 Makefile 和 GNU make 基于源 Markdown 文件创建各种文档输出目标 这包括使用latex or pdflatex创建 DVI 文件 使用 EPS 或 PS 格式以外的图像会导致错误 我可以在源 Markd
  • 如何制作一个makefile只用于编译一些java文件?

    我有三个java文件 名为A java B java C java A将创建对象B B将创建对象C 但我以前从未构建过makefile 有谁可以帮我构建一个 makefile 来编译这三个 java 文件吗 我应该使用什么工具来制作 mak

随机推荐

  • 无名飞控的自抗扰控制

    无名飞控的自抗扰控制 自控制的算法可以见韩京清先生的书点击打开链接 为了自抗扰控制买了无名飞控 xff0c 现在看看它的自抗扰代码 首先初始化 xff1a 从代码上大致可以看出只对俯仰 横滚方向姿态内环角速度控制器采用ADRC自抗扰控制器
  • ARM寄存器与汇编指令详解

    介绍ARM寄存器之前 xff0c 先来介绍一下ARM处理的模式 xff1a 用户模式 User ARM处理器正常的程序执行状态 快速中断模式 FIQ 用于高速数据传输或通道处理 外部中断模式 IRQ 用于通用的中断处理 管理模式 Svc 操
  • STM32定时器---正交编码器模式详解

    编码器分类 xff1a 按工作原理 xff1a 光电式 磁电式和触点电刷式 按码盘的刻孔方式 xff1a 增量式和绝对式两类 由于博主接触面还不是很广 xff0c 一共就用过两个种类的编码器 xff0c 都是属于光电的 差分编码器 一般由8
  • VM虚拟机下给Ubuntu 目录分区增加容量的方法

    最近在编译androdi5 1代码的时候突然发现虚拟机容量不够了 xff0c 很是蛋疼 xff0c 只好摸索如何想办法给相应目录增加容量 xff0c 以下方法亲测可行 xff01 1 第一步当然是增加硬盘容量了 xff0c 这个需要用到VM
  • 1.uCOS-II简介及移植uCOS-II到STM32F103平台详细步骤

    I 说明 作者 xff1a WXP 翱翔云端的鸟 联系方式 328452854 64 qq com 13100610853 联系请注明 CSDN 申明 个人原创 xff0c 转载请先经过本人同意 xff01 要说的话 个人水平有限 写之前也
  • 1.nRF52832裸机教程--开发环境搭建

    I 说明 作者 xff1a WXP 翱翔云端的鸟 联系方式 328452854 64 qq com 13100610853 联系请注明CSDN 申明 个人原创 xff0c 转载请先经过本人同意 xff01 要说的话 个人水平有限 写之前也看
  • 3.nrf52832裸机教程--系统时钟

    I 说明 作者 xff1a WXP 翱翔云端的鸟 联系方式 328452854 64 qq com 13100610853 联系请注明CSDN 申明 个人原创 xff0c 转载请先经过本人同意 xff01 要说的话 个人水平有限 写之前也看
  • Docker中使用ROS-GUI

    Docker中使用ROS GUI比较麻烦 xff0c 好在有国外的大神解决了这个难题 下面 xff0c 我就教大家如何在Docker中使用ROS GUI 1拉取大神编写的镜像 docker pull ct2034 vnc ros kinet
  • Linux环境下搭建git服务器和TortoiseGit客户端 ssh key测试

    Linux环境下搭建git服务器和TortoiseGit客户端 ssh key测试 1 git的安装2 用户和 ssh目录创建3 本地创建公钥私钥4 在服务器端导入本地公钥5 开启服务器中的RSA认证6 创建仓库7 本地克隆 1 git的安
  • RealSense技术在SR300摄像头上的应用

    RealSense技术在SR300摄像头上的应用 一 实感摄像头 1 RealSense技术 在计算机的发展过程中我们始终没有抛弃键盘和鼠标 xff0c 前几年win8和触屏的配合形成 了一种新的电脑使用模式 xff0c 但是依然没有打破传
  • 自动控制理论(2)——控制系统的数学模型(微分方程、传递函数)

    系列文章目录 自动控制理论 xff08 1 xff09 自动控制理论概述 自动控制理论 xff08 3 xff09 控制系统的数学模型 xff08 系统框图和信号流图 xff09 文章目录 系列文章目录一 线性系统的微分方程1 微分方程的建
  • Android 8.1共享系统代理中的热点(LineageOS15.1)

    https github com Mygod VPNHotspot 下载安装这个软件 xff0c 需要ROOT 开发者选项 xff1a 关闭WLAN硬件加速 该软件设置 xff1a 关闭IPV6 打开 修复DHCP 开启手机自带的热点 该软
  • 浏览器页面滚动条美化(样式)

    浏览器页面滚动条美化 xff08 样式 xff09 最近测试反应我们的产品在浏览器中当页面宽高出现溢出的情况下页面滚动条太丑了 xff01 让我们美化一下 xff01 然后花了一点时间专研了一下关于滚动条样式的相关知识 xff0c 今天就在
  • Android串口工具

    参考Android系统实现方式 xff0c 串口操作采用native实现 xff0c 比java层用文件流的方式更高效 xff0c 不需要延时和睡眠处理 xff0c 大量自测不会出现读取不到数据等问题 特点 xff1a 1 提供基本的串口操
  • 【VINS-Fusion入门之一】让系统跑起来

    文章目录 简介配置执行单目 43 IMU双目 43 IMU双目相机双目 43 GPS 落地备注 xff1a 简介 VINS xff0c 英文缩写Visual Inertial Systems 是一个实时视觉SLAM框架 xff0c 2017
  • 【VINS-Fusion入门之二】基于优化的多传感器融合

    文章目录 简介特征参考论文 解读系统框图相机模型 xff1a 配置文件全局优化闭环优化状态估计 简介 VINS Fusion is an optimization based multi sensor state estimator whi
  • RealSense T265使用教程

    RealSense ROS 安装 https github com IntelRealSense realsense ros 安装教程 https www intelrealsense com get started tracking ca
  • c++面试宝典

    目录 一 多线程 二 指针 三 字符串 四 面向对象 五 基本用法 六 c 43 43 11 七 算法 c 43 43 面试必考多线程 xff0c 内存 xff08 智能指针 xff09 xff0c 常见算法 xff0c 设计模式 一 多线
  • 音视频编解码之傅里叶变换和小波变换

    傅里叶变换的核心是从时域到频域的变换 xff0c 而这种变换是通过一组特殊的正交基来实现的 傅立叶变换使我们能通过频率成分来分析一个函数 任何信号 xff08 如图像信号 xff09 都可以表示成一系列正弦信号的叠加 傅立叶变换在实际中有非
  • CMakeLists.txt生成makefile

    本CMakeLists txt的project名称 会自动创建两个变量 xff0c PROJECT SOURCE DIR和PROJECT NAME PROJECT SOURCE DIR xff1a 本CMakeLists txt所在的文件夹