我有一组c ++文件,我使用make -j命令在不同的机器上编译。只有当我将pgi编译器与并行make一起使用时才会出现问题,对于某些文件我会收到以下错误(此特定错误适用于 atprop.cpp 文件):
/opt/share/gcc/4.6.0/el6/bin/ld: error in atprop.o(.eh_frame); no .eh_frame_hdr table will be created.
/opt/share/gcc/4.6.0/el6/bin/ld: atprop.o: invalid string offset 615811912 >= 1421 for section `.strtab'
/opt/share/gcc/4.6.0/el6/bin/ld: final link failed: Nonrepresentable section on output
我意识到,与许多可执行目标相关的源文件会出现此错误。例如, atprop.cpp 使用我在代码中使用的不同宏(无宏,-DUBC,-DVBC)编译三次。这是与 atprop.cpp
相关的Makefile的一部分 $(B)/atprop: $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o
$(CPPC) $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o -o $@ $(INC) $(FLAGSET2)
$(B)/atprop_ubc: $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o
$(CPPC) $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o -o $@ $(INC) $(FLAGSET2) -DUBC
$(B)/atprop_vbc: $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o
$(CPPC) $(S)/atprop.cpp $(O)/atlib.o $(O)/atwave.o $(O)/atvecop.o -o $@ $(INC) $(FLAGSET2) -DVBC
变量$(CPPC)= mpic ++,它等于PGI编译器的MPI包装器的路径。
$ mpic++ --version
pgcpp 12.10-0 64-bit target on x86-64 Linux -tp bulldozer
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2012, STMicroelectronics, Inc. All Rights Reserved.
请注意,如果我使用serial make(即没有-j选项的make),编译运行顺利没有问题。
我认为这是问题:PGI编译器创建一个与源文件同名的临时对象文件(对于上面的示例 atprop.o 。如果并行运行,使用不同的宏进行编译将所有写入同一个目标文件,这会导致我上面提到的问题。
这只发生在PGI编译器上,当我使用intel或gnu编译器时,我不会遇到这个问题。所以我的问题是我可以做些什么来缓解PGI编译器的这个问题?请记住,我有很多具有相同问题的c ++文件,我试图避免对Makefile进行重大修改。
答案 0 :(得分:1)
要确定您对PGI编译器正在执行的操作的猜测是否正确,您可以尝试使用strace
(可能使用-ff
和{{1从命令行手动运行)标记,并查看它创建的文件。
如果您确定是这个问题,那么您应该做的第一件事是查看PGI文档和/或在他们的支持论坛上询问是否有可以添加的编译器选项会改变这种行为或环境你可以设定的变量。
如果这些都不起作用,那么你就处于一个受伤的世界。一个简单的答案是在编译之前更改make规则以将源复制到唯一名称,但这会破坏调试它的能力(因为调试器编码的源文件将是一些随机文件名)。我能想到的任何更改都会对makefile进行非常重大的更改(例如,为从同一来源构建多个文件的规则添加仅限订单的先决条件)。
你的makefile似乎只是简单的明确规则列表,这太糟糕了;如果您使用较少数量的隐式规则,则修复makefile会更容易。
答案 1 :(得分:1)
为了快速解决方法,我在Makefile中的目标之间做了假依赖。这样我就可以避免同时编译同一个源文件(针对不同的目标)。