我有一组c++文件,使用make命令在不同的机器上编译。只有在使用带有并行make的pgi编译器时,才会出现一个问题,一些文件会出现以下错误(此特定错误用于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、-DVBC)编译了三次。这是Makefile中与atprop.cpp相关的部分
$(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.请注意,如果使用串行make (即不使用-j选项的make ),编译运行平稳,没有任何问题。
我认为这就是问题所在: PGI编译器创建一个与源文件同名的临时对象文件(在上面的例子中是atpro.o)。如果并行运行,使用不同宏的编译都会写入同一个对象文件,这将导致前面提到的问题。
这只发生在PGI编译器上,当我使用英特尔或gnu编译器时,我不会面对这个问题。所以我的问题是,用PGI编译器我能做些什么来缓解这个问题呢?请记住,我有很多c++文件都有相同的问题,我试图避免对Makefile进行重大修改。
发布于 2013-12-18 12:41:14
要确定您对PGI编译器所做的猜测是否正确,可以尝试使用strace运行它(通过命令行手动运行),也许使用-ff和-o标志,并查看它创建了哪些文件。
如果您确定是这个问题,您应该做的第一件事是查看PGI文档和/或在它们的支持论坛上询问是否有编译器选项可以添加来改变这种行为,或者可以设置环境变量。
如果这些都不起作用的话,你就处在一个充满伤害的世界。一个简单的答案是在编译之前更改make规则将源复制到唯一的名称,但这会破坏调试它的能力(因为调试器编码的源文件将是一些随机文件名)。我所能想到的任何更改都将涉及到对makefile的非常重要的更改(例如,在从同一个源构建多个文件的规则中添加仅订单的先决条件)。
遗憾的是,makefile看起来只是一长串显式规则;如果您使用的隐式规则数量较少,那么修复makefile就更容易了。
发布于 2014-01-04 14:09:15
为了快速解决这个问题,我在Makefile中的目标之间建立了假的依赖关系。这样,我就避免了同时编译同一个源文件(针对不同的目标)。
https://stackoverflow.com/questions/20653258
复制相似问题