个人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正发挥了巨大的作用。
如下(示例):
#根目录
##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相关指令
如下:
说明:
1:main 文件夹 输出 可执行程序(exe)
2:algorithm_dll 文件夹 输出 动态库(dll)
3:algorithm_lib 文件夹 输出 静态库(lib)
4:bin 文件夹 存放 可执行程序(exe) 和 动态库(dll)
4:lib 文件夹 存放 静态库(lib)
5:build 文件夹 存放 中间文件 ( makefiel 和 sln 等 )
其中,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")
其中,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")
(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")
学习路漫漫,持续搞起来!
下篇将专门讲解cmake语法。