前言
不得不承认在ubuntu对编译C/C++程序非常不友好,经常得自己写CMakeLists.txt.有时候在同一个项目中,还需要把自己写的类编译成动态库,下面记录下自己在ubuntu开发中遇到的坑。
假设我们这里定义了一个类
(1)这是类的头文件 mylib.hpp
#ifndef MYLIB_H
#define MYLIB_H
#include <iostream>
class Math{ //类名大写
public: //公有变量
static int AddAToB(int A, int B); //定义一个静态方法
int callPriv(int A,Math m);
private: //私有变量
int priv_a = 1; //c++11 以上可以直接在定义时初始化,但是仍然只能被类成员调用
}
#endif
(2)我们在该类的cpp文件中实现其成员mylib.cpp
#include "mylib.hpp"
int Math::AddAToB(int A, int B) //实现该方法的时候,需要指明该**类名**
{
int C = A+B;
return C;
}
int Math::AMulB(int A, Math m)
{
int C = A * m.priv_a;
return C;
}
(3)把Math类编译成动态库
第一种:直接使用命令编译:
g++ -shared -o libMath.so (生成的so文件) -fPIC -std=c++11 mylib.cpp
第二种:使用cmake编译,下面是CMakeLists.txt的相关写法:
cmake_minimum_required(VERSION 2.8)
project(mylib_)
set(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
set(mylib_dir /home/xxx/xxx/ (需要编译的代码的路径))
add_library(mylib_math SHARED ${mylib_dir}/mylib.cpp ${mylib_dir}/mylib.hpp)
------------------
接着执行cmake . (句号别漏了)
在执行 make 就编译完成了,此时会生成 libmylib_math.so的动态库文件
接着是调用该类的代码文件 test.cpp
#include "路径/mylib.hpp"
#include <iostream>
int main
{
Math m; //声明该类对象
int res_1, res_2;
int x = 3;
int y = 4;
res_1 = Math::AddAToB(x, y); //静态变量可以直接通过(类名::函数)的方式调用
res_2 = m.AMulB(x, m); //该方法中调用了Math的私有变量priv_a
std::cout << res_1 << std::endl; //输出7
std::cout<< res_2 <<std::endl; //输出3
}
(4)编译main函数所在的cpp文件并链接Math类的动态库
第一种方法:(直接使用命令编译)
g++ test.cpp -o demo -l mylib_math(动态库的名字,前面不用加lib) /home/ xxx/xxx/libmylib_math.so (动态库文件所在的路径)
第二种使用cmake进行编译,下面是CMakeLists.txt的代码:
cmake_minimum_required(VERSION 2.8)
project(test)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-fPIC -lstdc++ ${CMAKE_CXX_FLAGS}")
add_executable(demo /home/xxx/xxx//test.cpp (该cpp文件所在的路径))
TARGET_LINK_LIBRARIES(demo /home/xxx/xxx/libmylib_math.so (需要链接的动态库的路径))
接着输入 cmake .
然后 make 就编译完成了