我想创建静态XGBoost库,但我没有完成这项简单的任务。
首先,我只是尝试获取所有.o
个文件并通过ar rcs wrapper/libxgboostwrapper.a ./*
制作静态库,但我失败了。事实上,当我制作依赖于XGBoost的其他内容时,它会失败并出现错误:undefined reference to XGBoosterFree
。
此函数在包装器部分中定义,没有文件wrapper/libxgboostwrapper.o
。因此,为了首先创建静态库,我们必须创建wrapper/libxgboostwrapper.o
,其次,在所有需要的ar rcs
文件上运行.o
。
我如何修改Makefile 。
首先,我略微更改了一些变量的名称。
ifeq ($(OS), Windows_NT)
LIBRABIT = subtree/rabit/lib/librabit_empty.a
DLIB = wrapper/xgboost_wrapper.dll
SLIB = wrapper/xgboost_wrapper.lib
else
LIBRABIT = subtree/rabit/lib/librabit.a
DLIB = wrapper/libxgboostwrapper.so
SLIB = wrapper/libxgboostwrapper.a
endif
添加了新变量。
WRAP = wrapper/libxgboostwrapper.o
修改目标。
TARGET = $(BIN) $(OBJ) $(DLIB) $(SLIB) $(WRAP)
为wrapper/libxgboostwrapper.o
添加的依赖项与wrapper/libxgboostwrapper.so
完全相同。
wrapper/libxgboostwrapper.o: wrapper/xgboost_wrapper.cpp src/utils/*.h src/*.h src/learner/*.hpp src/learner/*.h updater.o gbm.o io.o $(LIBRABIT) $(LIBDMLC)
完成$(BIN)
,$(MOCKBIN)
,$(DLIB)
的所有操作后,我试图编译(或制作?)我的$(WRAP)
。< / p>
$(WRAP) :
$(CXX) $(CFLAGS) -fPIC -o $@ $(filter %.cpp %.o %.c %.a %.cc, $^) $(LDFLAGS) $(DLLFLAGS)
在完成所有这些事情后,我终于制作了wrapper/libxgboostwrapper.a
。
$(SLIB) : updater.o gbm.o io.o $(WRAP) $(LIBRABIT) $(LIBDMLC)
ar rcs $@ $^
在步骤5失败,错误如下:
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 10
我做错了什么?对我来说,似乎汇编.so
和.o
文件是相同的,除了不使用标记-shared
。
答案 0 :(得分:2)
这可能需要几次迭代,因为您似乎对这些文件的工作原理有一些误解。
第1步:首先,让我们编译一个源文件来生成一个目标文件:
g++ -o wrapper/xgboostwrapper.o -c wrapper/xgboost_wrapper.cpp
(不要调用目标文件&#34; libxgboostwrapper.o&#34;。&#34; lib&#34;前缀用于库,&#34; .o&#34;后缀是一个目标文件,当你使用它们时,它只是令人困惑。)
在此之前不要继续。
第2步:在makefile中编写规则来执行此操作:
wrapper/xgboostwrapper.o: wrapper/xgboost_wrapper.cpp
$(CXX) $(CFLAGS) -o $@ $<
在此之前不要继续。
第3步:找出实际需要的头文件,并将其作为先决条件添加。 (使用通配符将所有现有标头添加为先决条件是一个坏主意。):
wrapper/xgboostwrapper.o: wrapper/xgboost_wrapper.cpp src/utils/foo.h src/xgboost.h
$(CXX) $(CFLAGS) -o $@ $<
尝试那么多并告诉我们它是如何进行的,然后我们就可以继续了。