任務描述:在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)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示例程序。