CMAKE-实战1-windows(调用动态库和静态库)

windows--调用动态库和静态库

  • 前言
  • 一、cmake是什么?
  • 二、实战
    • 1.CmakeLists.txt 编写示例
    • 2.项目目录树
    • 3.项目文件
      • 3.1.静态库 (algorithm_lib)
      • 3.2.动态库 (algorithm_dll)
      • 3.3.可执行程序 (main)
    • 4.结果与sln结构展示
      • 4.1.执行结果
      • 4.2.sln目录结构
  • 三、总结


前言

个人cmake学习历程记录,帮助自己复习巩固,也为需要的小伙伴提供一点个人学习经验。


一、cmake是什么?

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。它能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。

Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。
链接: 百科

总结:官方的话总是显得比较高深,绕来绕去。
个人总结:camke首先是一个工具,一般为大型项目构建项目结构所用。以windows平台为例,可以在本地编写名为CMakeLists.txt的文件(名字固定),按照一定的用法规则,即可构建出sln。以前学习c++时,都是在vs上收到配置附加依赖项等环境。开发大型工程时,明显需要一个快速构建项目环境的工具,cmake正发挥了巨大的作用。

二、实战

1.CmakeLists.txt 编写示例

如下(示例):

#根目录

##cmake所需最低版本
cmake_minimum_required(VERSION 3.24.0)

##工程名
project(CMAKE_DEMO)

##设置路径名
set(TARGET_INCLUDE_LIB_PATH ${PROJECT_SOURCE_DIR}/algorithm_lib)
set(TARGET_INCLUDE_DLL_PATH ${PROJECT_SOURCE_DIR}/algorithm_dll)

##添加子目录
add_subdirectory(main)
add_subdirectory(algorithm_lib)
add_subdirectory(algorithm_dll)

CmakeLists.txt 需要遵循基本语法规则去书写,这里不过得介绍语法规则。感兴趣的可以查询cmake相关指令

2.项目目录树

如下:
CMAKE-实战1-windows(调用动态库和静态库)_第1张图片
说明:
1:main 文件夹 输出 可执行程序(exe)
2:algorithm_dll 文件夹 输出 动态库(dll)
3:algorithm_lib 文件夹 输出 静态库(lib)
4:bin 文件夹 存放 可执行程序(exe)动态库(dll)
4:lib 文件夹 存放 静态库(lib)
5:build 文件夹 存放 中间文件 ( makefiel 和 sln 等 )

3.项目文件

3.1.静态库 (algorithm_lib)

CMAKE-实战1-windows(调用动态库和静态库)_第2张图片
其中,public文件夹中存放算法的抽象类 iAlgorithmService_lib.h

(1) algorithm_lib.h 代码如下:

#ifndef _ALGORITHM_LIB_H
#define _ALGORITHM_LIB_H

#include "./public/iAlgorithmService_lib.h"
class  AlgorithmLib : public IAlgorithmLibService
{
public:
	AlgorithmLib() {};
	~AlgorithmLib() {};
public:
	virtual int add(int a, int b) override;
	virtual float add(float a, float b) override;
};
#endif

(2) algorithm_lib.cpp 代码如下:

#include"../algorithm_lib.h"

int AlgorithmLib::add(int a, int b)
{
	return a+b;
}
float AlgorithmLib::add(float a, float b)
{
	return a + b;
}
#endif

(3) iAlgorithmService_lib.h 代码如下:

#ifndef _IALGORITHMSERVICE_LIB_H_
#define _IALGORITHMSERVICE_LIB_H_

class  IAlgorithmLibService
{
public:
	IAlgorithmLibService() {};
	virtual ~IAlgorithmLibService() {};
public:
	virtual float add(float a , float b) = 0;
	virtual int add(int a , int b) = 0;
};
#endif

(4) CmakeList.text 代码如下:

set(TARGET "algorithm_static_lib")
set(TARGET_PUBLIC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/public)

include_directories(${TARGET_PUBLIC_PATH})

file(GLOB_RECURSE INCLUDE_H_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
source_group("include" FILES ${INCLUDE_H_FILES})

file(GLOB_RECURSE PUBLIC_H_FILES ${TARGET_PUBLIC_PATH}/*.h)
source_group("public" FILES ${PUBLIC_H_FILES})

file(GLOB_RECURSE SOURCE_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
source_group("source" FILES ${SOURCE_SRC_FILES})

set(all_src ${SOURCE_SRC_FILES}
			${INCLUDE_H_FILES}
			${PUBLIC_H_FILES}
			${SOURCE_SRC_FILES})

add_library(${TARGET} STATIC ${all_src})

SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")

3.2.动态库 (algorithm_dll)

其中,public文件夹中存放算法的抽象类 iAlgorithmService_dll.h

(1) algorithm_dll.h 代码如下:

#define DLL_EXPORT __declspec(dllexport)

#include
#include "./public/iAlgorithmService_dll.h"

extern "C" DLL_EXPORT void haha();

class  DLL_EXPORT AlgorithmDll : public IAlgorithmDllService
{
public:
	AlgorithmDll() {};
	~AlgorithmDll() {};

public:
	virtual int add(int a, int b) override;
	virtual double add(double a, double b) override;
	virtual float add(float a, float b) override;
};

(2) algorithm_dll.cpp 代码如下:

#include"algorithm_dll.h"
int DLL_EXPORT AlgorithmDll::add(int a, int b)
{
	return a+b;
}

double DLL_EXPORT AlgorithmDll::add(double a, double b)
{
	return a + b;
}

float DLL_EXPORT AlgorithmDll::add(float a, float b)
{
	return a + b;
}

void haha()
{
	std::cout << "haha" << std::endl;
}

(3) iAlgorithmService_dll.h 代码如下:

#ifndef _IALGORITHMSERVICE_DLL_H
#define _IALGORITHMSERVICE_DLL_H

class  IAlgorithmDllService
{
public:
	IAlgorithmDllService() {};
	virtual ~IAlgorithmDllService() {};

public:
	virtual double add(double a , double b) = 0;
	virtual int add(int a , int b) = 0;
	virtual float add(float a, float b) = 0;
};
#endif

(4) CmakeList.text 代码如下:

set(TARGET "algorithm_shared_dll")

set(TARGET_PUBLIC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/public)


include_directories(${TARGET_PUBLIC_PATH})

file(GLOB_RECURSE INCLUDE_H_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
source_group("include" FILES ${INCLUDE_H_FILES})

file(GLOB_RECURSE PUBLIC_H_FILES ${TARGET_PUBLIC_PATH}/*.h)
source_group("public" FILES ${PUBLIC_H_FILES})

file(GLOB_RECURSE SOURCE_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
source_group("source" FILES ${SOURCE_SRC_FILES})

set(all_src ${SOURCE_SRC_FILES}
			${INCLUDE_H_FILES}
			${PUBLIC_H_FILES}
			${SOURCE_SRC_FILES})

add_library(${TARGET} SHARED ${all_src})

SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")

3.3.可执行程序 (main)

(1) test.h 代码如下:

#include"algorithm_lib.h"
#include "algorithm_dll.h"


void staticLibTest();
void staticDllFuncTest();
void staticDllClassTest();

(2) main.cpp 代码如下:

#include
#include"test.h"
#include 
using namespace std;

void staticLibTest()
{
	AlgorithmLib ad;
	int sum = ad.add(1, 2);
	std::cout << "sum = " << sum << std::endl;
}

void staticDllFuncTest()
{
    //根据实际输出路径定义
	string str = "E:\\cmakeDemo\\lib\\Debug\\algorithm_shared_dll.dll";
	HMODULE handle = LoadLibrary(str.c_str());
	typedef void (*print)();
	print pr = (print)GetProcAddress(handle,"haha");
	pr();
	FreeLibrary(handle);
}

void sharedDllClassTest()
{
	AlgorithmDll ad;
	double sum = ad.add(1.11, 3.11);
	std::cout << "sum = " << sum << std::endl;

	float a = 1.1;
	float b = 2.1;
	float sum1 = ad.add(a, b);
	std::cout << "sum1 = " << sum1 << std::endl;
}

int main()
{
	//staticLibTest();
	//staticDllFuncTest();
	sharedDllClassTest();
	system("pause");
	return 0;
}

(3) CmakeList.text 代码如下:

set(TARGET "service")

file(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
source_group("source" FILES ${SOURCE_FILES})

file(GLOB_RECURSE HEAD_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
source_group("include" FILES ${HEAD_FILES})

include_directories(${TARGET_INCLUDE_LIB_PATH})
include_directories(${TARGET_INCLUDE_DLL_PATH})

add_executable(${TARGET} ${SOURCE_FILES} ${HEAD_FILES})

target_link_libraries(${TARGET} algorithm_static_lib)
target_link_libraries(${TARGET} algorithm_shared_dll)

SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")

4.结果与sln结构展示

4.1.执行结果

CMAKE-实战1-windows(调用动态库和静态库)_第3张图片

4.2.sln目录结构

CMAKE-实战1-windows(调用动态库和静态库)_第4张图片


三、总结

学习路漫漫,持续搞起来!
下篇将专门讲解cmake语法。

你可能感兴趣的:(cmake,windows,c++)