为了账号安全,请及时绑定邮箱和手机立即绑定

我对Cmake不是很了解,现在工程中出现了这么一个需求:

我对Cmake不是很了解,现在工程中出现了这么一个需求:

C++
回首忆惘然 2023-01-07 13:09:21

一个工程需要工程外的文件作为库,这很常见。但同时这个工程外的文件也需要这个工程内部头文件。

先展示一个demo:

.
├── CMakeLists.txt
├── include
│ └── mul_lib.h
├── mul_lib.c
└── my_project
├── CMakeLists.txt
├── include
│ ├── fun.c
│ └── fun.h
└── src
├── CMakeLists.txt
└── main.c

在上面的文件中,我的工程目录是my_project,而工程外面有一个我需要的头文件mul_lib.h文件,在这个头文件中有这么一句:

#include <fun.h>

本来呢,这句是要导入其他文件夹下的文件的,但是我现在想让它导入我工程下面的include文件下的fun.h文件。

这就出现了标题所描述的问题,请问我要如何编写CMakeLists.txt文件才能实现这种想法呢?

查看完整描述

1 回答

?
FFIVE

TA贡献1519条经验 获得超6个赞

首先给你说明使用extern一次只能包含一个变量或者函数,如果你的另一个文件中有N多个变量或函数的话,你要依次使用extern逐个包含进来,如果这样的话你会不会觉得太麻烦,而且这样程序的可读性也降低了。因此你要把整个文件的内容引入到当前文件中,最好使用#include把头文件包含进来。下面就给你介绍一个extern关键字和把程序写在多个文件中的内容吧。

链接性:链接性为外部的名称可在文件之间共享,链接性为内部的名称只能由一个文件中的函数共享。局部变量不存在共享,也就是说局部变量不存在链接性问题。也就是说链接性为外部的变量可以使用extern关见字把他包含进来由其他文件使用,即和其他文件共享同一个变量;而链接性为内部的变量则不能在其他文件之中使用,如果每个文件中都有一个相同的这个变量,则彼此之间是相互独立的,不存在共享性。比如文件1有一个链接性为外部的变量int e=3;则文件2可以使用extern int e;把e包含进来,两个文件使用的是同一个变量e,文件2对e的修改将影响到文件1中的e的变量。而如果文件1和文件2中的两个变量e的链接性是内部的话,则两个变量将是各自独立的变量,对各自变量的修改不影响另一个文件中的同名变量。

1、对于大型程序一般将一个程序写在多个文件中:一般把程序分成三部分,头文件和两个源文件,其中头文件包含类的声明或函数的声明。其中一个源文件就包含这些类和函数的定义,而另一个源文件则是主程序。
2、将程序放在多个文件中的好处是比如有多个这样的程序需要在头文件中声明的这些函数,则只需在该程序中把这些头文件包含进来。头文件和包含头文件定义的文件就组成了一个软件包,可用于各种程序中。
3、通常不应将函数声明和变量声明放在头文件中。因为如果头文件包含一个函数定义,然后在同一程序的其他两个文件中包含了这个头文件,则同一程序中将包含同一函数的两个定义,除非是内联函数,否则就将出错。
4、头文件一般包含:函数原型,使用#define或const定义的符号常量,结构声明,类声明,模板声明,内联函数。
5、包含头文件时使用#include关见字,在#include后面文件名最好使用双引号不要使用尖括号,比如#include “eee.h”使用双引号和尖括号的区别是使用尖括号时编译器将首先在标准头文件中查找,而使用双引号则首先在当前工作目录或源代码目录查找。
6、不能在同一个文件中包含头文件两次。一般不会犯这种错误,但是当使用包含了一个头文件的文件时有可能在不知情的情况下犯这个错误。
7、使用预处理器指令#ifndef来解决上面的问题。语名#ifndef hyong…..#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef….#endif之间的语句。#define通常创建符号常量,比如#define H 3;把常量3定义为名字H,但只使用#define就能创建名称,比如#define H;就创建了一个名称H。完整的#ifndef….#endif语句的例子如下:#ifndef HY #define HY void g(); #endif;该语句的执行顺序为:编译器首先遇到该头文件时,名称HY没有被定义,这时编译器就将查看#ifndef….#endif之间的内容,并读取到#define HY这一行。如果在同一文件中遇到包含该头文件的代码时,编译器就知道HY这个名字已经被#define定义了,从而跳过#ifndef….#endif之间的内容。注意这种方法并不能防止头文件被包含两次,而只是让他忽略除第一次包含之外的所有内容。

//将程序放在多个文件中的示例:
//头文件hyong.h的内容如下
#ifndef HY //一般在头文件都都使用这种格式以防止头文件在同一文件中被包含两次。语名#ifndef hyong…..#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef….#endif之间的语句。
#define HY //在这里用define定义一个名字HY,以便在下次访问到该头文件时,使该名字已经被定义,从而让程序跳过#ifndef….#endif间的语句。
void g(); //在头文件中声明一个函数g();
#endif

//在头文件hy.h中定义函数,一般不允许这样做
#include <iostream>
using namespace std;
void f(){cout<<"f()"<<endl;}

//定义头文件中声明的函数的源文件hyong.cpp的内容如下
#include "stdafx.h" //注意:在VC++中所有的源文件中都要包含这条语句。
#include "hyong.h" //将头文件hyong.h包含进来,这里使用双引号,而不是引号,以便能更快地检查到该头文件中定义的名字
#include “hy.h” //
#include <iostream>
using namespace std;
void g(){cout<<"g()"<<endl;} //定义头文件hyong.h中声明的函数g()

//主程序源文件ff.cpp的内容如下
#include "stdafx.h"
#include<iostream>
#include "hyong.h" //注意,主程序和hyong.cpp的文件中都包含了这个头文件。
//#include “hy.h” //错误,在同一程序中的另一个文件hyong.cpp中已包含过该头文件,因为f函数是在hy.h这个头文件中定义的,在这里再包含头文件hy.h就会出现在同一程序中定义了两个f()函数的错误。
using namespace std;
int main() {g(); cout<<"p"<<endl; } //f();//对f函数的调用错误,因为f函数在头文件hy.h中定义,并且不能在主程序文件中再包含头文件hy.h,在这里就会出现f是未标识的标识符的错误。

 


查看完整回答
反对 回复 2023-01-10

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信