当前位置: 首页 > article >正文

cmake编译

cmake_minimum_required (VERSION 2.8)

project (demo)

##第一个是生成后的名称, 后面包含所有源文件
add_executable(main main.c testFunc.c)

##cmake提供了一个命令可以把指定目录下所有的源文件存储在一个变量中
aux_source_directory(. SRC_LIST)  ##将当前位置的所有源文件存储在SRC_LIST
add_executable(main ${SRC_LIST}) ##在add_executable里调用SRC_LIST
    
#aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件
set( SRC_LIST
	 .#main.c
	 .#testFunc1.c
	 .#testFunc.c)

## 在不同目录下有多个源文件  新的命令include_directories  添加多个指定头文件的搜索路径,路径之间用空格分隔
## 因为没有头文件不能通过编译  下面包含两个头文件的路径,test_func和test_func1
include_directories (test_func test_func1)

aux_source_directory (test_func SRC_LIST)
aux_source_directory (test_func1 SRC_LIST1)

add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})

项目级的组织结构

<img src=“https:##gitee.com#zheshu#typora#raw#master#images#202305051703855.png” alt=“image-20230505170359824” style=“zoom:50%;” #>

cmake_minimum_required (VERSION 2.8)

project (demo)

add_subdirectory (src)

## add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
##三个参数 后面两个可选
##这个命令是 增加编译子层

source_dir 源代码目录

指定一个包含CMakeLists.txt和代码文件所在的目录,该目录可以是绝对路径,也可以是相对路径,对于后者相对路径的起点是CMAKE_CURRENT_SOURCE_DIR。此外,如果子目录再次包含的CMakeLists.txt,则将继续处理里层的CMakeLists.txt,而不是继续处理当前源代码。

binary_dir 二进制代码目录

这个目录是可选的,如果指定,cmake命令执行后的输出文件将会存放在此处

上面两个参数保证了可以和其他目录里的cmake文件一同编译,并且可以将cmake的输出放到另外一个目录里面,而第三个参数可以让新增加的子目录从ALL目录里面删除,独立于源工程

多个cmakelists例子

cmake_minimum_required (VERSION 2.8)

project (demo)

add_subdirectory (src)  ##增加src编译目录

#######################################################################################
    
##在src目录里的CMakeLists.txt 有下面的内容
aux_source_directory (. SRC_LIST) ##将当前目录的源文件定义为SRC_LIST

include_directories (..#include) ##程序编译的时候需要头文件,而又在不同目录,因此需要将头文件包含进来

add_executable (main ${SRC_LIST})
    
##EXECUTABLE_OUTPUT_PATH 目标二进制可执行文件的存放位置
##PROJECT_SOURCE_DIR:工程的根目录
##这里set的意思是把存放elf文件的位置设置为工程根目录下的bin目录
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}#bin) 
    

然后进入根目录下的build里面,然后执行cmake… 然后再make,为什么在build目录下运行cmake?cmake和make会生成很多文件,和运行没有什么关系,这样cmake的时候所有的中间文件都将在这个目录下生成,删除的时候也很好删除,非常方便,如果不这样做,cmake运行时生成的附带文件就会跟源码文件混在一起,这样会对程序的目录结构造成污染。

也可以在一个头文件中写CMakeLists.txt,下面写一个例子

使用一个cmakelists例子

# 设置cmake的最低版本和项目名称
cmake_minimum_required(VERSION 3.0)
project(mprpc)

# 生成debug版本,可以进行gdb调试
set(CMAKE_BUILD_TYPE "Debug")

# 设置项目可执行文件输出的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}#bin)
# 设置项目库文件输出的路径	  下面有关于库文件的介绍
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}#lib)

# 设置项目编译头文件搜索路径 -I
include_directories(${PROJECT_SOURCE_DIR}#src#include)
include_directories(${PROJECT_SOURCE_DIR}#example)
# 设置项目库文件搜索路径 -L
link_directories(${PROJECT_SOURCE_DIR}#lib)

# src包含了mprpc框架所有的相关代码
add_subdirectory(src)
# example包含了mprpc框架使用的示例代码
add_subdirectory(example)

动态库和静态库的编译控制

库是一组预先编译好的方法,库文件分为静态库和动态库,静态库和动态库的区别体现在程序的链接阶段。

Windows的静态库文件扩展名是 .lib,动态库文件扩展名是 .dll

Linux的静态库扩展名是 .a,动态库扩展名是 .so

无论是静态库文件还是动态库文件都是都是将函数封装编译生成.o文件然后将所有 .o 文件合并生成库文件,供自己或他人调用。好处在于编译后的库文件的源代码被加密,使用者看不到,可保密。

Linux系统存储的库的位置一般在:/lib 和 /usr/lib,库的头文件一般会被存储在 /usr/include 下或其子目录下

静态库的生成和使用

静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。比如

ar -crv libhyhello.a hello.o

# 下面是将多个.o文件生成动态库
ar -crv libhyhello.a A1.o A2.o

静态库的使用

#第一种方法
gcc -o hello main.c -L. -lhyhello
#第二种方法
gcc main.c libhyhello.a -o hello
# 第三种方法
gcc -c main.c
gcc -o hello main.o libmyhello.a

动态库的生成和使用

lib开头,so结尾

gcc -shared -fPIC -o libhyhello.so hello.o

# 将所有的.o文件生成动态库
gcc -shared *.o -o libhysofile.so

动态库的使用

gcc -o hello main.c libhyhello.so 

env是列出所有的环境变量,

静态库与动态库的区别

静态库会将全部进行拷贝,而动态库文件在使用的时候,只有在程序执行的时候才会被连接动态库使用

cmakelists生成库文件

cmake_minimum_required (VERSION 3.5)

project (demo)

set (SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.c)

add_library (testFunc_shared SHARED ${SRC_LIST})
add_library (testFunc_static STATIC ${SRC_LIST})

set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

add_library 生成库文件,第一个参数是名字,第二个参数是SHARED或者STATIC,第三个参数是生成库的源文件。

这里使用了两次add_library一个是静态库,一个是动态库

set_target_properties是设置版本号什么的,可以看到第一个参数使用了上面的的名字,可以直接用上面的。

下面的set,LIBRARY_OUTPUT_PATH是默认库文件的输出路径,PROJECT_SOURCE_DIR是工程目录

cmakelists使用库文件

cmake_minimum_required (VERSION 3.5)

project (demo)


set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)

# find testFunc.h
include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)

find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)

add_executable (main ${SRC_LIST})

target_link_libraries (main ${TESTFUNC_LIB})

find_library 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径

target_link_libraries 把目标文件与库文件进行链接

条件编译

编译程序时想添加一些编译选项,如-Wall,-std=c++11等,就可以使用add_compile_options来进行操作。

cmake_minimum_required (VERSION 2.8)

project (demo)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

add_compile_options(-std=c++11 -Wall) 

add_executable(main main.cpp)

一些常用的编译命令

cmake_minimum_required (VERSION 2.8)  cmake的最小版本
project (demo) 项目的名称
add_executable(main main.c testFunc.c) 第一个参数是生成可执行文件的名字,由后面的参数生成

aux_source_directory(.  SRC_LIST) 将当前位置的所有源文件存储在SRC_LIST变量里面
aux_source_directory (test_func SRC_LIST)  将一个源文件放入变量里面
set( SRC_LIST  .#main.c .#testFunc1.c  .#testFunc.c)手动将一些东西赋值给变量
add_executable(main ${SRC_LIST}) 使用后面的变量编译

include_directories (test_func test_func1) 编译的时候需要头文件,如果头文件不在当前目录下,需要指定搜索的路径
add_subdirectory (src) 项目级别,继续编译这个目录里面的cmakelists.txt
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}#bin)  EXECUTABLE_OUTPUT_PATH 目标二进制可执行文件的存放位置,PROJECT_SOURCE_DIR:工程的根目录,这里set的意思是把可执行文件的位置设置为工程根目录下的bin目录
add_compile_options(-std=c++11 -Wall) 想添加一些编译选项

add_library (testFunc_shared SHARED ${SRC_LIST}) 第一个参数是名字,第二个参数是SHARED动态和STATIC静态库,第三个参数是生成库的源文件
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}#lib) 设置库文件的生成路径

find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib) find_library 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径
target_link_libraries (main ${TESTFUNC_LIB})   target_link_libraries  把目标文件与库文件进行链接

或者直接
link_directories(${PROJECT_SOURCE_DIR}#lib) 设置项目库文件搜索路径 -L

set(CMAKE_BUILD_TYPE "Debug") 生成debug版本,可以进行gdb调试


http://www.kler.cn/news/17422.html

相关文章:

  • 截图的背景色如何去除?这里介绍一个小工具
  • buildroot系统调试苹果手机网络共享功能
  • 人机智能中几个困难问题浅析
  • API接口的对接流程和注意事项
  • STM32F4_十进制和BCD码的转换
  • 【地铁上的设计模式】--结构型模式:装饰器模式
  • IJKPLAYER源码分析-重要字段
  • LeetCode 1003. Check If Word Is Valid After Substitutions【栈,字符串】中等
  • 【GAMES101】03 Transformation
  • 回忆我的爷爷
  • 什么是图数据库Neo4j
  • 力扣---LeetCode141/142. 环形链表 (I)和(II) (代码详解+流程图+数学逻辑拓展)
  • 自动驾驶技术:前景、优势与挑战
  • kubernetes安装
  • Docker 架构
  • Vue生命周期
  • 第二十四回:如何屏蔽事件
  • SpringMVC(后)SSM整合
  • [创新工具和方法论]-01- DOE课程基础知识
  • K8s 安全是云安全的未来
  • AI仿写软件-仿写文章生成器
  • 计算机组成原理4.2.3提高存储器访问速度的措施
  • 送了老弟一台 Linux 服务器,它又懵了!
  • Ae:橡皮擦工具
  • Redis缓存穿透和雪崩
  • 3 文件和目录
  • 归纳截图小结
  • innodb_flush_log_at_trx_commit 和 sync_binlog 参数解析
  • 数字中国建设峰会|大模型带来产业智能化新机遇
  • 【Linux0.11代码分析】03 之 setup.s 启动流程