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