cmake 指定编译器_我们需要懂得CMake文件
我們需要懂得CMake文件
一、前言
從事于linux下的C++開發的人員都知道,在C++下編寫程序是沒有類似windows下編譯器的一鍵編譯和運行的按鈕,只能由我們開發人員進行手動編譯、運行;為了減免這種繁瑣而且復雜的勞動力,出現了makefile文件,makefile文件可以幫助我們很快的編譯大量文件,最終形成可執行文件;其實編寫makefile文件并不是很復雜,但是后面出現了cmake,這個可以直接幫我們寫makefile文件,我們只需要編寫cmake文件即可;
接下來,我們去看看cmake的一些規則和實踐,我會從實踐中來說明這些規則;
二、cmake
我們從案例開始
案例一:
在demo1的文件夾下,創建test.cpp文件和CMakeLists.txt文件;
test.cpp下存放的是我們測試的c++程序;
CMakeLists.txt就是cmake文件;
測試程序:
#include
#include
using namespace std;
class Test:public enable_shared_from_this
{public:
Test(){}
~Test(){}shared_ptr getPtr()
{return shared_from_this();
}void set(int id,string name){
_id = id;
_name = name;
}int getId(){return _id;
}string getName(){return _name;
}private:string _name;int _id;
};int main(){shared_ptrt1 = make_shared();
t1->set(1,"test");cout<<"id:"<getId()<<endl;cout<<"name:"<getName()<<endl;return 0;
}CMakeList.txt文件內容:
# 指定運行此配置文件所需的 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
#命令表示項目的名稱是 Demo1
project (demo1)
#添加-std=c++11選項
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#命令表示生成項目的名稱是 test
add_executable(test test.cpp)然后,我們在當前目錄下執行cmake .進行編譯生成makefile;
然后,執行make命令;
我們會發現,當前目錄下出現了可執行程序
我們從上面這個案例中,來解析cmake文件的語法:
指定運行此配置文件所需的 CMake 的最低版本,如果不加入此行會受到警告信息
cmake_minimum_required (VERSION 2.8)表示項目的名稱是 Demo1,也就是在哪個文件夾中
project (demo1)生成應用程序 test
add_executable(test test.cpp)添加-std=c++11選項
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
或者
add_compile_options(-std=c++11)在cmake腳本中,設置編譯選項可以通過add_compile_options命令,也可以通過set命令修改CMAKE_CXX_FLAGS或CMAKE_C_FLAGS。但是set命令設置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS變量則是分別只針對c和c++編譯器的;
上面我們會發現產生了很多cmake的中間文件,我們可以創建一個文件夾,將所有的中間文件以及最終的執行文件放在其中:
root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/demo2# mkdir build
root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/demo2# cd build/
root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/demo2/build# cmake ..這樣就ok了;
通過上面這個例子,我們大概熟悉了cmake的最基本的、也是核心的用法;
案例二:(多文件)
目錄結構
root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/demo2# tree
.
├── CMakeLists.txt
├── hello.cpp
├── hello.h
└── test.cpp
0 directories, 4 files首先看下文件內容:
test.cpp
#include
#include
#include "hello.h"
using namespace std;
class Test:public enable_shared_from_this
{public:
Test(){}
~Test(){}shared_ptr getPtr()
{return shared_from_this();
}void set(int id,string name){
_id = id;
_name = name;
}int getId(){return _id;
}string getName(){return _name;
}private:string _name;int _id;
};int main(){shared_ptrt1 = make_shared();shared_ptrt2 = make_shared();
t1->set(1,"test");cout<<"id:"<getId()<<endl;cout<<"name:"<getName()<<endl;
t2->setVal(10);cout<<"val:"<getVal()<<endl;return 0;
}hello.h
#pragma once
#include
using namespace std;
class Hello
{
public:
Hello();
~Hello();
void setVal(int val);
int getVal();
private:
int _val;
};hello.cpp
#include "hello.h"
Hello::Hello()
{
}
Hello::~Hello()
{
}
void Hello::setVal(int val)
{
_val = val;
}
int Hello::getVal()
{
return _val;
}再看看cmake文件:
CMakeLists.txt
# 指定運行此配置文件所需的 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
#命令表示項目的名稱是 Demo2
project (demo2)
#添加-std=c++11選項
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#查找當前目錄下的所有源文件,并將名稱保存到 DIR_SRCS 變量
aux_source_directory(. DIR_SRCS)
#命令表示生成項目的名稱是 main
add_executable(main ${DIR_SRCS})解析一下這個用法:
相比于第一個案例來說,這個文件新增了
aux_source_directory(. DIR_SRCS)這句代碼的代表:查找當前目錄下的所有源文件,并將名稱保存到 DIR_SRCS 變量
我們看一下aux_source_directory的用法:
aux_source_directory(
)該命令會把參數
然后使用${}方式獲取值;
那么,如果在不同的問價夾,那么怎么辦?
案例三:多文件 多目錄
我們只是把上面的文件進行移動,最終的目錄結構為:
.
├── CMakeLists.txt
├── hello
│ ├── CMakeLists.txt
│ ├── hello.cpp
│ └── hello.h
└── test.cpp
1 directory, 5 files想比較剛才只是將hello.h和hello.cpp文件移動到hello的文件夾中;
我們需要寫兩個cmake文件
最外層CMakeLists.txt文件內容:
# 指定運行此配置文件所需的 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
#命令表示項目的名稱是 Demo2
project (demo3)
#添加-std=c++11選項
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#查找當前目錄下的所有源文件,并將名稱保存到 DIR_SRCS 變量
aux_source_directory(. DIR_SRCS)
# 添加 hello 子目錄
add_subdirectory(hello)
#命令表示生成項目的名稱是 main
add_executable(main ${DIR_SRCS})
#添加動態庫
target_link_libraries(main hello)在hello文件夾中的CMakeLists.txt文件:
# 指定運行此配置文件所需的 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
#查找當前目錄下的所有源文件,并將名稱保存到 DIR_SRCS 變量
aux_source_directory(. DIR_LIB_SRCS)
# 生成鏈接庫
add_library(hello ${DIR_LIB_SRCS})相比于前面的CMakeLists.txt的文件來說,本次的cmake文件,多了以下幾個規則:
add_library:
該指令的主要作用就是將指定的源文件生成鏈接文件,然后添加到工程中去。該指令常用的語法如下:
add_library( [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL][source1] [source2] [...])
其中表示庫文件的名字,該庫文件會根據命令里列出的源文件來創建。而STATIC、SHARED和MODULE的作用是指定生成的庫文件的類型。STATIC庫是目標文件的歸檔文件,在鏈接其它目標的時候使用。SHARED庫會被動態鏈接(動態鏈接庫),在運行時會被加載。MODULE庫是一種不會被鏈接到其它目標中的插件,但是可能會在運行時使用dlopen-系列的函數。默認狀態下,庫文件將會在于源文件目錄樹的構建目錄樹的位置被創建,該命令也會在這里被調用。而語法中的source1 source2分別表示各個源文件。
link_directories該指令的作用主要是指定要鏈接的庫文件的路徑,該指令有時候不一定需要。因為find_package和find_library指令可以得到庫文件的絕對路徑。不過你自己寫的動態庫文件放在自己新建的目錄下時,可以用該指令指定該目錄的路徑以便工程能夠找到。
target_link_libraries該指令的作用為將目標文件與庫文件進行鏈接。該指令的語法如下:
target_link_libraries( [item1] [item2] [...][[debug|optimized|general] ] ...)上述指令中的是指通過add_executable()和add_library()指令生成已經創建的目標文件。而[item]表示庫文件沒有后綴的名字。默認情況下,庫依賴項是傳遞的。當這個目標鏈接到另一個目標時,鏈接到這個目標的庫也會出現在另一個目標的連接線上。這個傳遞的接口存儲在interface_link_libraries的目標屬性中,可以通過設置該屬性直接重寫傳遞接口。
這個就是多文件多目錄操作,這里貼以下具體流程截圖:
案例四:(分類文件夾)
在實際公司開發的時候,我們遇到最多就是使用分類文件夾的方式,就比如頭文件一般放在當前目錄下的include的目錄下,.cpp文件一般放在src文件中,靜態、動態庫可以放在lib中;一般來說,這種事比較規范的,而且我們不需要根據頭文件進行尋找文件的位置;
先看一下案例的目錄:
root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/demo5# tree .
.
├── CMakeLists.txt
├── example
│ └── test.cpp
├── include
│ └── hello.h
└── src
└── hello.cpp
3 directories, 4 files簡單看一下文件的內容:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(demo4)
set(CMAKE_CXX_STANDARD 11)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
include_directories(
${PROJECT_SOURCE_DIR}/include/
)
add_library(${PROJECT_NAME} SHARED
src/hello.cpp
)
add_executable(test example/test.cpp)
target_link_libraries(test
${PROJECT_NAME}
)example/test.cpp
#include "hello.h"
int main(){
HelloTest ht;
ht.Print();
return 0;
}include\hello.h
#include "hello.h"
HelloTest::HelloTest()
{
}
HelloTest::~HelloTest()
{
}
void HelloTest::Print()
{
cout<<"HelloTest"<<endl;
}先來執行一下:
運行一下:
我們發現運行成功了,再看看目錄文件:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.5.1
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ └── CMakeCCompilerId.c
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ └── CMakeCXXCompilerId.cpp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── demo4.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── CXX.includecache
│ │ │ ├── DependInfo.cmake
│ │ │ ├── depend.internal
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ ├── progress.make
│ │ │ └── src
│ │ │ └── hello.cpp.o
│ │ ├── feature_tests.bin
│ │ ├── feature_tests.c
│ │ ├── feature_tests.cxx
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ ├── TargetDirectories.txt
│ │ └── test.dir
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── CXX.includecache
│ │ ├── DependInfo.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── example
│ │ │ └── test.cpp.o
│ │ ├── flags.make
│ │ ├── link.txt
│ │ └── progress.make
│ ├── cmake_install.cmake
│ ├── Makefile
│ └── test
├── CMakeLists.txt
├── example
│ └── test.cpp
├── include
│ └── hello.h
├── lib
│ └── libdemo4.so
└── src
└── hello.cppcmake產生的中間文件我們不用關心,主要就是在lib文件夾中產生了libdemo4.so文件;
詳細看一下CMakeLists.txt文件:
按照C++11標準
set(CMAKE_CXX_STANDARD 11)
設置編譯動態庫輸出路徑
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
PROJECT_SOURCE_DIR代表的是CMakeLists.txt所在目錄
include_directories 是用來提供找頭文件路徑的
include_directories(
${PROJECT_SOURCE_DIR}/include/
)
基本的cmake使用的就這么多了,當然,cmake文件還有很多的用法,不過在平時普通的項目中,這些基本夠用了,更高級的語法后面還會逐漸完善。
想了解學習更多C++后臺服務器方面的知識,請關注:微信公眾號:====CPP后臺服務器開發====
掃碼CPP后臺服務器開發轉載是一種動力 分享是一種美德
總結
以上是生活随笔為你收集整理的cmake 指定编译器_我们需要懂得CMake文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本win10的图标变大了怎么办啊 笔
- 下一篇: 好用的ghost xp系统怎么安装 安装