GCC makefile shell 相关个人笔记

shell 函数
notdir 
用于去掉文件的绝对路径,只保留文件名
patsubst 
$(patsubst %.c, %.o, $(SRC_C))
把$(SRC_C)中的变量符合后缀是.c的全部替换成.o

.gcc常用参数
    2.1 -v / --version    //查看编译器版本
    2.2 -I   //指定头文件的路劲  -l 头文件目录路径
    2.3 -c   //将汇编文件生成二进制文件  (compile)只编译生成中间同名目标文件,不链接
    2.4 -o   //指定生成文件的名字 (output)指定输出文件名,该文件为可执行文件,不加-o会默认生成x.out
    2.5 -d   //gdb调试的时候需要加的参数
    2.6 -D   //编译的时候指定宏 
    2.7 -Wall //添加警告信息
    2.8 -On   优化,n是优化级别

--whole-archive 和 --no-whole-archive 

是ld专有的命令行参数,gcc 并不认识,要通gcc传递到 ld,需要在他们前面加 -Wl,字串。--whole-archive 可以把 在其后面出现的静态库包含的函数和变量输出到动态库,--no-whole-archive 则关掉这个特性。
比如你要把 liba.a  libb.a libc.a 输出到 libabc.dll(或libabc.so)时应该这么写:
libabc.dll:liba.c libb.a libc.a
       gcc  -shared -o $@ -L. -Wl,--whole-archive -la -lb -lc -Wl,--no-whole-archive
在--whole-archive作用下的库里不能有函数同名


gcc 编译命令
-c, (compile)只编译生成中间同名目标文件,不链接
-o,(output)指定输出文件名,该文件为可执行文件,不加-o会默认生成a.out


LD  命令

-Ttext 连接时将初始地址重定向

$(LD) -Ttext=0x7c00 -o $(OBJDIR)/mbr $(OBJDIR)/mbr_start.o $(OBJDIR)/mbr.o

-Ttext是连接时将初始地址重定向为0x7c00(若不注明此,则程序的起始地址为0)。比如,在mbr_start.S文件中函数inb()的编译完成后在mbr_start.o中的偏移地址是0x006b,则在连接时指定-Ttext=0x7c00,连接之后其地址为0x7c6b, 其他函数调用此函数时,也就会调用地址0x7c6b,而不会是0x006b

-O 开启编译优化 -O1 -O2 -O3 数字表示可选优化级别 
-D 宏定义 当你想要通过宏控制你的程序,不必傻乎乎的在程序里定义,然后需要哪个版本,只需要在执行gcc的时候,指定-D,后面跟宏的名称即可
-g 可执行程序包含调试信息 -g为了调试用的 加个-g 是为了gdb 用,不然gdb用不到
-G  SIZE, --gpsize SIZE //数据大小(如果没有大小,与 --shared 相同)
-h filename //设置共享库的内部名称
-I PROGRAM, -dynamic-linker PROGRAM //将 PROGRAM 设置为要使用的动态链接器
-I libname , --library LIBNAME //搜索库目录
-L DIRECTORY,--library-path 目录
                              将 DIRECTORY 添加到库搜索路径
-w 关闭编译时的警告,也就是编译后不显示任何warning,因为有时在编译之后编译器会显示一些例如数据转换之类的警告,这些警告是我们平时可以忽略的
-W 会显示警告,但是只显示编译器认为会出现错误的警告。
-Wall 编译后显示所有警告


--section-start
-(, --start-group //开始一个组
  -), --end-group //结束一个组


 

一、-g
-g可执行程序包含调试信息
-g为了调试用的
加个-g 是为了gdb 用,不然gdb用不到

二、-o
-o指定输出文件名
-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
一般语法:
gcc filename.c -o filename
上面的意思是如果你不打 -o filename(直接gcc filename.c )
那么默认就是输出a.out.这个-o就是用来控制输出文件的。 ------用./a.out执行文件

三、-c
-c 只编译不链接
产生.o文件,就是obj文件,不产生执行文件

四、-D
其意义是添加宏定义,这个很有用。

当你想要通过宏控制你的程序,不必傻乎乎的在程序里定义,然后需要哪个版本,去修改宏。

只需要在执行gcc的时候,指定-D,后面跟宏的名称即可。

示例:

gcc test.c -o test -D OPEN_PRINTF_DEBUG

或者gcc test.c -o test -DOPEN_PRINTF_DEBUG

两者都是可以的。

五、-w
-w的意思是关闭编译时的警告,也就是编译后不显示任何warning,因为有时在编译之后编译器会显示一些例如数据转换之类的警告,这些警告是我们平时可以忽略的。

六、-W和-Wall
-W选项类似-Wall,会显示警告,但是只显示编译器认为会出现错误的警告。

-Wall选项意思是编译后显示所有警告

七、-O3
-O是大写字母O,不是数字0哦。

意思是开启编译优化,等级为三。

八、-shared
如果想创建一个动态链接库,可以使用 gcc的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。

九、-fPIC
-fPIC 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code)
这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

十、-l (小写的l)参数和-L (大写的l)参数
gcc编译程序时,可能会用到“-I”(大写i),“-L”(大写l),“-l”(小写l)等参数,下面做个记录。
例1:
例2:

-l(小写的l)参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?
就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。

好了现在我们知道怎么得到库名了,比如我们自已要用到一个第三方提供的库名字叫libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件)。放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了。
但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它放在/usr/X11R6/lib目录下,我们编译时就要用-L /usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest

十一、Linux-(C/C++)动态链接库生成以及使用(libxxx.so)
编译结果:生成libmax.so
运行结果:生成可执行程序main(成功了)(这里编译使用的是相对路径)
接下来,使用绝对路径编译main(在我自己编译):


使用C++编译使用C语言提供的链接库, 编译链接出错(下面只是简单将main.c 改为main.cpp)
怎么办呢??

libmax这个库仅适合C使用,C++并不适合,如果想编译一个可以供C++使用。那么头文件(max.h)就需要改变,

需要额外增加一句:extern “C”

max.h(修改如下):

这样就解决了

但是这样有一个问题,难道每次编译都要改来改去,有没有同时适合C/C链接库的方法呢?
答案是有的,只需要改动头文件即可,使用条件编译
C++有一个宏:__cpluscplus 当用g++编译的时候,就可以识别这个宏

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值