cmake 生成exe调用生成的lib(动态库与静态库)

上一个cmake生成exe的博客已经说明了怎么在 linux cmake-gui 和 visual studio 下怎么编译CMake工程。这篇文章会直接在 visual studio 下构建目标。

下面主要对CMake生成的两种方式进行相关的生成

1.总CMakeLists.txt生成所有目标

2.含有subject CMake 生成所有目标

为什么提上面两种方式?这里牵扯到lib构建顺序依赖的问题(这里将在本文的 sub模块分离式生成目标 下进行详细的解释)

 

顶层CMakeLists.txt生成所有目标。

工程结构

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0)
# 最低版本要求 cmake 构建工具小于2.8.0将报错

project(genExeLinkLib)
# 工程项目名称

#set(MOD_CLASS_PATH "${CMAKE_SOURCE_DIR}/class")
set(MOD_CLASS_PATH ${CMAKE_SOURCE_DIR}/class)
# 设置一个变量标记路径 以上两种写法都是可行的 为了更好的适应各种CMake工程 推荐写第二种方式
# ${CMAKE_SOURCE_DIR} 这个取CMake自带宏里面的路径 就是这个CMakeLists.txt所在的路径

aux_source_directory(${MOD_CLASS_PATH} MOD_CLASS_SRC)
# ${} 固定的范式,取变量 MOD_CLASS_PATH 里面的值,这里为 ${CMAKE_SOURCE_DIR}/class
# MOD_CLASS_SRC 自定义的一个变量
# 整条语句将对 ${CMAKE_SOURCE_DIR}/class 的源码*.cpp 和*.c 文件 输出到变量 MOD_CLASS_SRC

#add_library(class_sayHello ${MOD_CLASS_SRC})# 默认构建静态库
#add_library(class_sayHello STATIC ${MOD_CLASS_SRC}) #和上面语句是一样的 
add_library(class_sayHello SHARED ${MOD_CLASS_SRC}) # 构建动态库
# 将所有的源文件归档成lib 这一句将会在build下生成lib
# 设置生成目录这里暂时先不做编写 如果生成静态库的话直接注释打开然后注释 SHARED 这一句

# --------------上面的语句就已经能够生成动态库------------------
aux_source_directory(${CMAKE_SOURCE_DIR} RP_ALL_SRC)
# 这里对 ${CMAKE_SOURCE_DIR} 也就是当前CMakeList.txt 目录下的*.cpp输出到变量
# RP_ALL_SRC (ROOTPATH_ALL_SRC 意为顶层目录所有源码)
add_executable(HelloExecute ${RP_ALL_SRC})

# --------------这里很明显还没有引用lib 这是至少百分之八十友友遇到的错误----------
# error:link 多半就是目录问题 引用未定义的函数一般都是 宏 或者你忘记写函数实现
target_link_libraries(HelloExecute class_sayHello)  
#为生成目标添加一个库 可以是多个 比如 target_link_libraries(HelloExecute lib1 lib2) 
#这里因为是在同一个CMakeLists.txt中 所以lib会被识别并找到,这里默认构建了其生成的依赖关系
#为了屏蔽平台差异 我们直接省略后缀 .lib  因为gcc生成的库 .a  .so

Hello.h

#ifndef HELLO_H
#define HELLO_H

#include <iostream>

class _declspec(dllexport)  Hello
{
public:
	Hello();
	~Hello();
	void sayHello();
}; 

#endif // !HELLO_H

Hello.cpp

#include "Hello.h"

Hello::Hello()
{
}

Hello::~Hello()
{
}

void Hello::sayHello()
{
	std::cout << __FUNCTION__ << std::endl;
}

main.cpp

#include "class/Hello.h"
#include <iostream>
int main(int argc, char* argv[]) 
{
	Hello helloUnit;
	helloUnit.sayHello();

	int a;
	std::cin >> a;
}

运行结果

 

add_subdirectory生成目标

 

上图对整个目录结构进行梳理,每一个存在CMakeLists.txt 都可以称之为模块。为了更好的实现上图的结构应当避免模块间的耦合度(当然这不是硬性的规定)。具体的模块间的引用问题这里暂时留在下一篇博客中去说明。比如在其他子项的目录中我存在一种顺序依赖的关系、包括后面在 CMakeLists.txt中的 package_find() 语法命令。其实上面的目录结构是存在问题的,这里为了适应本博文和读者理解,循序渐进吧。

 

工程结构:

 

genExeLinkLib/class/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0) #cmake的 最低版本

project(class)#尽量和目录同名,为了方便区分

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} class_ALL_SRC)
# 遍历当前cmake下的所有*.c和*.cpp文件 输入到变量 class_ALL_SRC
# CMAKE_CURRENT_SOURCE_DIR 是当前的CMakeLists.txt的路径,如果存在疑问你可以打开下面的语句论证
# message(STATUS "CMAKE_CURRENT_SOURCE_DIR >>${CMAKE_CURRENT_SOURCE_DIR}")

add_library(${CMAKE_PROJECT_NAME} ${class_ALL_SRC})
#引用当前所有c和cpp文件 生成一个 class.lib
#CMAKE_PROJECT_NAME 为cmake自带变量 获取当前project()设置的变量,主要作用于当前CMakeLists.txt文件

genExeLinkLib/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0)

project(genExeLinkLib) #工程名称

aux_source_directory(${CMAKE_CURRENT_LIST_DIR} genXX_ALL_SRC) #遍历当前CMakeLists.txt所有*.c和*.cpp 输出到 genXX_ALL_SRC 变量

add_subdirectory(class) #添加子项

add_executable(genExeLinkLib ${genXX_ALL_SRC}) # 生成可执行目标 genExeLinkLib

target_link_libraries(genExeLinkLib class) # 添加lib依赖

install(TARGETS genExeLinkLib
    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/dll
	ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
	LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)#安装目录

 

运行结果:

 

 

如果大家在使用CMakeLists.txt工程上遇到了问题可以加我的 CMake技术交流Q群 870836798

CMake中,你可以使用add_library命令来设置生成动态库静态库。add_library命令用于创建一个新的库目标,并指定库的类型。 要生成动态库,可以将add_library命令的第一个参数设置为库的名称,然后将第二个参数设置为SHARED。例如: ```cmake add_library(mylib SHARED source1.cpp source2.cpp) ``` 上面的例子中,我们创建了一个名为mylib动态库目标,并将源文件source1.cpp和source2.cpp添加到该目标中。生成动态库文件将具有与平台相关的扩展名(如.so、.dll或.dylib)。 要生成静态库,可以将add_library命令的第一个参数设置为库的名称,然后将第二个参数设置为STATIC。例如: ```cmake add_library(mylib STATIC source1.cpp source2.cpp) ``` 上面的例子中,我们创建了一个名为mylib静态库目标,并将源文件source1.cpp和source2.cpp添加到该目标中。生成静态库文件将具有与平台相关的扩展名(如.a、.lib或.a)。 默认情况下,CMake将根据操作系统和构建配置(如Release或Debug)来决定使用动态库还是静态库。但你也可以使用set_target_properties命令来显式地指定目标生成的库类型。例如: ```cmake set_target_properties(mylib PROPERTIES LINKER_LANGUAGE CXX) ``` 上面的例子中,我们将目标mylib的链接器语言设置为C++,这将影响生成的库的类型。 总之,通过在add_library命令中使用SHARED或STATIC作为第二个参数,可以设置生成动态库静态库。你也可以使用set_target_properties命令来显式指定库的类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值