c++ - 为什么使用 Make 3.8.1 构建与使用 Make 4.1 不同?

标签 c++ gcc makefile

我正在使用带有 C++ 的 gcc 构建一个嵌入式 ARM 项目:

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: ***

使用 ver 4.1,'cc' 不显示,但只有 GCC 在那里。

重点是:

在版本 3.8.2 Gnu make 中,变量 'HOSTCC' 在 sub:recipe 中没有被覆盖, 即使它是在命令行中指定的。

( 我在构建 u-boot 时注意到了这个现象。 有关“Makefile 重制”的更多信息, 请参阅 make 手册“3.5 如何重制 Makefile”。)

这个差异似乎来自ver 3.8.2 gnu make's main.c(line 2091)。

在 ver 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.
}

关于c++ - 为什么使用 Make 3.8.1 构建与使用 Make 4.1 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34991119/

相关文章:

c++ - Qt Json 解析 C++

c++ - 为什么使用 string::iterator 而不是索引?

c - 不完整数组类型的 p[0] 和 *p 等价

makefile - 我需要帮助减少 makefile 中的依赖项

c++ - 显示 Windows 用户对话框

c++ - C/C++ : "for" macro to track loops which are running many iterations

c++ - 为什么 std::remove 不能与 std::set 一起使用?

c++ - 代码编译,但没有控制台输出

linux - 如何使用 `make` 创建最终的可执行文件?

linux - 典型的 ./configure 在 Linux 中做了什么?