前言
不得不承認在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 就編譯完成了