gcc 编译和makefile技巧

GCC调试参数

-E        预处理,宏展开。
-P        。
-M  生成文件关联的信息。包含目标文件所依赖的所有源代码。
-c   编译的时候阻止链接命令,仅仅生成*.o中间文件  gcc -o simple.o  -c simple.c
-M  生成文件关联的信息。包含目标文件所依赖的所有源代码。
-v  在链接的时候,显示详细的信息。

Makefile 调试参数
make -p
  和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。

假设有文件simple.c:
!!!宏展开,预处理 -E -P, 这个对于想要了解代码的内容太重要了
gcc -E -P simple.c
gcc -E simple.c                #将会生成更多的内容,对于阅读不方便,加上'-P'就可以屏蔽这些内容
假设包含了 
#include <netinet/tcp.h>
展开后,选项可以看到展开后的代码,-E选项还会提示include头文件的绝对地址,-E -P会省略
# 29 "simple.c" 2
# 1 "/usr/include/netinet/tcp.h" 1 3 4
# 92 "/usr/include/netinet/tcp.h" 3 4
struct tcphdr
  {
    u_int16_t source;
    u_int16_t dest;
    u_int32_t seq;
    u_int32_t ack_seq;
。。。

依赖头文件:

gcc -M simple.c

gcc -MD simple.c              #将生成simple.d 文件

-M
  生成文件关联的信息。包含目标文件所依赖的所有源代码
  
-MM
  和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。
  
-MD
  和-M相同,但是输出将导入到.d的文件里面
  
-MMD
  和-MM相同,但是输出将导入到.d的文件里面

Makefile:

定义一个需要的宏,传递到子目录中:

ADDED_FLAGS += -g

export ADDED_FLAGS

我们定义makefile文件:
ifeq ($(VERBOSE),)
SILENCE=@echo "building: "$@ ;
else
SILENCE=
endif

再规则中:
all:test.o
     $(SILENCE) gcc -o prj test.o

这样如果在编译时,输入:make, 就不会打印 gcc -o prj test.o
输入:make VERBOSE=aa 就会打印                       

变量:

准确来说是make的内置变量,比如:CURDIR, SHELL等,不需要赋值,可以直接输出结果

echo $(CURDIR)

Link:

http://blog.sina.com.cn/s/blog_87edb138010172d6.html

如何知道这些变量的值呢?

make -p

输出当前Make的内部数据库,大家可以查到CURDIR等值。

make --debug=v/a/b

常用v进行调试

输出变量信息:

在任何文件加上:

$(error problem $(Var))

就会输出变量$(Var)的结果,同时停止编译

subst 替换

$(subst \,/,$(WIND_BASE))

因为在windows下文件分隔符和Linux正好相反,需要进行替换,否则在Windows运行可能导致错误

调试手段:引用:https://coolshell.cn/articles/3790.html

VARS.MK

1

2

3

4

5

6

7

8

%:

        @echo '$*=$($*)'

d-%:

        @echo '$*=$($*)'

        @echo '  origin = $(origin $*)'

        @echo '   value = $(value  $*)'

        @echo '  flavor = $(flavor $*)'

以下部分内容忽略,仅仅给自己用于复习和记忆

make -p这个选项输出非常多,但是是一个很好的调试方法
为了输出到屏幕和文件中,执行:  make -p 2>&1 | tee log.txt
每进入一个目录,这个目录下包含Makefile,那么就会产生一部分新的内容
每一个部分,前面是

#=====  离开前一个目录
# make[3]: Leaving directory `/home/netgear/WNDR3700v4_src/package/ookla'
#=====  准备进入新的目录
# GNU Make 3.81
# Copyright (C) 2006  Free Software Foundation, Inc.
。。。。。。
# make[3]: Entering directory `/home/netgear/WNDR3700v4_src/package/openssl'
# XXX: OpenSSL "make depend" will look for installed headers before its own,
#=====  如果没有-p 选项,这些内容也会输出
make V=99  -j1 clean-staging               
make[4]: Entering directory `/home/netgear/WNDR3700v4_src/package/openssl'
rm -f /home/netgear/WNDR3700v4_src/staging_dir/target-mips_uClibc-0.9.30.1/stamp/.openssl_installed
make[4]: [clean-staging] Error 123 (ignored)
make[4]: Leaving directory `/home/netgear/WNDR3700v4_src/package/openssl'
make -C /home/netgear/WNDR3700v4_src/build_dir/target-mips_uClibc-0.9.30.1/openssl-1.0.2o MAKEDEPPROG="mips-openwrt-linux-uclibc-gcc" OPENWRT_OPTIMIZATION_FLAGS="-Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -fpic"  depend
make[4]: Entering directory `/home/netgear/WNDR3700v4_src/build_dir/target-mips_uClibc-0.9.30.1/openssl-1.0.2o'


#=====  打印整个Makefile文件展开后的信息,包括所有变量,和执行命令 Make data base 做为开始的标识
# Make data base, printed on Tue Jul 24 15:46:36 2018

# Variables

# makefile (from `/home/netgear/WNDR3700v4_src/include/quilt.mk', line 223)
Build/Quilt = $(call Quilt/Template,$(PKG_BUILD_DIR),,,$(if $(TARGET_BUILD),Kernel,Package))
# makefile (from `Makefile', line 10)
PKG_NAME := openssl
# makefile (from `/home/netgear/WNDR3700v4_src/.config', line 1251)
CONFIG_PACKAGE_wide-dhcpv6-control = y
 

可以搜索all:等关键字,查看Makefile的编译策略










 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值