2015-10-25 2 views
0

Я хочу создать статическую библиотеку XGBoost, но я не справляюсь с этой простой задачей.Сделать статическую библиотеку вместо динамической

Во-первых, я просто пытался взять все файлы .o и через ar rcs wrapper/libxgboostwrapper.a ./* сделать статическую библиотеку, но я потерпел неудачу. Фактически, когда я делаю другие вещи, которые зависят от XGBoost, он терпит неудачу с ошибками: undefined reference to XGBoosterFree.

Эта функция определена в части обертки и нет файла wrapper/libxgboostwrapper.o. Поэтому, чтобы сначала создать статическую библиотеку, нам нужно создать wrapper/libxgboostwrapper.o, во-вторых, запустите ar rcs по всем необходимым файлам .o.

Как я модифицировал Makefile.

  1. Во-первых, я немного изменил имена некоторых переменных.

    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 
    
  2. Добавлена ​​новая переменная.

    WRAP = wrapper/libxgboostwrapper.o 
    
  3. Модифицированная цель.

    TARGET = $(BIN) $(OBJ) $(DLIB) $(SLIB) $(WRAP) 
    
  4. Добавлены зависимости для 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) 
    
  5. После того как все сделано для $(BIN), $(MOCKBIN), $(DLIB), я пытаюсь скомпилировать (или сделать?) Мой $(WRAP).

    $(WRAP) : 
        $(CXX) $(CFLAGS) -fPIC -o [email protected] $(filter %.cpp %.o %.c %.a %.cc, $^) $(LDFLAGS) $(DLLFLAGS) 
    
  6. После всего этого материала, наконец, я делаю wrapper/libxgboostwrapper.a.

    $(SLIB) : updater.o gbm.o io.o $(WRAP) $(LIBRABIT) $(LIBDMLC) 
        ar rcs [email protected] $^ 
    

Это терпит неудачу на этапе 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 файлов shuld не совпадают, кроме флага -shared не используется.

ответ

1

Это может занять несколько итераций, поскольку у вас, похоже, есть несколько неправильных представлений о том, как эти файлы работают.

ШАГ 1: Во-первых, давайте компилировать исходный файл для создания объектного файла:.

g++ -o wrapper/xgboostwrapper.o -c wrapper/xgboost_wrapper.cpp 

(Не называть объектный файл «libxgboostwrapper.o» The «Lib» префикс для библиотека, суффикс «.o» предназначен для объектного файла, когда вы используете их оба, это просто запутывает.)

Не работайте до тех пор, пока это не сработает.

ШАГ 2: Написать правило в вашем Makefile, чтобы сделать это:

wrapper/xgboostwrapper.o: wrapper/xgboost_wrapper.cpp 
    $(CXX) $(CFLAGS) -o [email protected] $< 

Не продолжайте, пока что не работает.

ШАГ 3: Рисунок из которых заголовок файлы, которые он на самом деле нужно , и добавить их в качестве предпосылок. (Это плохая идея использовать подстановочные знаки, чтобы добавить все существующие заголовки в качестве предпосылок.):

wrapper/xgboostwrapper.o: wrapper/xgboost_wrapper.cpp src/utils/foo.h src/xgboost.h 
    $(CXX) $(CFLAGS) -o [email protected] $< 

Попробуйте что-то и сказать нам, как это пошло, то мы можем продолжить.

+0

Большое спасибо! Я решил свои проблемы без вашего ответа, к сожалению! :) Сначала я создал файл-файл wrapper.o, а затем просто добавил все необходимые объектные файлы в одну библиотеку. – Jihad

Смежные вопросы