我有一个简单的 C++ 程序,可以在我的 Mac(Mavericks)上成功构建,但在 R 中构建和加载clang++
时会失败。R CMD SHLIB
dyn.load
这是使用 Gurobi 优化器的 C++ 代码(存储在 中simple.cpp
):
#include "gurobi_c++.h"
#include <iostream>
void fxn() {
GRBEnv env = GRBEnv(); // Create a Gurobi environment
GRBModel colgen = GRBModel(env); // Create empty model object
colgen.addVar(0, 1, 0.0, GRB_BINARY); // Add binary variable to model
std::cout << "Hello world" << std::endl;
}
int main(int argc, char **argv) {
fxn();
return 0;
}
clang++
我可以使用链接到 Gurobi 库成功编译和运行此代码:
$ clang++ simple.cpp -I/Library/gurobi562/mac64/include \
-L/Library/gurobi562/mac64/lib -lgurobi_c++ -lgurobi56 -stdlib=libstdc++ \
-lpthread -lm
$ ./a.out
Hello world
我能够成功编译R CMD SHLIB
:
$ MAKEFLAGS="PKG_CXXFLAGS=-I/Library/gurobi562/mac64/include" R CMD SHLIB \
simple.cpp -L/Library/gurobi562/mac64/lib -lgurobi_c++ -lgurobi56 \
-stdlib=libstdc++ -lpthread -lm
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG \
-I/usr/local/include -I/Library/gurobi562/mac64/include -fPIC -mtune=core2 \
-g -O2 -c simple.cpp -o simple.o
clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup \
-single_module -multiply_defined suppress -L/usr/local/lib -L/usr/local/lib \
-o simple.so simple.o -L/Library/gurobi562/mac64/lib -lgurobi_c++ -lgurobi56 \
-stdlib=libstdc++ -lpthread -lm -F/Library/Frameworks/R.framework/.. \
-framework R -Wl,-framework -Wl,CoreFoundation
但是,dyn.load("simple.so")
在 R 中失败:
Error in dyn.load("simple.so") :
unable to load shared object '[path]/simple.so':
dlopen([path]/simple.so, 6): Symbol not found: __ZN8GRBModel6addVarEdddcNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE
Referenced from: [path]/simple.so
Expected in: flat namespace
in [path]/simple.so
从c++filt
中,我可以看到缺少的符号是GRBModel::addVar(double, double, double, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
,它应该由我正在链接的 Gurobi 库之一提供。
从以前的帖子中,我收集到这些“找不到符号”错误通常是由于没有链接正确的库而发生的,但我已经能够成功编译和运行simple.cpp
,并且我将相同的链接选项传递给R CMD SHLIB
.
以下是我的~/.R/Makevars
文件的内容:
CC=clang
CXX=clang++
编辑我认为这个问题可能与-stdlib=libstdc++
我在编译代码时使用的选项有关。当我从第一个构建(的工作调用)中删除此选项时,clang++
我得到的第一个链接器错误是:
Undefined symbols for architecture x86_64:
"GRBModel::addVar(double, double, double, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_fxn in simple-pRHAEs.o
dyn.load
这与导致失败的未定义符号相同。