如何使依赖生成工作的C? (另外..解码这个sed/make语句!)

问题描述:

我有一个make build系统,我试图破译别人写的。当我在Redhat系统上运行时出现错误,但在我的solaris系统上运行时出现错误。 gmake的版本是相同的主版本(小版本中的一版)。如何使依赖生成工作的C? (另外..解码这个sed/make语句!)

这对于建立一个C项目,并且使系统具有由每个目录的本地的Makefile继承

的Makefile.global在它所有的目标,开始与

全球Makefile.global
all: $(LIB) $(BIN) 

全局文件还具有以下行

ifndef INCLUDE_GEN_DEPS 
sinclude $(GEN_DEPS) 
endif 

,其中lib构建库和BIN建立二进制文件。

跳下目标我有

$(LIB) : $(GEN_LIB) 

$(GEN_LIB) : $(GEN_DEPS) $(GEN_OBJS) 
     $(AR) $(ARFLAGS) $(GEN_LIB) $(GEN_OBJS) 
$(GEN_DEPS) : 
     @set -e; rm -f [email protected]; \ 
     $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename [email protected] | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o [email protected] :,g' > [email protected] ; \ 
     cat [email protected] > [email protected] ; \ 
     cat [email protected] | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> [email protected] ; \ 
     rm [email protected] 
    $(GEN_OBJS) : 
     $(CC) $(CFLAGS) $(INCDIRS) -c $(*F).c -lmpi -o [email protected] 

我觉得这些都是我需要包括回答我的问题有关的目标。这些变量的

定义:

CC = icc 
CDEP_FLAG = -M 
CFLAGS = various compiler flags ifdef type flags 
INCDIRS = include directory where all .h files are 
GEN_OBJDIR = /lib/objs 
HOME_SRC = . 
GEN_LIB = lib/$(LIB) 
GEN_DEPDIR=/lib/deps 
GEN_DEPS = $(addprefix $(GEN_DEPDIR)/,$(addsuffix .d,$(basename $(OBJS)))) 

我觉得这已经涵盖一切你所需要的。从名字基本上可以看出来。

现在尽我所能,这是在/ lib/deps中生成一个.d文件,该文件具有对象和源依赖关系。换句话说,对于utilities.a库,我将得到一个utils.o和utils.c依赖堆栈,全部在文件utils.d中

这个文件中正在产生一些语法错误,我认为,因为我得到以下错误:

../lib/deps/util.d:25: *** target pattern contains no '%'. Stop. 
gmake[2]: *** [all] Error 2 
gmake[1]: *** [all] Error 2 
gmake: *** [all] Error 2 

我不知道如果我的错误是在依存产生,或者一些进一步下跌的一部分,就像对象生成目标?

如果您需要进一步的信息,让我知道,我会添加后

+0

您是否试过用'-d'选项运行gmake来查看它在做什么? – 2010-05-26 18:49:15

比较什么被写入的lib/DEPS/util.d您的工作(Solaris)上机非工作(红帽) ,特别注意第25行。这可能会给你一个很好的提示,说明发生了什么问题。

如果它们相同,则问题是一次性制作次要版本。

如果情况不同,问题可能是正在运行的工具或安装了不同版本的ICC(更可能)之间的某些区别。

编辑

解码规则来实现:

$(GEN_DEPS) : 
     @set -e; rm -f [email protected]; \ 
     $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename [email protected] | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o [email protected] :,g' > [email protected] ; \ 
     cat [email protected] > [email protected] ; \ 
     cat [email protected] | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> [email protected] ; \ 
     rm [email protected] 

这条规则使得$(GEN_DEPS)的相关文件,其对应于具有.c所有源文件更改为.d

@set -e; rm -f [email protected]; 

导致任何错误立即退出此规则具有故障,而不是继续,并删除我们即将目标再生对应于我们试图用旗帜来自动生成依赖生成.D文件.c文件

$(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename [email protected] | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o [email protected] :,g' > [email protected] ; 

运行ICC而不是编译。 basename [email protected] | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,' 子句正在将.d名称翻译回.c名称。

将输出(这是depdendency规则)传递给sed脚本sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o [email protected] :,g',该文件将依赖项文件本身添加为依赖于icc为依赖的.o(对象)文件找到的所有内容。将所有这些写入临时文件。

cat [email protected] > [email protected] ; 

将临时文件复制到输出依赖文件。

cat [email protected] | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> [email protected] ; 

附加的依赖关系的第二拷贝到依赖文件,通过该剥去目标,使第一报头到目标一点脚本修改。因此,这是为源文件中出现的第一个头文件添加一组附加依赖项。

rm [email protected] 

删除临时文件。

+0

我会检查一下。我没有想到编译器生成依赖关系的可能性不同。我实际上在solaris系统上使用cc(这是SGI MIPS) – Derek 2010-05-26 19:03:57

+0

这几乎肯定是问题所在 - 不同的编译器倾向于使用不同的标志来生成依赖关系,并以稍微不同的方式生成它们,这会导致sed命令出现问题在makefile中。 – 2010-05-26 19:14:00

+0

太好了。我会去检查差异,看看发生了什么。你认为解决这个问题的最好方法是什么?为每个平台制定一套不同的制定规则?我认为我们将从现在开始主要坚持使用intel架构(使用icc),但是它们总是有机会被移植到其他地方。 – Derek 2010-05-26 19:29:23