我有一个看起来有点像这样的GNU Makefile:
LIST = item1
.PHONY: targetMain targetA targetB preA preB
targetMain:
# DO all the work in here
echo $(LIST)
targetA: preA targetMain
targetB: preB targetMain
preA:
LIST += itemA
preB:
LIST += itemB
Run Code Online (Sandbox Code Playgroud)
我的想法是运行make targetA或make targetB.他们两个都做了非常类似的事情,但有一个不同的项目列表.问题是变量没有有条件地附加到,它总是附加到,这意味着我的输出始终是"item1 itemA itemB".
我如何有条件地附加到变量?
我正在编写的程序的要求是它必须能够信任配置文件.为了实现这一点,我使用几种散列算法在编译时生成文件的散列,这会产生一个散列为常量的标头.
对此的依赖非常简单,我的程序依赖于config_hash.h,它有一个生成它的目标.
makefile看起来像这样:
config_hash.h:
$(SH) genhash config/config_file.cfg > $(srcdir)/config_hash.h
$(PROGRAM): config_hash.h $(PROGRAM_DEPS)
$(CC) ... ... ...
Run Code Online (Sandbox Code Playgroud)
我正在使用gcc的-M选项,这对于处理依赖项非常有用.如果我的标题更改,我的程序将重建.
我的问题是,我需要能够判断配置文件是否已更改,以便重新生成config_hash.h.我不太确定如何解释这种对GNU的依赖.
我已经尝试将config/config_file.cfg列为config_hash.h的依赖项,并.PHONY为config_file.cfg 提供目标但没有成功.显然,我不能依赖-M开关来帮助我,因为配置文件不是任何目标代码的一部分.
有什么建议?不幸的是,我不能发布很多Makefile,或者我只是发布了整个内容.
是否可以将GNU make配置为仅显示错误.make --no-print-directory抑制所有输入/离开消息.同样我不想看到" make[4]: Nothing to be done for install.".只是构建错误.
谢谢.
所以我有一个变量:
PROGS = element0 \
element1
Run Code Online (Sandbox Code Playgroud)
我有每个变量:
element0_SRCS = src/xxx.c src/q.c
element1_SRCS = src/xxx.c src/z.c
Run Code Online (Sandbox Code Playgroud)
如果我有另一组变量,那么我可以很容易地做我想做的事情:
element0_OBJS = src/xxx.o src/q.o
element1_OBJS = src/xxx.o src/z.o
ALL_PROGS = $(foreach p, $(PROGS), $(p)_prog)
all : $(ALL_PROGS)
.SECONDEXPANSION:
%_prog : $$($$*_OBJS)
gcc - blah blah
Run Code Online (Sandbox Code Playgroud)
但是,我想消除"_OBJS"变量的需要并使用_SRCS变量.我可以用每个编程做这个人:
element0_prog : $(element0_SRCS:.c=.o)
Run Code Online (Sandbox Code Playgroud)
尽管使用第二次扩展来重新创建%_prog规则的各种尝试都失败了.
$$($$*_SRCS:.c=.o) ==>目标模式不包含'%'
$$(patsubst %.c,%.o,$$($$*_SRCS)) ==>使用.c文件而不是.o文件构建目标.
在这里几乎不知所措.
球队,
我有一个环境变量,我希望在编译该特定项目时未定义/取消设置,然后启用它.
我试过使用..下面的代码..
ifdef ${ENV_VAR_TEST}
undefine ${ENV_VAR_TEST}
endif
但我仍然看到它在编译环境中反映出来......这些是未定义/取消设置变量的正确步骤吗?我在这里错过了一些基础知识.
谢谢你的时间 .
我想利用MALLOC_PERTURB_环境变量来更改内存分配参数(man 3 mallopt)。但是,我想在应用程序级别而不是整个系统级别上控制分配参数。理想情况下,如果我可以通过项目的makefile控制它们。我试图通过makefile更改提到的变量,但是没有成功。
为了进行测试,我创建了这个test.c文件:
#include<stdlib.h>
#include<stdio.h>
#define N 50
int main()
{
char *chars;
int i;
if (NULL == (chars = malloc(N * sizeof(*chars))))
return EXIT_FAILURE;
free(chars);
for (i = 0; i < N; ++i)
printf("%c", chars[i]);
printf("\n");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
是的,我知道我正在从释放的内存中进行读取,但这是使用MALLOC_PERTURB_的全部重点。
预期结果:50个字符的ASCII字符,值MALLOC_PERTURB_。
足够近:
$ export MALLOC_PERTURB_=97
$ gcc test.c -o test
$ ./test
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa??
$ export MALLOC_PERTURB_=105
$ gcc test.c -o test
$ ./test
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii??
Run Code Online (Sandbox Code Playgroud)
然后,我尝试将编译包含在makefile中,但没有成功。
导出变量 (如此处建议)
生成文件
all:
export MALLOC_PERTURB_=110
gcc test.c -o test
Run Code Online (Sandbox Code Playgroud)
结果(我期望110个字母为n)
$ export …Run Code Online (Sandbox Code Playgroud) 我的C++ 03项目需要升级到C++ 11,我可以保证在我想要使用的所有GCC中至少可以获得对它的实验性支持.
但是,这可能是-std=c++0x或者可能-std=c++11来自较新的GCC.有一天它会-std=c++14(当CentOS赶上......).
我如何形成一个GNU Makefile,CXXFLAGS根据哪个成功添加"最佳"标志?
我可以说"好吧,我使用的最早的GCC仍然没有生产就绪的C++ 11支持所以我应该坚持使用C++ 03",但是,好吧.
我查看了GNU Makefile条件语句的文档,但是找不到有关如何有条件地构建目标及其依赖项的任何信息。
编辑:当我有条件地说时,我的意思是依赖于在调用make时在命令行中设置的变量值。抱歉,您没有早点说明。
要添加到上面的编辑。如果在命令行中设置的某些变量具有特定值,即使需要更新目标及其依赖项,我也要避免这样做。
谢谢!
我的Makefile中有一条规则大致如下所示:
target_file: src_file
some_tool src_file > target_file
Run Code Online (Sandbox Code Playgroud)
(当然,在现实中我使用$@和$<,但对于这个问题,我更喜欢一个更明确的风格.)
问题是target_fileshell始终使用新的时间戳创建,即使some_tool失败也是如此.在这种情况下,target_file存在空,即使我修复了底层问题,在我手动删除target_file或触摸之前也不会重建它src_file.
此外,some_tool只写入标准输出,所以我不能通过更清洁的方法来解决这个问题some_tool ... -o target_file.
我目前的方法是删除
target_file: src_file
some_tool src_file > target_file || rm -f target_file
Run Code Online (Sandbox Code Playgroud)
但是,这有一个缺点,即Make如果some_tool失败则不会注意到,因为在那种情况下rm接管并返回exitcode 0(成功).
另一种方法可能是:
target_file: src_file
some_tool src_file > target_file.tmp
mv target_file.tmp target_file
Run Code Online (Sandbox Code Playgroud)
但是这种代码很乏味,而且在失败时会留下令人讨厌的文件target_file.tmp.
有没有更优雅的方法来解决这个问题?
从我的角度来看,我有一个相当复杂的Makefile。
这主要是因为我想在那里添加颜色和其他不必要的东西。
无论如何,我可以跳进我的问题:
除了Linux,我最近还支持* BSD,因此我需要检查在多个地方使用的平台。Makefile中可以进行条件变量赋值吗?就像是:
platform := [ $$(uname) = Linux ] && echo Linux || echo BSD or other
Run Code Online (Sandbox Code Playgroud)
当然这是行不通的,但是希望您能理解我的意思。
我需要一个可以与BSD make和GNU 一起使用的解决方案make。