linux下gcc编程04-cmake工程管理

一。cmake简介

 CMake是一个跨平台的编译、安装、测试以及打包工具;CMake不直接编译软件,而是结合原生构建系统来构建软件。
   CMake配置文件是CMakeList.txt文件(每个源码文件夹下都要有一个),CMake根据配置文件再生成Unix的Makefile或VS的solution文件等。
   Cmake旨在通过一个配置来解决不同平台编写不同编译配置文件的方法 cmake仅仅帮我们生成编译工程文件,最终编译靠
 各自编译器
   图解:

  

  1》 cmake安装 

yum -y install cmake

 查看版本

[root@localhost rule]# cmake --version
cmake version 2.8.12.2

cmake官方向导 https://cmake.org/cmake-tutorial/
官方文档:https://cmake.org/documentation 老版本在最下面
最简单的配置文件
添加一个hello.c的源码

#include <stdio.h>
void main(){
	printf("hello\n");
}

在当前目录下新建CMakeList.txt文件内容

#CMake最低版本号要求
cmake_minimum_required (VERSION 2.8)
#项目信息
project (demo)
#指定生成目标 参数1表示生成目标文件的名称 参数2表示源文件
add_executable(demo hello.c)

执行 (cmake 有cmakelist.txt文件的目录)

cmake .

执行完成后 发现当前目录下 生成了Makefile文件 使用make 命令就可以编译了

[root@localhost helloworld]# cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /root/vc/helloworld
[root@localhost helloworld]# make && ./demo
[100%] Built target demo
hello

 

二。cmake多目录实战

假设项目的目录结构为:

inc目录下为头文件a.h:

#include <stdio.h>
#include <stdlib.h>
int add(int p1,int p2);
void syso(char* c);

math目录下为 add方法的实现c文件 mmath.c 因为头文件不在同一个目录 所以gcc 指定 -I

#include "a.h"
int add(int p1,int p2){
	return p1+p2;
}

utils目录包含了syso方法的实现syso.c

#include "a.h"
void syso(char* c){
	printf(c);
}

根目录下有个 main.c 添加应用的入口main方法
 

#include "a.h"
void main(){
	int number=add(111,333);
	char str[25];
	sprintf(str, "%d", number);
	syso(str);	
}

假设这里分别 将 mmath.c编译成动态库.so syso.c编程静态库 .a 
math目录下添加一个 CMakeLists.txt文件

#设置输出的链接库的位置 PROJECT_BINARY_DIR是 cmake执行的目录 PROJECT_SOURCE_DIR是有
# CMakeLists.txt的目录 比如cmake .. 当前目录就是 PROJECT_BINARY_DIR 上一级目录就是
# PROJECT_SOURCE_DIR
set(LIBRARY_OUTPUT_PATH  ${PROJECT_BINARY_DIR})
include_directories (${PROJECT_SOURCE_DIR}/../inc)
#将某个文件编译成动态库
add_library(mmath SHARED mmath.c)

utils目录下添加一个 CMakeLists.txt文件

#设置输出的链接库的位置
set(LIBRARY_OUTPUT_PATH  ${PROJECT_BINARY_DIR})
include_directories (${PROJECT_SOURCE_DIR}/../inc)
#将某个文件编译成静态库
add_library(syso STATIC syso.c)

根目录下添加一个CMakeLists.txt文件 要求运行根目录自动调用子目录的
 

#CMake最低版本号要求
cmake_minimum_required (VERSION 2.8)
#项目信息
project (mydemo)
#定义编译时 包含头文件位置
include_directories (inc)
#生成时打印出消息
MESSAGE(STATUS "开始生成子目录math")
#cmake调用子目录 执行子目录的 CmakeLists.txt 
add_subdirectory (math) 
MESSAGE(STATUS "开始生成子目录utils")
add_subdirectory (utils) 
#指定链接目标文件的目录
link_directories(${PROJECT_BINARY_DIR})
#定义一个变量 ALL_C 使用 ${变量名引用}
set(ALL_C main.c)
MESSAGE(STATUS "开始生成程序")
#指定生成目标
add_executable(mydemo ${ALL_C})
#指定 mydeo这个可执行文件依赖 syso和mmath两个动态链接库
target_link_libraries(mydemo syso)
target_link_libraries(mydemo mmath)

#-----------------------------
# 下面的代码仅用于学习命令
#-----------------------------
#-----执行命令 拿到系统版本 指定uname -r 将结果写入MY_HOST_SYSTEM_NAME变量
EXEC_PROGRAM(uname ARGS -s OUTPUT_VARIABLE MY_HOST_SYSTEM_NAME)
if(MY_HOST_SYSTEM_NAME STREQUAL "Linux")
	message(STATUS "系统是:${MY_HOST_SYSTEM_NAME}")
endif()
#-----给INSTALL_STATIC_LIBRARIES定义个默认值 如果cmake ../ -DINSTALL_STATIC_LIBRARIES=OFF 没有带这个参数默认值就是ON 带了就是带了的值
OPTION(INSTALL_STATIC_LIBRARIES "Install static libraries",ON)
message(STATUS "输出是:${INSTALL_STATIC_LIBRARIES}")
#-----循环输出 0-5 步数是1	
foreach(loop_var RANGE 0 5 1)
	message(STATUS "循环输出是:${loop_var}")
endforeach(loop_var)	

foreach(loop_var "zs" "ls")
	message(STATUS "循环输出是:${loop_var}")
endforeach(loop_var)
#包含一个包含cmake语法的txt文件 
include(a.txt)
#-----获取环境变量
set(MPATH $ENV{PATH})
message(STATUS "包含获取变量:${a} 环境变量 ${MPATH}")			

#-----定义宏
MACRO(testMacro age)  
  set(age 11) #宏修改参数是无效的
  message(STATUS "这是一个宏定义 参数是 ${age}")
endmacro(testMacro)
#调用宏
set(age 10)
testMacro(${age})					  
					  
#-----定义函数
function(myage age])
   set(age 11 PARENT_SCOPE) #函数内修改参数是无效的 调用方的值还是之前的值 必须加上PARENT_SCOPE才能修改
  message(STATUS "这是一个函数定义 参数是 ${age}")
endfunction(myage)	
set(age 10)
myage(${age})		
#注意函数内部修改的值对外部无效 除非使用了引用修改值 PARENT_SCOPE	  
message(STATUS "age值: ${age}")					  
					  
#-----get_filename_component 得到一个完整文件名中的特定部分。					  
GET_FILENAME_COMPONENT(MYDIR "c:/a/a.txt" DIRECTORY) #获取目录 结果 c:/a
message(${MYDIR})
GET_FILENAME_COMPONENT(MYDIR "c:/a/a.txt" EXT)		#EXT获取后缀 	txt路径(PATH),文件名(NAME),文件扩展名(EXT),去掉扩展名的文件名(NAME_WE),完整路径(ABSOLUTE),或者所有符号链接被解析出的完整路径(REALPATH)		  
message(${MYDIR})					  		  

因为运行cmake 会生成很多的临时文件为了 怕污染源代码  我们进入bin目录执行 
 

[root@localhost bin]# cmake ../
CMake Warning (dev) in CMakeLists.txt:
  Syntax Warning in cmake code at

    /root/vc/cmake/CMakeLists.txt:33:59

  Argument not separated from preceding token by whitespace.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- 开始生成子目录math
-- 开始生成子目录utils
-- 开始生成程序
-- 系统是:Linux
-- 输出是:OFF
-- 循环输出是:0
-- 循环输出是:1
-- 循环输出是:2
-- 循环输出是:3
-- 循环输出是:4
-- 循环输出是:5
-- 循环输出是:zs
-- 循环输出是:ls
-- 包含获取变量:1 环境变量 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
-- 这是一个宏定义 参数是 10
-- 这是一个函数定义 参数是 10
-- age值: 11
c:/a
.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /root/vc/cmake/bin
[root@localhost bin]# make
Scanning dependencies of target mmath
[ 33%] Building C object math/CMakeFiles/mmath.dir/mmath.c.o
Linking C shared library ../libmmath.so
[ 33%] Built target mmath
Scanning dependencies of target syso
[ 66%] Building C object utils/CMakeFiles/syso.dir/syso.c.o
Linking C static library ../libsyso.a
[ 66%] Built target syso
Scanning dependencies of target mydemo
[100%] Building C object CMakeFiles/mydemo.dir/main.c.o
Linking C executable mydemo
[100%] Built target mydemo
[root@localhost bin]# ./mydemo



 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值