我想知道是否有一种方法可以trap在GNU中实现make,类似于内置的BASH?
如果用户按下CTRL-C,或者make自身失败(非零退出),我想调用特定目标或宏.
(GNU)make使用了几个变量,如:
CC - 默认情况下为C编译器 ccCFLAGS - C编译器的标志,默认为空我想在我的中指定一些我自己的默认值Makefile.在下面的示例中,我使用条件赋值运算符?=在运行时能够覆盖我的默认值make:
CFLAGS ?= CFLAGS_my_default
CC ?= CC_my_default
print:
echo CC=$(CC) CFLAGS=$(CFLAGS)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不会改变CC变量的值,因为原始默认值保持不变.CFLAGS由我的赋值设置,因为变量最初是空的:
$ make print
echo CC=cc CFLAGS=CFLAGS_my_default
CC=cc CFLAGS=CFLAGS_my_default
Run Code Online (Sandbox Code Playgroud)
从环境变量覆盖按预期工作:
$ CC=CC_from_env CFLAGS=CFLAGS_from_env make print
echo CC=CC_from_env CFLAGS=CFLAGS_from_env
CC=CC_from_env CFLAGS=CFLAGS_from_env
Run Code Online (Sandbox Code Playgroud)
如何更改变量的默认值,并且仍然可以在调用时覆盖它们make?
我们需要一些C++代码来创建一个make文件.每个.h和.C对创建一个对象,然后一些对象链接在一起形成一个可执行文件.很标准的东西.
这个非gnu make命令只是将所有文件构建到目录中的对象中
%.o:%.C
$(CC) $(CPFLAGS) -c $<
Run Code Online (Sandbox Code Playgroud)
这样做是为每个%.C文件(即每个.C文件)构建一个相应的.o文件.
有人知道如何使用gmake吗?
干杯
标记
在Make this flag中存在:
-l [load], - load-average [= load]指定如果有其他作业正在运行且负载平均值至少为load(浮点数),则不应启动新作业(命令).如果没有参数,则删除先前的加载限制.
您是否有一个很好的策略来确定负载限制的值?我的机器似乎差别很大.
所以我需要确保如果我为特定目标交叉编译设置了一个shell变量.如果未设置变量,则make应显示消息,然后退出.
我的Makefile中有以下规则:
.PHONY: checksource
all: checksource default
checksource:
$(if $(and $(ifeq ($(CROSS_COMPILE), whatever)), $(ifeq ($(VARIABLE),))), \
($(shell echo "Error! VARIABLE not defined!") \
$(shell exit 2)))
Run Code Online (Sandbox Code Playgroud)
如果$CROSS_COMPILE设置为任何:
$> echo $CROSS_COMPILE
whatever
$>
Run Code Online (Sandbox Code Playgroud)
并且未定义$ VARIABLE:
$> echo $VARIABLE
$>
Run Code Online (Sandbox Code Playgroud)
它不会退出make并构建默认目标.好吧,我知道我可以使用嵌套ifeq来做到这一点,但我想让它漂亮(并学习更多关于makefile).
我一直在设计一个多配置Makefile(一个支持单独的'debug'和'release'目标),并且遇到了一个奇怪的问题,这似乎是GNU make中的一个bug.
当隐式规则中引用这些变量时,GNU make似乎没有正确扩展特定于目标的变量.这是一个简化的Makefile,它显示了这个问题:
all:
@echo specify configuration 'debug' or 'release'
OBJS := foo.o bar.o
BUILDDIR = .build/$(CONFIG)
TARGET = $(addprefix $(BUILDDIR)/,$(OBJS))
debug: CONFIG := debug
release: CONFIG := release
#CONFIG := debug
debug: $(TARGET)
release: $(TARGET)
clean:
rm -rf .build
$(BUILDDIR)/%.o: %.c
@echo [$(BUILDDIR)/$*.o] should be [$@]
@mkdir -p $(dir $@)
$(CC) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
指定目标'debug'时,CONFIG设置为'debug',BUILDDIR和TARGET同样正确扩展.但是,在从对象构建源文件的隐式规则中,$ @被展开,就像CONFIG不存在一样.
以下是使用此Makefile的输出:
$ make debug
[.build/debug/foo.o] should be [.build//foo.o]
cc -c foo.c -o .build//foo.o
[.build/debug/bar.o] should be [.build//bar.o]
cc -c bar.c -o …Run Code Online (Sandbox Code Playgroud) 我有一个目录/ src包含我的所有源文件,/ bin用于在运行make命令后存储所有二进制文件.该目录如下所示:
/BuildDirectory
- - /src
- - /bin
- - configure
- - Makefile.am
- - configure.ac
- - ...
Run Code Online (Sandbox Code Playgroud)
现在在Makefile.am中,我必须指定:
bin_PROGRAMS = bin/x bin/y bin/z bin/k ...
bin_x_SOURCES = src/x.cpp
bin_y_SOURCES = src/y.cpp
bin_z_SOURCES = src/z.cpp
Run Code Online (Sandbox Code Playgroud)
是否有任何变量可以帮助摆脱所有"bin /"和"src /"?例如,我只需指定:
$BIN = bin
$SRC = src
Run Code Online (Sandbox Code Playgroud)
他们将在正确的文件夹中查找正确的文件并将其编译到正确的位置.
谢谢
我正在使用gmake并gcc -MM跟踪手册中的标题依赖项.该机制依赖于makefile include指令来导入计算的依赖项.
由于.d文件包含在makefile中,因此它们必须存在于任何目标中,包括clean.因此,在clean做正确的事情之前,必须生成依赖关系,如果一个人无法构建,那么就会clean变得更加混乱.
此外clean,它希望在构建任何目标之前创建所有依赖项.
此外,如果任何文件被更改为包含不存在的文件,则依赖关系解析会中断,并且根本不会构建任何文件.
如果删除了标头,那么现有的依赖项文件仍然将其命名为目标,并且在删除有问题的依赖项文件之前不会构建任何内容...这是无法完成的clean.
include用通配符替换替换模式以包含所有预先存在的依赖项文件可以解决一些问题,但它仍然无法清除损坏的依赖项,并且永远不会删除过时的依赖项文件.有更好的解决方案吗?该手册的示例是否真正用于实际用途?
你能帮我理解GNU Make(版本3.81)如何处理简单的Makefile吗?这是文件:
.PHONY: a b c e f
a : b c
@echo "> a(b,c)"
e : a
@echo "> e(a)"
e : f
@echo "> e(f)"
f :
@echo "> f()"
b :
@echo "> b()"
c :
@echo "> c()"
Run Code Online (Sandbox Code Playgroud)
现在我运行命令
make e
Run Code Online (Sandbox Code Playgroud)
建立'e'目标.Make的输出如下:
Makefile:7: warning: overriding commands for target `e'
Makefile:5: warning: ignoring old commands for target `e'
> f()
> b()
> c()
> a(b,c)
> e(f)
Run Code Online (Sandbox Code Playgroud)
http://www.gnu.org/software/make/manual/html_node/Error-Messages.html给出了下一个解释:
'警告:覆盖目标`xxx'的配方
'警告:忽略目标`xxx'的旧配方
GNU make只允许为每个目标指定一个配方(双冒号规则除外).如果为已经定义为具有目标的目标提供配方,则会发出此警告,第二个配方将覆盖第一个配方.
但是从输出中我们可以看到构建'a'目标的命令也被执行.我认为根据'Error-Messages'页面中的描述make,在处理这个Makefile并尝试构建'e'目标(make …
我有一个规则something,适用于变量VAR.我也有另一个规则something-all,需要运行something,以VAR设置为每个值vars.
vars = hello world
something:
echo $(VAR)
something-all:
$(foreach VAR,$(vars),something)
Run Code Online (Sandbox Code Playgroud)
我得到了这不太有效
noob@work:~/Desktop$ make something-all
something something
make: something: No such file or directory
make: *** [something-all] Error 1
Run Code Online (Sandbox Code Playgroud)
它应该打印hello\nworld.
我曾经通过检索VAR来通过通配符规则这样做%,但感觉这是错误的方法.这看起来像这样:
vars = hello world
all: $(foreach VAR,$(vars),something-$(VAR))
something-%:
echo $*
Run Code Online (Sandbox Code Playgroud)