Ubuntu環境下cmake編譯C++代碼爲可執行文件

任務描述:在Ubuntu下利用cmake方式編譯C++代碼,並運行。

分爲三個步驟,由淺入深逐步講解。

Part A. 多源碼編譯;Part B. 源碼+第三方庫編譯;Part C. 多文件源碼+第三方庫


Part A 源碼

step 1. 編寫示例代碼如下:

#include <iostream>
#include "a.h"
#define NUM 100
int main()
{
    std::cout << NUM << std::endl;
    std::cout << "Hello World!" << std::endl;
    a();
    return 1;
}

其中的“a()”函數的功能是輸出一個字符串,如下:

#include "a.h"
void a()
{
    std::cout << "aaaa" << std::endl;
}

我們的文件結構如下圖:

step 2. 編寫CMakeLists.txt文件,放在與源文件同級的路徑下

cmake_minimum_required (VERSION 2.8)
project(dome CXX)

aux_source_directory(. DIR_SRC)
add_executable (demo ${DIR_SRC})

相關含義可以參考 參考1參考2,感謝博主的分享。

主要解釋一下容易出問題的地方:

(1)project中的CXX指的是C++,如果不特別指定,則支持所有語言 ;工程名稱中的dome可以自由指定。

(2)aux_source_directory作用是自動搜索指定路徑下的全部源文件,指定的路徑由關鍵字提供,且與之前的“.”之間有空格,表示DIR_SRC的上一級目錄爲指定的搜索路徑。

(3)add_executable 中的第一個名字dome是我們編譯後生成的可執行文件的名字,可以自由指定,不要求必須與工程同名。

step 3. 編譯

第一步,在源代碼所在路徑下新建build文件夾並進入

$ mkdir build
$ cd build

build文件夾將存放cmake中間過程產生的文件,目的是與源代碼文件隔離。因此可以理解爲何在上一部中,搜索源文件要在當前

 路徑的上一級目錄了。此時文件結構如下圖:

第二步,執行cmake生成Makefile

$ cmake ..
-- The CXX compiler identification is GNU 7.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 
-- Configuring done
-- Generating done

指令中空格後的“..”也是表示上一級目錄,因爲我們的CMakeLists.txt文件是與build文件夾同級的。

通過上述編譯信息也可以看到,使用了指定的CXX編譯器。

第三步,執行make生成可執行文件

$ make
Scanning dependencies of target demo 
[ 33%] Building CXX object CMakeFiles/dome.dir/a.cpp.o
[ 66%] Building CXX object CMakeFiles/dome.dir/test.cpp.o
[100%] Linking CXX executable demo 
[100%] Built target demo 

上述顯示編譯完畢,則在build下生成名爲demo的可執行文件, 可以成功運行。


Part B  源碼+第三方庫

step 1. 第三方庫以opencv爲例,即利用c++開發依賴於opencv的代碼。

查看opencv版本等相關信息請參見 查閱opencv版本信息,感謝博主的分享。

step 2.  我們的文件結構與A部分大致相同,但是在test.cpp中用到了opencv庫進行開發,示例代碼如下圖

step 3. 編寫CMakeLists.txt文件

可以參考

cmake_minimum_required (VERSION 2.8)
project(demo CXX)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

aux_source_directory(. DIR_SRC)
add_executable (demo ${DIR_SRC})

target_link_libraries(demo ${OpenCV_LIBS})

與Part A相同的部分不再贅述,其他新增的部分可以參考 cmake添加opencv依賴庫,感謝博主的分享。

step 4. 其餘的編譯操作與Part A相同,

$ mkdir build
$ cd build
$ cmake ..
-- The CXX compiler identification is GNU 7.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version "3.4.1") 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sz/Desktop/test/build
$ make
Scanning dependencies of target dome
[ 33%] Building CXX object CMakeFiles/dome.dir/a.cpp.o
[ 66%] Building CXX object CMakeFiles/dome.dir/test.cpp.o
[100%] Linking CXX executable demo 
[100%] Built target demo 

最終可以順利運行示例程序。


Part C 多文件源碼

在Part B的基礎上,我們將a.h和a.cpp整理在文件夾a中存放,這更加符合我們真正開發時的文件結構,即根目錄下是框架/測試程序,子文件夾下是功能實現。數據結構如圖

則我們的CMakeLists.txt文件改寫如下:

cmake_minimum_required (VERSION 2.8)
project(demo CXX)
 
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

aux_source_directory(. DIR_SRC)
message(STATUS "SRC: ${DIR_SRC}")
aux_source_directory(./a DIR_SRC1)
message(STATUS "SRC: ${DIR_SRC1}")

add_executable (demo ${DIR_SRC} ${DIR_SRC1})
target_link_libraries(demo ${OpenCV_LIBS})

其中 aux_source_directory(./a DIR_SRC1) 表示的是搜索a文件路徑下的源碼;

並在生成可執行文件時,將全部源碼文件給出,如 add_executable (dome ${DIR_SRC} ${DIR_SRC1})

當然,如果有很多子文件分別存放不同功能源碼,那麼相應的可以有DIR_SRC2,DIR_SRC3等等,只要在編譯可執行文件時一一寫入指令就可以了。

其中 message(STATUS "SRC: ${DIR_SRC}") 是在打印出DIR_SRC的內容,是CMakeLists.txt的調試信息,可以不寫,此處僅是爲了方便觀察是否所有源碼文件都被找到了。運行結果如下:

$ mkdir build
$ cd build/
$ cmake ..
-- The CXX compiler identification is GNU 7.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version "3.4.1") 
-- SRC: ./test.cpp
-- SRC: ./a/a.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sz/Desktop/test/build
$ make
Scanning dependencies of target demo 
[ 33%] Building CXX object CMakeFiles/dome.dir/test.cpp.o
[ 66%] Building CXX object CMakeFiles/dome.dir/a/a.cpp.o
[100%] Linking CXX executable demo 
[100%] Built target demo 
$ ./demo 

最終可以成功運行demo示例程序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章