一.文件结构
1.结构
CMakeLists.txt
---myapp
CMakeLists.txt
myapp.c
---mylib
CMakeLists.txt
mylib.c
mylib.h
2.说明
mylib:只有一个源文件,编译输出一个动态库;
myapp:也只有一个源文件,链接 mylib 动态库,编译输出一个可执行程序;
二.代码
1.mylib.h
// mylib/mylib.h w文件
#ifndef _MY_LIB_
#define _MY_LIB_
#ifdef MY_LINUX
#define MYLIB_API extern
#else
#ifdef MYLIB_EXPORT
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
#endif
MYLIB_API int my_add(int num1, int num2);
MYLIB_API int my_sub(int num1, int num2);
#endif // _MY_LIB_
2.mylib.c
# mylib/mylib.c 文件
#include "mylib.h"
int my_add(int num1, int num2)
{
return (num1 + num2);
}
int my_sub(int num1, int num2)
{
return (num1 - num2);
}
3.mylib/CMakeLists.txt
# mylib/CMakeLists.txt 文件
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(mylib VERSION 1.0.0)
# 自定义宏,代码中可以使用
ADD_DEFINITIONS(-DMYLIB_EXPORT)
# 头文件
INCLUDE_DIRECTORIES(./)
# 源文件
FILE(GLOB MYLIB_SRCS "*.c")
# 编译目标
ADD_LIBRARY(${PROJECT_NAME} SHARED ${MYLIB_SRCS})
4.myapp.c
// myapp/myapp.c 文件
#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
int main(int argc, char *argv[])
{
int ret1, ret2;
int a = 5;
int b = 2;
ret1 = my_add(a, b);
ret2 = my_sub(a, b);
printf("ret1 = %d \n", ret1);
printf("ret2 = %d \n", ret2);
getchar();
return 0;
}
5.myapp/CMakeLists.txt
# myapp/CMakeLists.txt 文件
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(myapp VERSION 1.0.0)
# 头文件路径
INCLUDE_DIRECTORIES(./include)
# 库文件路径
LINK_DIRECTORIES(./lib)
# 源文件
FILE(GLOB MYAPP_SRCS "*.c")
# 编译目标
ADD_EXECUTABLE(${PROJECT_NAME} ${MYAPP_SRCS})
# 依赖的动态库
TARGET_LINK_LIBRARIES(${PROJECT_NAME} mylib)
6.最外层的CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(cmake_demo VERSION 1.0.0)
SET(CMAKE_C_STANDARD 99)
# 自定义宏,代码中可以使用
if (CMAKE_HOST_UNIX)
ADD_DEFINITIONS(-DMY_LINUX)
else ()
ADD_DEFINITIONS(-DMY_WINDOWS)
endif()
ADD_SUBDIRECTORY(mylib)
ADD_SUBDIRECTORY(myapp)
三.Linux 下构建过程
说明:如果没有Cmake,需要先安装:
# 查看版本
cmake --version
# Ubuntu下安装最新 CMake
sudo apt install cmake
1.cmake 配置
为了不污染源文件目录,在最外层目录下新建build目录,然后执行cmake指令:
$ cd ~/tmp/cmake_demo/
$ mkdir build
$ cd build/
$ ls
$ cmake ..
2.make 编译
需要手动创建include和lib文件夹,并且把头文件mylib.h和库文件libmylib.so拷贝进去,操作过程如下:
$ cd ~/tmp/cmake_demo/myapp/
$ mkdir include lib
$ cp ~/tmp/cmake_demo/mylib/mylib.h ./include/
$ cp ~/tmp/cmake_demo/build/mylib/libmylib.so ./lib/
3.准备好头文件和库文件之后,再次编译一下:
$ cd ~/tmp/cmake_demo/build/
$ make
[ 50%] Built target mylib
[ 75%] Building C object myapp/CMakeFiles/myapp.dir/myapp.c.o
[100%] Linking C executable myapp
[100%] Built target myapp
此时,就在 build/myapp 目录下生成可执行文件myapp了。
4.测试、执行
$ cd ~/tmp/cmake_demo/build/myapp
$ ./myapp
ret1 = 7
ret2 = 3
由于我们是在build目录下编译的,编译过程中所有的输出和中间文件,都放在build目录下,一点都没有污染源文件。
四.windows下构建
1.把Linux系统中的build文件夹删除,然后把测试代码压缩,复制到Windows系统中继续测试。
在Windows下编译,一般就很少使用命令行了,大部分都使用VS或者VSCode来编译。
2.第一步: cmake 配置
先安装Cmake软件,官网下载安装即可:Download CMake ;
新建一个build目录,然后采用CMake软件来进行配置,如图:
注意:用的CMake软件要和CMakeLists.txt里面定义的版本要匹配
配置成功后再Generate:
成功Configure和Generate后build目录内容如下:
3.用vs打开配置好的工程,编译运行即可
注意:
运行的时候,mylib.dll 要放到myapp.exe生成的目录中。