我们为我们的系统使用GNU Make.在我们的makefile文件的末尾,我们有一个名为Makedepends的包含,它使用gcc上的-MM开关生成一堆.d文件.然后,我们使用include $(CXXFILES:.cc = .d)行为每个.cc文件包含.d文件.但是当我们删除文件或移动文件时,依赖性步骤会中断,我们必须手动删除.d文件(即使make clean也不起作用,因为依赖项失败)
有没有办法生成这些依赖.d文件或包含这些依赖.d文件,它们将优雅地处理文件删除或重定位?
编辑:例如:我有serial.cc和makefile生成一个serial.d文件,它依赖于buffer.h,但后来我改变它,所以我不再需要buffer.h,我删除buffer.h.下次我运行make时,它会阻塞,因为它包含.d文件仍然使serial.o依赖于buffer.h.
我正在尝试为我的Makefile创建一个通用的构建模板,就像他们在eval文档中讨论的那样.
我遇到了GNU Make 3.80的已知错误.当$(eval)计算超过193个字符的行时,使用"虚拟内存耗尽"错误导致崩溃.
我的代码导致问题看起来像这样.
SRC_DIR = ./src/
PROG_NAME = test
define PROGRAM_template
$(1)_SRC_DIR = $$(SRC_DIR)$(1)/
$(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c)
$(1)_OBJ_FILES = $$($(1)_SRC_FILES):.c=.o)
$$($(1)_OBJ_FILES) : $$($(1)_SRC_FILES) # This is the problem line
endef
$(eval $(call PROGRAM_template,$(PROG_NAME)))
Run Code Online (Sandbox Code Playgroud)
当我运行这个Makefile时,我明白了
gmake: *** virtual memory exhausted. Stop.
Run Code Online (Sandbox Code Playgroud)
预期的输出是./src/test/中的所有.c文件都被编译成.o文件(通过隐式规则).
问题是$$($(1)_SRC_FILES)和$$($(1)_OBJ_FILES)长度超过193个字符(如果有足够的源文件).
我已经尝试在只有2个.c文件的目录上运行make文件,它工作正常.只有在SRC目录中有很多.c文件时才会出现错误.
我知道GNU Make 3.81修复了这个bug.不幸的是,我没有权限或能力在我正在研究的系统上安装新版本.我坚持3.80.
那么,有一些解决方法吗?也许拆分$$($(1)_SRC_FILES)并在eval中单独声明每个依赖项?
我正在OSX 10.6上以32位模式构建第三方库(该库是Xerces 2.8).我已确定__LP64__已设置预处理器定义.但是,据我所知,它没有被设置在第三方项目的任何配置文件中,并且通过所有文件(通过Finder)进行全局搜索#define __LP64__并没有向我显示这是由系统.
我通过make命令行构建库(不涉及Xcode).
我想知道在哪里__LP64__定义 - 以及它的目的是什么,因为我正在以32位模式构建项目.
考虑以下make:
all: a b
a:
echo a
exit 1
b:
echo b start
sleep 1
echo b end
Run Code Online (Sandbox Code Playgroud)
在make -j2我收到以下输出时运行它:
echo a
echo b start
a
exit 1
b start
sleep 1
make: *** [a] Error 1
make: *** Waiting for unfinished jobs....
echo b end
b end
Run Code Online (Sandbox Code Playgroud)
我们有一个很大的make文件,很容易错过错误,因为在执行结束时没有错误消息.
是否有一种方法可以在make执行结束时出现错误消息?
更新:
请参阅我的可能解决方案如何从make中检查make退出状态.
在FreeBSD上说,应用程序需要使用GNU make(gmake)编译,而不是标准系统make.是否有任何指令我可以放入Makefile停止执行它并在Makefile未使用gmake编译时打印错误?
我想告诉(g)make从单独的文件中包含一些常见的初始化,知道包含文件相对于主Makefile的相对位置.
但是在手册中我找不到任何内置变量,例如,它会为您提供当前Makefile的名称.
例如,如果我想将文件的内容包含在与当前make文件相同的目录中,而不是硬连接include的位置:
# MAIN Makefile : ./scripts/make/TaskA.mk
include ./scripts/make/Common.inc
...
Run Code Online (Sandbox Code Playgroud)
我想写下类似于_MAKEFILE_包含TaskA.mk位置的内容:
# MAIN Makefile : ./scripts/make/TaskA.mk
MAKEFILE_DIR=$(dirname $(_MAKE_FILE_))
include $(MAKEFILE_DIR)/Common.inc
Run Code Online (Sandbox Code Playgroud) 我试图实现一个简单的字符串比较来获取文件的类型(使用其扩展名),如下所示:
extract_pkg: $(PKG)
$(eval EXT := $(suffix $(PKG)))
@echo $(EXT)
ifeq ($(EXT), .zip)
@echo "is zip file"
else
@echo "is not a zip file"
endif
extract_pkg : PKG = mypkg.zip
Run Code Online (Sandbox Code Playgroud)
但是,当我运行它时,它会进入else分支.我的猜测是,它与点有关,但我没有找到解决方案.谢谢你的帮助 !
编辑1:基本代码实际上有点像以下,它按预期工作:
test_cmp:
ifeq (.zip,.zip)
@echo ".zip==.zip"
endif
ifeq (zip,zip)
@echo "zip==zip"
endif
Run Code Online (Sandbox Code Playgroud)
因此问题出在其他地方!
make 继续构建并说当我的依赖文件说对象依赖于已移动的头文件时,一切都是最新的.
如果运行make -d以捕获评估,我看到:
Considering target file `../build/out/src/manager.o'.
Looking for an implicit rule for `../build/out/src/manager.o'.
No implicit rule found for `../build/out/src/manager.o'.
Pruning file `../product/build/config/product.conf'.
Pruning file `../build/out/opt_cc.txt'.
Considering target file `../mem/src/manager.c'.
Looking for an implicit rule for `../mem/src/manager.c'.
No implicit rule found for `../mem/src/manager.c'.
Finished prerequisites of target file `../mem/src/manager.c'.
No need to remake target `../mem/src/manager.c'.
Pruning file `../mem/mem.h'.
Finished prerequisites of target file `../build/out/src/manager.o'.
Prerequisite `../product/build/config/product.conf' is older than target `../build/out/src/manager.o'.
Prerequisite `../build/out/opt_cc.txt' is older than target …Run Code Online (Sandbox Code Playgroud) 我使用以下简单的Makefile来构建一些简单的文件.我是制作Makefile的新手.我不知道为什么它继续重建,即使文件是在第一次制作之后构建的,而我不是在编辑任何文件.
EXE = nextgenrsm
CC = gcc
LIBS = StarterWare_Files/
CFLAGS = -c
INCLUDE_PATH = StarterWare_Files/
MAIN_SRC = $(wildcard *.c)
MAIN_OBS = $(patsubst %.c,%.o,$(MAIN_SRC))
LIB_SRC = $(wildcard StarterWare_Files/*.c)
LIB_OBS = $(patsubst StarterWare_Files/%.c,%.o,$(LIB_SRC))
output: $(EXE)
$(EXE): $(MAIN_OBS) $(LIB_OBS)
$(CC) $(MAIN_OBS) $(LIBS)$(LIB_OBS) -o $(EXE)
$(MAIN_OBS): $(MAIN_SRC)
$(CC) $(CFLAGS) *.c -I$(INCLUDE_PATH)
$(LIB_OBS): $(LIB_SRC)
cd $(LIBS); \
$(CC) $(CFLAGS) *.c -I../
clean:
rm -rf $(LIBS)*.o $(EXE) *.o
Run Code Online (Sandbox Code Playgroud)
新编辑的MAKEFILE
EXE = nextgenrsm
CC = gcc
LIBS = StarterWare_Files/
CPPFLAGS = _IStarterWare_Files/
MAIN_OBS = $(patsubst %.c,%.o,$(wildcard …Run Code Online (Sandbox Code Playgroud) 我有一个带有一些模式规则¹的make文件,最终成为另一个规则的先决条件.显示我困惑的症状的最小例子是:
.PHONY: clean default one two
default: clean one two
clean:
@rm -f {one,two}.{a,b}
one two: %: %.a %.b
@echo TARGET $@ PREREQUISITES $^
%.a %.b:
@echo Prereq $@
@touch $@
Run Code Online (Sandbox Code Playgroud)
运行它时我期望的输出是:
Prereq one.a Prereq
one.b
TARGET one PRACQUISITES one.a
one.b Prereq two.a Prereq
two.b
目标两个PREREQUISITES two.a two.b
相反,只有第一个先决条件被构建,make给我这个:
Prereq one.a
TARGET one PRACQUISITES one.a one.b Prereq
two.a
TARGET两个PREREQUISITES two.a two.b
正如您所看到的,配方本身正确地解析这些并知道它应该在两个先决条件之后构建,但实际上并未运行先决条件规则.
顺便说一下,我在这里使用第二项的仅订单先决条件,但这并不重要:同样的问题无论如何都表现出来.
如果我第二次运行相同的目标,那么它构建第二个先决条件.换句话说,两次传球最终得到了我需要的结果:
$ make clean
$ make one
Prereq one.a
TARGET one PREREQUISITES one.a one.b
$ …Run Code Online (Sandbox Code Playgroud) gnu-make ×10
makefile ×9
c++ ×1
compilation ×1
dependencies ×1
eval ×1
freebsd ×1
linux ×1
macos ×1