菜鸟笔记
提升您的技术认知

cmake基础-ag真人游戏

cmake安装:download | cmake。

在这之前,我们介绍一下cmake。虽然make和makefile简化了手动构建的过程,但是编写makefile文件仍然是一个麻烦的工作,因此就有了cmake工具。cmake工具用于生成makefile文件,而如何生成makefile文件,则由cmakelists.txt文件指定。它们直接的关系如下图:

使用cmake生成makefile并编译的流程如下:

  • 编写cmake配置文件cmakelists.txt。
  • 执行命令 cmake path生成cmakefile。其中,path为cmakelists.txt所在的目录。
  • 使用make命令进行编译。

指定编译器

特别注意的是,指定编译器的语句需要放在cmakelists.txt文件最前面。

指定gcc版本

在linux系统下,gcc一般在/user/bin目录下。在里面可以看gcc的版本。

zhudk@vm1:/usr/bin$ cd
zhudk@vm1:~$ cd /usr/bin
zhudk@vm1:/usr/bin$ ls |grep gcc
c89-gcc
c99-gcc
gcc
gcc-7
gcc-ar
gcc-ar-7
gcc-nm
gcc-nm-7
gcc-ranlib
gcc-ranlib-7
x86_64-linux-gnu-gcc
x86_64-linux-gnu-gcc-7
x86_64-linux-gnu-gcc-ar
x86_64-linux-gnu-gcc-ar-7
x86_64-linux-gnu-gcc-nm
x86_64-linux-gnu-gcc-nm-7
x86_64-linux-gnu-gcc-ranlib
x86_64-linux-gnu-gcc-ranlib-7

如果没有指定编译器的话,默认使用的就是gcc编译器。如果系统中有多个版本gcc,需要指定gcc的版本,可以在环境变量中设置:

export cc=gcc-7      

设置完成后,我们执行cmake命令,会发现如下打印:

zhudk@vm1:/expand/zhudk/demo$ cmake .
-- the c compiler identification is gnu 7.5.0
-- the cxx compiler identification is gnu 7.5.0
-- check for working c compiler: /usr/bin/cc
-- check for working c compiler: /usr/bin/cc -- works
-- detecting c compiler abi info
-- detecting c compiler abi info - done
-- detecting c compile features
-- detecting c compile features - done
-- check for working cxx compiler: /usr/bin/c  
-- check for working cxx compiler: /usr/bin/c   -- works
-- detecting cxx compiler abi info
-- detecting cxx compiler abi info - done
-- detecting cxx compile features
-- detecting cxx compile features - done
-- configuring done
-- generating done
-- build files have been written to: /expand/zhudk/demo
使用交叉编译器

使用结对路径:

set(cross_compiler_path "/expand/zhudk/toolchain/opt/friendlyarm/toolchain/6.4-aarch64/bin/aarch64-linux-gcc")
set(cmake_c_compiler ${cross_compiler_path})

或者直接使用编译器名称:

set(cmake_c_compiler "aarch64-linux-gcc")

项目配置

指定cmake最小版本
cmake_minimum_required (version 3.10)
指定项目名
project (main)
# 或
project ("main")
指定编译语言与项目版本
project (main languages cxx version 1.0.0)

编译配置

添加编译选项

方式1

set(cmake_cxx_flags   "-no-pie")
set(cmake_c_flags   "-no-pie") # 命令行方式传入:-dcmake_c_flags=-no-pie

方式2

add_compile_options (
添加搜索路径

头文件

include_directories (inc)

库文件

link_directories (lib)
添加库文件

note:target_link_libraries需要放于add_executable之后

静态库

target_link_libraries(project_name mxnet) #添加libmxnet.a

动态库

target_link_libraries(project_name -lmxnet) #添加libmxnet.so
添加子目录编译
add_subdirectory (lib)
添加程序宏定义

为当前路径以及下层路径的目标加入编译器命令行定义,相当于在**c/c **程序中使用#define

对全部生成目标而言

add_definitions (-dfoo -dbar ...)

对单个生成目标而言

target_compile_definitions(
                            [items1...]
                           [ [items2...] ...]
                          )

生成目标

编译生成可执行文件

必须放在project的前面

add_executable (main main.cpp)
编译生成库

note:默认生成静态库,除非特意指定生成库的类型

  • 静态库
add_library(archive static archive.cpp zip.cpp lzma.cpp)
  • 动态库
add_library(archive shared archive.cpp zip.cpp lzma.cpp)

经典示例

多目录多源文件

# set(cross_compiler_path "/expand/zhudk/toolchain/opt/friendlyarm/toolchain/6.4-aarch64/bin/aarch64-linux-gcc")
# set(cmake_c_compiler ${cross_compiler_path})
set(cmake_c_compiler "aarch64-linux-gcc")
project(haha)
cmake_minimum_required(version 3.10)
set(cmake_c_flags "-g -wall -o2")
set(executable_output_path ${project_source_dir}/build/bin)
aux_source_directory(. src)
aux_source_directory(./aaa src)
aux_source_directory(./bbb src)
aux_source_directory(./ccc src)
add_executable(${project_name} ${src})

上述项目结构是一个不同目录下多个源文件的情况,根据代码功能不同放在不同的目录下。

set(executable_output_path ${project_source_dir}/build/bin)

是设置生成的可执行文件的路径,project_source_dir:工程的根目录

aux_source_directory(dir var)

是把指定目录下所有源文件存储在一个变量中(追加在这个变量中)。

add_executable(${project_name} ${src})

生成可执行文件。

关于头文件的引用,在aaa.c文件中:

#include "aaa.h"
#include "../bbb/bbb.h"
#include "../ccc/ccc.h"

算是手动引用的。如果不想在include的时候手动引用,则可以在cmakelists.txt中提前添加头文件搜索目录。

include_directories(./bbb)

现在我们来运行cmake。注意,因为运行cmake的时候会生成很多附带文件,如果直接在根目录下运行cmake的话,会对程序目录造成污染,所以,建议在./build目录下运行cmake,然后可执行文件存放在./build/bin

zhudk@vm1:/expand/zhudk/demo/build$ cmake ..
-- the c compiler identification is gnu 7.5.0
-- the cxx compiler identification is gnu 7.5.0
-- check for working c compiler: /usr/bin/cc
-- check for working c compiler: /usr/bin/cc -- works
-- detecting c compiler abi info
-- detecting c compiler abi info - done
-- detecting c compile features
-- detecting c compile features - done
-- check for working cxx compiler: /usr/bin/c  
-- check for working cxx compiler: /usr/bin/c   -- works
-- detecting cxx compiler abi info
-- detecting cxx compiler abi info - done
-- detecting cxx compile features
-- detecting cxx compile features - done
-- configuring done
-- generating done
-- build files have been written to: /expand/zhudk/demo/build
zhudk@vm1:/expand/zhudk/demo/build$ make
scanning dependencies of target haha
[ 20%] building c object cmakefiles/haha.dir/main.c.o
[ 40%] building c object cmakefiles/haha.dir/aaa/aaa.c.o
[ 60%] building c object cmakefiles/haha.dir/bbb/bbb.c.o
[ 80%] building c object cmakefiles/haha.dir/ccc/ccc.c.o
[100%] linking c executable bin/haha
[100%] built target haha
生成库

aux_source_directory(. libsrc)
#设置库输出路径
set(library_output_path ../lib)
#生成静态库 最后的库名称会为libhello.a
#add_library(hello static ${libsrc})
#生成动态库 最后的库名称会为libhello.so
#add_library(hello shared ${libsrc})
#只是连续2次使用add_library指定库名称时(第一个参数),这个名称不能相同
#所以上述写法 不会生成动态库。可以先不使用相同的名称,再修改库的名称
add_library(hello_static static ${libsrc})
add_library(hello_shared shared ${libsrc})
set_target_properties(hello_static properties output_name hello)
set_target_properties(hello_shared properties output_name hello)
链接库

还是上述的库文件。

project(haha)
cmake_minimum_required(version 3.10)
set(cmake_c_flags "-g -wall -o2")
set(executable_output_path ${project_source_dir}/build/bin)
aux_source_directory(. src)
aux_source_directory(./aaa src)
aux_source_directory(./bbb src)
aux_source_directory(./ccc src)
include_directories(./include)
find_library(lib libhello.a hints ${project_source_dir}/lib)
add_executable(${project_name} ${src})
target_link_libraries(${project_name} ${lib})
  • find_library: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是hints,第4个参数是路径,其它用法可以参考cmake文档
  • target_link_libraries: 把目标文件与库文件进行链接。

使用find_library的好处是在执行cmake ..时就会去查找库是否存在,这样可以提前发现错误,不用等到链接时。

添加控制选项

在cmakelists.txt中使用变量
option(debug "a debug option" off) #0或者off 1或者on
if(debug)
	message("debug is ${debug}")
else()
	message("debug is ${debug}")	
endif()

加入想在cmakelists.txt文件中控制一些语句,可以使用option定义变量。

option命令,其第一个参数是这个option的名字,第二个参数是字符串,用来描述这个option是来干嘛的,第三个是option的值,on或off,也可以不写,不写就是默认off

在执行cmake命令的时候,可以设置其值。cmake .. -ddebug=1

在源码中使用option变量

在cmakelists.txt中定义宏,可以直接在源码中使用。

add_definitions(-ddebug)
#include 
#include "./aaa/aaa.h"
#include "./bbb/bbb.h"
#include "./ccc/ccc.h"
#include "hello.h"
int main(void)
{
  
	printf("hello world!\n");
	aaa();
	bbb();
	ccc();
	hello();
#ifdef debug
	printf("debug\n");
#endif
	return 0;
}

可以直接在源码中使用,会打印debug

在源码中使用option变量

在cmakelists.txt中定义宏,可以直接在源码中使用。

add_definitions(-ddebug)
#include 
#include "./aaa/aaa.h"
#include "./bbb/bbb.h"
#include "./ccc/ccc.h"
#include "hello.h"
int main(void)
{
  
	printf("hello world!\n");
	aaa();
	bbb();
	ccc();
	hello();
#ifdef debug
	printf("debug\n");
#endif
	return 0;
}

可以直接在源码中使用,会打印debug

仔细想了一下,如果真的需要修改宏的时候,还不如直接修改源码,修改后直接make就可以了,如果修改了cmakelists.txt文件,那么还重新cmake。

网站地图