为什么使用 Make 3.8.1 构建与使用 Make 4.1 构建不同
Why is building with Make 3.8.1 different to Make 4.1?
我正在使用gcc
构建一个嵌入式ARM项目,C++:
11:01:29 ○⨠ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 224288]
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
并制作:
17:11:17 ○⨠ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
我正在构建一段最近的代码,它根本不适合我 - 代码构建和部署得很好,但功能却不存在。Tt没有任何意义,因为代码看起来完全没问题。
一位同事和我一起审查了它,我们发现代码没有问题,所以为了笑,我们决定让他构建和部署它。
它工作正常!
所以检查我们的版本,他正在运行make 4.1
.我升级到这个,嘿,presto,它工作正常。
11:06:15 ○⨠ make --version
GNU Make 4.1
Built for x86_64-apple-darwin14.3.0
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
我们又玩了3.81
,并推断出优化可能是问题所在。
但这两个实例都-Os
传递给gcc
.
所以,我的问题是 - 为什么Make
会对这里的编译器产生影响?!
当
发生"Makefiles remade"时,Gnu make 在版本 3.8.2 和 4.1 之间的行为略有不同。例如,执行以下逗号:
----- commands ----
rm ./sub.mk ./add_rule ; make -f test.mk HOSTCC=GCC
----- test.mk -----
$(info ===== test.mk(lv $(MAKELEVEL)) ==== )
$(info origin=$(origin HOSTCC))
HOSTCC = cc
$(info HOSTCC=$(HOSTCC))
$(info ------------------ )
.PHONY: all sub sub2
all:
@echo "... build $@ ..."
touch ./add_rule
@echo "*** using HOSTCC=$(HOSTCC) at all: ***"
$(MAKE) -f ./test.mk sub
@echo "*** using HOSTCC=$(HOSTCC) at all: ***"
sub:
@echo "... build $@ ..."
@echo "*** using HOSTCC=$(HOSTCC) at sub: ***"
-include sub.mk
ifneq ($(wildcard ./add_rule),)
sub.mk:
@echo "... build $@ ..."
echo "$$$ (info --- $@(included) ---)" > $@
endif
----- end of test.mk -----
使用 Ver 3.8.2 Gnu Make,控制台输出的最后几行是:
....
===== test.mk(lv 1) ====
origin=environment
HOSTCC=cc
------------------
--- sub.mk(included) ---
make[1]: Entering directory `/home/user/make-test'
... build sub ...
*** using HOSTCC=cc at sub: ***
make[1]: Leaving directory `/home/user/make-test'
*** using HOSTCC=GCC at all: ***
使用版本 4.1,"cc"不显示,但只有 GCC 在那里。
关键是:
在版本 3.8.2 Gnu make 中,变量 'HOSTCC' 在 sub:recipe 中没有被覆盖, 即使在命令行中指定。
(我在构建 u-boot 时注意到了这种现象。 有关"重新制作文件"的更多信息, 请参阅制作手册"3.5 如何重新制作生成文件"。
这种差异似乎来自版本 3.8.2 gnu make's main.c(第 2091 行)。
在版本 4.1 代码中,putenv() 不存在。
/* Reset makeflags in case they were changed. */
{
const char *pv = define_makeflags (1, 1);
char *p = alloca (sizeof ("MAKEFLAGS=") + strlen (pv) + 1);
sprintf (p, "MAKEFLAGS=%s", pv);
putenv (p); //<<=== the different point.
}
相关文章:
- 防止 GNU Make 在每次构建时生成 protobuf 代码
- 将 make 和 cmake 合并到构建系统中
- 使用 CMake (make) 和 GCC 构建和编译 gSOAP 项目
- 如何在bazel中使用make规则链接库构建
- 每次都构建(make)lib,只有在lib较新时才重新编译项目
- "无法确定要运行哪个"make"命令.检查构建配置中的"make"步骤
- 修复了安装 OSRM 时使用"make"命令时的构建问题
- QT make在构建时有很大的输出
- 使用MINGW-MAKE构建OpenCV 3.3在47%时给出错误2
- 如何构建库并将其与Make链接在一起
- gcov,make,cmake,ctest覆盖构建
- 使用qt构建qt-make项目时出错
- 最小的GNU Make构建系统
- 为什么使用 Make 3.8.1 构建与使用 Make 4.1 构建不同
- 用于构建提升的'stage'参数:"don't know how to make <e>stage"
- 构建C++项目的正确方法是什么?Make/IDE/Ant.
- 使用GCC make管理调试和发布构建
- DistCC和CMake-运行make时在本地构建和分布式构建之间进行选择
- 隐式构建规则:GNU Make Multiple Makefiles Multiple Directories
- GNU make: Makefile一次构建多个.cpp文件