mapreduce c 编程无法使用 -fPIC link,如何解决?
mapreduce c programing failed to link with -fPIC, how to fix?
我有一个示例程序如下,w.cpp 在 ubunt 18.04 上使用 g++7.3.0
#include<algorithm>
#include<limits>
#include<string>
#include"stdint.h"
#include"Pipes.hh"
#include"TemplateFactory.hh"
#include"StringUtils.hh"
using namespace std;
using namespace HadoopPipes;
using namespace HadoopUtils;
class wMapper:public Mapper{
public:
wMapper(TaskContext&){}
void map(MapContext& context){
string line = context.getInputValue();
vector<string> words = splitString(line, " ");
for(size_t i=0;i<words.size();++i){
context.emit(words[i], toString(i));
}
}
};
class wReducer:public Reducer{
public:
wReducer(TaskContext&){}
void reduce(ReduceContext& context){
int count = 0;
while(context.nextValue()){
count += toInt(context.getInputValue());
}
context.emit(context.getInputKey(), toString(count));
}
};
int main(){
return HadoopPipes::runTask(TemplateFactory<wMapper, wReducer>());
}
然后我编译它:
g++ w.cpp -I$HADOOP_LIB/include -I$HADOOP_HOME/include \
-I$JAVA_HOME/include -L$HADOOP_LIB/native -lhadooppipes -lhadooputils
-lpthread -lcrypto -o w -fPIC
报错:
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooppipes.a(HadoopPipes.cc.o): relocation R_X86_64_32S against symbol `_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooputils.a(StringUtils.cc.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooputils.a(SerialUtils.cc.o): relocation R_X86_64_32S against symbol `_ZTVN11HadoopUtils12FileInStreamE' can not be used when making a PIE object; recompile with -fPIC
无论我添加或删除“-fPIC”标志,同样的错误。
问题是:
- 您的编译器配置为默认构建 position-independent executables,并且
- 您link使用的某些库(尤其是
libhadooppipes.a
)未以允许它们[=]的方式编译25=]进入 PIE 二进制文件。
解决方案:将 -nopie
添加到 link 命令行。
我有一个示例程序如下,w.cpp 在 ubunt 18.04 上使用 g++7.3.0
#include<algorithm>
#include<limits>
#include<string>
#include"stdint.h"
#include"Pipes.hh"
#include"TemplateFactory.hh"
#include"StringUtils.hh"
using namespace std;
using namespace HadoopPipes;
using namespace HadoopUtils;
class wMapper:public Mapper{
public:
wMapper(TaskContext&){}
void map(MapContext& context){
string line = context.getInputValue();
vector<string> words = splitString(line, " ");
for(size_t i=0;i<words.size();++i){
context.emit(words[i], toString(i));
}
}
};
class wReducer:public Reducer{
public:
wReducer(TaskContext&){}
void reduce(ReduceContext& context){
int count = 0;
while(context.nextValue()){
count += toInt(context.getInputValue());
}
context.emit(context.getInputKey(), toString(count));
}
};
int main(){
return HadoopPipes::runTask(TemplateFactory<wMapper, wReducer>());
}
然后我编译它:
g++ w.cpp -I$HADOOP_LIB/include -I$HADOOP_HOME/include \
-I$JAVA_HOME/include -L$HADOOP_LIB/native -lhadooppipes -lhadooputils
-lpthread -lcrypto -o w -fPIC
报错:
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooppipes.a(HadoopPipes.cc.o): relocation R_X86_64_32S against symbol `_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooputils.a(StringUtils.cc.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: /opt/hadoop-2.8.4/lib/native/libhadooputils.a(SerialUtils.cc.o): relocation R_X86_64_32S against symbol `_ZTVN11HadoopUtils12FileInStreamE' can not be used when making a PIE object; recompile with -fPIC
无论我添加或删除“-fPIC”标志,同样的错误。
问题是:
- 您的编译器配置为默认构建 position-independent executables,并且
- 您link使用的某些库(尤其是
libhadooppipes.a
)未以允许它们[=]的方式编译25=]进入 PIE 二进制文件。
解决方案:将 -nopie
添加到 link 命令行。