linux gcc编译c文件头文件
linux gcc编译c文件头文件,使用GCC编译器编译C语言
凶猪下山
转载
关注
0点赞·1047人阅读
GCC编译C源代码有四个步骤:预处理—->编译—->汇编—->链接。
可以利用GCC的参数来控制执行的过程,这样就可以更深入的了解编译C程序的过程。
下面将通过对一个程序的编译来演示整个过程。
#include
int main()
{
printf("happy new year!\n");
return 0;
}
1:预处理:编译器将C程序的头文件编译进来,还有宏的替换,可以用gcc的参数-E来参看。
预处理 命令:gcc -E hello.c -o hello.i
作用:将hello.c预处理输出hello.i
2:编译:这个阶段编译器主要做词法分析、语法分析、语义分析等,在检查无错误后后,把代码翻译成汇编语言。可用gcc的参数-S来参看。
编译器(ccl)将文本文件hello.i 翻译成文本文件hello.s, 它包含一个汇编语言程序。汇编语言程序中的每条语句都以一种标准的文本格式描述了一条低级机器语言指令。
编译命令:gcc -S hello.i -o hello.s
作用:将预处理输出文件hello.i汇编成hello.s文件
3:汇编:把编译阶段生成的.s 文件转换为二进制目标代码。可用gcc的参数-c来参看。汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成可重定位目标程序的格式, 并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它的字节编码是机器语言。
汇编 命令:gcc -c hello.s -o hello.o
作用:作用:将汇编输出文件hello.s编译输出hello.o文件
4:链接:把obj文件链接为可执行的文件:链接器(ld)负责.o文件的并入。结果就是hello文件,它是一个课执行的目标文件,可以加载到存储器后由系统调用。
链接命令:gcc hello.o -o hello
一步操作的话是: (-o必须在hello之前 )
$gcc hello.c -o hello
$./hello或者:(会默认生成a.out文件)
$gcc hello.c
$./a.out
‘贰’ C语言,关于头文件
编译器会在链接时搜索参与链接的所有文件,b.c中的函数会被链接到a.c所需的位置(不需要头文件也可)
‘叁’ C++中类的头文件和实现文件怎么用
例如:有三个文件。名字分别是:a.h
,
a.cpp,
aTest.cpp
.
a.h就是类的头文件。a.cpp是头文件a.h中类的实现,它里面要有
#include"a.h"
。
aTest.cpp是类的使用文件,在这个文件里你可以用这个类去完成它能完成的功能,在它里面要有:
#include"a.h"
,但是不用
#include"a.cpp"
,,,,,,,,,,,
。在编译a.h时,自动编译了a.cpp。
‘肆’ 关于头文件编译
头文件不能编译,只能编译源文件。
源文件预编译的时候,如果碰到#include <xxx.h>,就把xxx.h中的文本内容全部复制到相应的位置
比如在
cpp中写
int a[] = {
#include "a.h"
};
在"a.h"中写
1, 2, 3, 4, 5
是合法的。
预编译后就是
int a[] = {
1, 2, 3, 4, 5
};
你还可以试验其他更古怪的#include方法。再结合#define去理解预编译的意义。
‘伍’ C#中如何使用头文件(xxxx.h),以及如何将头文件编译成动态链接库(DLL)
头文件、cpp文件和dll文件之间的是这样的关系:头文件声明方法,cpp实现方法、cpp编译后得到dll,因此头文件描述的是dll文件的接口,也就是具体实现的接口。如果你只有dll文件,只要知道其导出的方法就可以直接使用,win32有对应的api。如果想要将dll中的所有可用方法包含到项目中,就要包含头文件。这就是说,头文件和dll文件是对应的。另外,如果你的头文件中已经包含了实现代码,那你需要提供一个空的cpp文件,包含该头文件,并将它们编译成dll文件。
C#没法直接用C++的头文件,但是可以直接用dll,使用的技术称作PInvoke,原理是在C#代码中用extern关键字添加dll中所需方法的签名,也就是二楼说的那种方法。此外,如果这个dll是采用com技术实现的,也可以使用.NET平台提供的COM互操作特性直接导入使用。
‘陆’ 编译时怎么使用.a文件
编译时怎么使用.a文件
for example:(1)动态库的编译
这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。
命令:$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
‘柒’ linux下,C语言头文件在哪
一、 C标准库头文件,以及Linux的标准库文件的对应头文件,默认放在/usr/include下。 如图:
标识出了最常用的几个头文件。
二、 自定义头文件,或者集成头文件,需要在编译的时候指定。可以在命令行中指定,也可以在makefile中指定。
指定自定义头文件路径方式为:
-IPATH1 -IPATH2...
如当前目录下的inc文件夹,指定为头文件, 那么在编译a.c时,可以命令写作:
gcc a.c -I./inc -o a.out
‘捌’ c++头文件编译重编译
#ifndef XXXXX_H // 如果没有定义 XXXXX_H
#defined XXXXX_H // 先定义 XXXXX_H , 那么下一次编译到这个 头文件的时候上一句条件不成立,下面的内容就不会再编译了。
// 头文件中的代码
#endif
在C++中,可以用#pragma once,用了#pragma once 之后就可以不用那么麻烦去判断有没有编译 过这个头文件了,那个由编译器自己判断了。
‘玖’ 关于在linux下用gcc编译头文件的问题。
我用一个例子来告诉你怎么样在 C++ 里使用C的头文件/函数。
比方说我有一个C的头文件叫 c.h, C的源码文件叫 c.c,内容分别是
c.h:
#ifndef _ASDFD_INCLUDED_
#define _ASDFD_INCLUDED_
#include <stdio.h>
extern int test(int a);
#endif
c.c:
#include "c.h"
int test(int a)
{
printf("A = %d\n", a);
return a*a;
}
现在我想在c++中使用c.c中提供的函数test(),我的c++文件名字叫 a.cpp,那么里面跟C有关的部分就要用 extern "C" {} 大括号括起来,看看我的
a.cpp:
#include <iostream>
using namespace std;
extern "C"
{
#include "c.h"
}
int main()
{
int b = 12;
b = test(b);
cout<<"b = "<<b<<endl;
return 0;
}
看到了吧,#include "c.h" 被 extern "C" {}括起来了。
然后是如何编译,先把C文件编出目标文件(.o)来
gcc -c c.c
你会看到生成了 c.o,其实,有目标文件就够了,如果你一定要做成(静态/动态)库文件,也是可以的,不过我这里就不深入了,做成库和直接用目标文件对解决你的问题没有任何区别。
然后再编译C++文件,也就是我的 a.cpp
g++ -o hello a.cpp c.o
看到了吧,我在编译 a.cpp 的时候把C生成的 c.o也加上了。 然后生成 可执行的 hello, 运行
./hello
就可以看到
A = 12
b = 144
关于创建静态库,假定你有3个C文件, a.c, b.c, c.c 提供了你C++要用到的接口,那么可以把这三个C文件编译出来的目标文件放到一个库文件里供C++使用,方法为
先编译出目标文件
gcc -c a.c b.c c.c
这时候你应该看到有 a.o b.o c.o了
然后创建库文件
ar cr libtest.a a.o b.o c.o
这三个目标文件就放入 libtest.a 这个静态库中了,然后编译C++程序 (你的C++程序应该已经按照我前面说的用 extern "C" 把C的接口都括起来了),假定你的 libtest.a 放在 /home/aaa/lib下
g++ -o my.exe my.cpp -L/home/aaa/lib -ltest
就会生成可执行文件 my.exe了。
‘拾’ ios中怎么调用a文件里的内容
ios中后缀名为a的文件是编译好的二进制文件,一般是第三方为了保密代码而使用的。a文件里边的内容是没法看懂的,只有配合.h头文件,知道它有哪些暴露出来的属性或者函数才能调用。调用方法和平时使用 .h .m 文件一样,只是你看不见.m里边的代码而已。