C++项目经验(1)——切实理解#include<>和#include““的区别,并利用它“抠库”

目录

1.<>和""的含义

实验结果:

解释:

2.抠库-OSQP为例

步骤1:OSQP和OSQP-Eigen安装

步骤2:把头文件和库文件抠出来,并写CMakeLists

步骤3.开干

3.代码


1.<>和""的含义

背景:#include<>和#include""的区别困扰了我很久,网上的说法亦不明朗,于是决定做实验探究(by ubuntu, CMake)

实验结果:

<>的搜索范围=系统目录(含临时);" "的搜索范围=该文件的相对路径+<>的搜索范围

解释:

① 什么叫该文件的相对路径?

即该#include命令所在的文件的相对路径。我们现有一个文件夹Test,结构如下

Test
├── out_file.h
└── test_inner
    ├── CMakeLists.txt
    ├── haha.cc
    ├── haha.h
    ├── include
    │   └── include.h
    ├── main.cc
    └── src
        └── src.h

3 directories, 7 files

那么,CMakeLists关于头文件什么也不设置,在main.cc里,你可以直接

#include "haha.h"
#include "src/src.h"
#include "include/include.h"
#include "../out_file.h"

同理,在include.h里,你可以直接

#include "../haha.h"
#include "../src/src.h"
#include "../../out_file.h"

简单点说,就是要引用文件对该文件的相对路径,只要你愿意,写个“../../../../fxxk.h”跑到很远的地方去找,也可以

②什么叫系统目录?

实质是编译器预处理的默认搜索目录,指令如下所示

echo | g++ -v -x c++ -E -    // 打印gcc预处理c++的默认目录
echo | gcc -x c -v -E -      // 打印gcc预处理c的默认目录
echo | clang -x c++ -v -E -  // 打印clang预处理c++的默认目录

我电脑里(Ubuntu 18.04),打印gcc预处理c++的默认目录的结果如下

#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/7
 /usr/include/x86_64-linux-gnu/c++/7
 /usr/include/c++/7/backward
 /usr/lib/gcc/x86_64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

换句话说,你随便写个"fxxk.h"放在这些文件夹之一,也可以直接

#include <fxxk.h>

③“系统目录(含临时)”中的“临时”是什么意思?

记不记得,CMakeLists里,我们经常会添加头文件目录——调用include_directories指令。

这个指令底层上是改变了什么?

就是暂时性地将include_directories指令提到的路径,加在系统目录之后,只在本次Cmake有效(但我还不知道怎么去证明这件事)

所以,只要你在include_directories把源码涉及的文件夹全包含一遍……头文件你可以全写<>(不重名的前提下)

④有同名怎么办?

按顺序,先找到哪个用哪个。<>搜索时,按系统目录顺序搜索,""搜索时,先搜相对路径,再搜系统

2.抠库-OSQP为例

很多库我们不都是直接安装的嘛,但实际上,除去很复杂的,相当一部分库的安装,只是把头文件放进系统目录,把库文件也放进系统目录,以OSQP库为例,下面演示怎么全抠出来并使用。

好处:女朋友:“我要用OSQP!”你:“安装啊。”女朋友:“我不!我不装!我要直接跑!”你:“我给你封个docker。”女朋友:“不,我不要docker,我就要直接跑!”你:“……”(哦不,我没有女朋友。但我是打工人啊,公司可不允许交一个安库才能运行的代码)

步骤1:OSQP和OSQP-Eigen安装

安装步骤详见:qp solver

安装它们的最后一步(sudo make install),你会看到如下代码(以OSQP为例)

 由于我以前安过,所以写的up-to-date,第一次安应该是Installing

然后你就发现了,头文件被安装在/usr/local/include/osqp和/usr/local/include/qdldl两个文件夹下,库文件在/usr/local/lib下,有4个。OSQP-EIGEN也是同理。

步骤2:把头文件和库文件抠出来,并写CMakeLists

现在我们的文件结构如下,其中抠出来的头文件和库文件分别放在了自建的对应文件夹的include和lib文件夹下(Eigen也是同理,我也抠了)

3rdparty_test
├── 3rdparty
│   ├── Eigen
│   │   ├── Eigen
│   │   ├── signature_of_eigen3_matrix_library
│   │   └── unsupported
│   ├── osqp
│   │   ├── include
│   │   └── lib
│   └── osqp-eigen
│       ├── include
│       └── lib
├── CMakeLists.txt
└── main.cpp

然后CMakeLists加的关键几行如下,都很常规(分别是添加头文件目录,添加库文件目录,生成可执行文件,链接库),很好理解

include_directories(3rdparty/osqp/include 3rdparty/Eigen 3rdparty/osqp-eigen/include)

LINK_DIRECTORIES(3rdparty/osqp/lib 3rdparty/osqp-eigen/lib)

add_executable (${PROJECT_NAME} main.cpp)

TARGET_LINK_LIBRARIES(${PROJECT_NAME} libosqp.so libosqp.a libOsqpEigen.so)

步骤3.开干

这个时候,你就可以回到之前的抠库的地方,把系统里这几个库的文件全部删了!!!

然后,#include它们,看跑不跑得通

main.cpp的头文件包含如下所示

#include "osqp.h"
#include "Eigen/Core"
#include "Eigen/Dense"
#include "OsqpEigen.h"

这个时候你发现可能能跑通,抠库成功??

不是,还不能打包发给女朋友,因为大概率是你删系统库还没删干净,比如你打开osqp-eigen.h,开头是这样写的

/**
 * @file OsqpEigen.h
 * @author Giulio Romualdi, Stefano Dafarra
 * @copyright  Released under the terms of the BSD 3-Clause License
 * @date 2018
 */
#ifndef OSQPEIGEN_OSQPEIGEN_H
#define OSQPEIGEN_OSQPEIGEN_H

#include <OsqpEigen/Constants.hpp>
#include <OsqpEigen/Data.hpp>
#include <OsqpEigen/Settings.hpp>
#include <OsqpEigen/Solver.hpp>
#include <OsqpEigen/SparseMatrixHelper.hpp>

#endif //OSQPEIGEN_OSQPEIGEN_H

按道理来说,这是找不到的,我们需要把它们改成(或者改目录结构)

#include "Constants.hpp"
#include "Data.hpp"
#include "Settings.hpp"
#include "Solver.hpp"
#include "SparseMatrixHelper.hpp"

或

#include <Constants.hpp>
#include <Data.hpp>
#include <Settings.hpp>
#include <Solver.hpp>
#include <SparseMatrixHelper.hpp>

当你把每个头文件(或目录结构)都改好时,就真的抠出来了,能打包发女朋友啦!

发之前,你可以先把整个文件夹拷出来,放到一个新建的啥也没有的虚拟机里跑跑,没bug就是零卡!

我自己把每个文件的头文件都改好了,并在新的虚拟机里测试过能跑的代码放在下面链接里了,希望对路过的人有所帮助。也希望我早日找到女朋友o(╥﹏╥)o

3.代码

链接: 某度   /s/17Zl4_kBgZr8cQhr77yuuyQ 
提取码:oobk 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值