前言
很久没有写文章了,最近在刷《剑指offer》,看懂了算法思想,也要动手练习一下,但又不想在visual studio下练,整个工程文件太大了,所以用vscode连接WSL,在Linux环境下编程练习,难受的是之前都是在有图形界面的条件下用CLion编程的,整个流程就是使用IDE自动解决了,对c++的编译链接使用过程比较生疏,故重新学习以此篇随笔记录学习过程。
工具
- CMake 3.16
- gcc 5.4
- ubuntu 16.04(wsl)
基础知识
C/C++程序编译过程详解
在Linux 环境下编程首先感觉到一点疑惑就是,如果我不写makefile,使用CMake ,CMake是怎么找到我自己定义的类的头文件和源文件的。假如我在一个main.cpp 里创建了一个example 的类对象,而这个类是定义在main.cpp之外的头文件和源文件中。这个类是以静态库链接还是动态库的形式链接。在IDE环境下开发的时候,不需要考虑这些东西,但是在Linux 环境下开发,不搞清楚这些东西好像寸步难行。
以上问题很难通过搜索引擎限制的寥寥数字得到答案,关键点在于对CMake的理解。
CMake是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。 它用配置文件控制建构过程(build process)的方式和Unix的make相似,只是CMake的配置文件取名为CMakeLists.txt。CMake并不直接建构出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用。
从CMake 软件的定义可以知道其只是一个自动化工具,其对C++文件编译遵循的常规流程,当理清了头绪了,就可以学习相应的CMake语法进行构建了。
示例
首先是目录结构,为了篇幅简洁,所以删掉一些自动生成的文件和文件夹。
hellblazer@SurFace-ProJ:~/c_pplus_pratice/test-multi-file$ tree .
.
├── build 构建文件夹,采用out of source 编译,即源文件外编译
│ ├── bin
│ │ └── test ‘可执行文件’
│ ├── lib
│ ├── libfoo.a 静态库文件
│ └── libfoo.so 动态库文件
├── CMakeLists.txt
└── src
├── CMakeLists.txt
├── lib
│ ├── CMakeLists.txt
│ ├── include
│ │ └── foo.h
│ └── src
│ └── foo.cpp
└── test
├── CMakeLists.txt
└── src
└── test.cpp 测试文件
./CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(MULTI_PROJECT)
add_subdirectory(src)
./src/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
add_subdirectory(lib)
add_subdirectory(test)
./src/lib/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
#添加对c++11的支持
set( CMAKE_CXX_FLAGS "-std=c++11" )
#PROJECT_BINARY_DIR 为源外编译目录
set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib")
#PROJECT_SOURCE_DIR 为工程顶层目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src/lib/src FOOlib_src)
#指明头文件目录
include_directories("${PROJECT_SOURCE_DIR}/src/lib/include")
#SHARED 为生成动态库文件 libfoo.so
add_library(foo SHARED ${FOOlib_src})
#STATIC 生成静态库文件 libfoo_static.a
add_library(foo_static STATIC ${FOOlib_src})
#重置静态库文件名为libfoo,因为cmake不允许输出重名
set_target_properties(foo_static PROPERTIES OUTPUT_NAME "foo")
./src/test/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
#添加对c++11的支持
set( CMAKE_CXX_FLAGS "-std=c++11" )
#定义输出文件目录
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin")
#定义源文件目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src/test/src test_src)
#头文件目录
include_directories("${PROJECT_SOURCE_DIR}/src/lib/include")
#库文件目录
link_directories("${PROJECT_BINARY_DIR}/lib")
#定义可执行文件名
add_executable(test ${test_src})
#链接静态库文件
target_link_libraries(test libfoo.a)
编译命令
cd build
cmake ..
make
出错,可以用make clean