У нас есть проект на C, в котором мы хотим использовать vowpal wabbit. Мы можем сгенерировать исполняемый бинарный файл проекта без vowpalWabbit, и он также работает нормально. Но когда мы связываем vowpalWabbit с существующим проектом, сгенерированный двоичный файл каким-то образом поврежден. Мы можем скомпилировать и запустить отдельную программу, связав библиотеку vowpal wabbit.
Мы пытаемся связать VowpalWabbit с make-файлом существующего проекта следующим образом:
CFLAGS = -g -Wall -O2 -std=gnu99 -Wno-unused-variable -Wno-sign-compare
CXXFLAGS = -g -Wall -O2 -std=gnu++11 -fno-strict-aliasing -Wno-unused-variable -Wno-sign-compare
VW_LIBS = $(VW_HOME)/vowpal_wabbit/vowpalwabbit/libvw.la $(VW_HOME)/vowpal_wabbit/vowpalwabbit/liballreduce.la
SRC = $(BASE_DIR)/$(VW)/$(SRC_DIR)
SRC_FILES =$(SRC)/vw_predict_test.cpp
ALL_SRC_FILES = $(SRC_DIR)/test_main.cpp \
$(SRC_FILES)bin_PROGRAMS = test
## binary
test_SOURCES = $(ALL_SRC_FILES)
test_LDADD = $(VW_LIBS) -lthriftnb -lthrift -levent -lpthread -lm -lssl -lstdc++
test_CXXFLAGS = $(INCLUDES) $(CXXFLAGS)
test_CFLAGS = $(INCLUDES) $(CFLAGS)
этот make-файл генерирует испорченный исполняемый файл. Когда мы выполняем ldd для этого исполняемого файла, мы получаем следующее сообщение:
$ ldd test
not a dynamic executable
Пожалуйста, объясните, как мы можем связать vowpalWabbit в нашем исполняемом файле.
РЕДАКТИРОВАТЬ: Для лучшего понимания, вставив снимок нашего MakeFile.
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
CFLAGS = -g -Wall -O2 -std=gnu99 -Wno-unused-variable -Wno-sign-compare
CXXFLAGS = -g -Wall -O2 -std=gnu++11 -fno-strict-aliasing -Wno-unused-variable -Wno-sign-compare
BASE_DIR = .
# Dependencies defined here
COMMON = common
COMMONS_REPO = @COMMONS_REPO@
ANALYTICS_REPO = @ANALYTICS_REPO@
CRYPT = $(COMMONS_REPO)/crypt
SSSTORE = $(COMMONS_REPO)/datastore/lib/C
PREDICT = $(ANALYTICS_REPO)/predict
SRC_DIR = src
LIB_DIR = lib
INCLUDE_DIR = include
OBJDIR = build
SCRIPT_DIR = scripts
CONF_DIR = conf
VW = $(ANALYTICS_REPO)/vw
VW_LIBS = $(VW_HOME)/vowpal_wabbit/vowpalwabbit/libvw.la $(VW_HOME)/vowpal_wabbit/vowpalwabbit/liballreduce.la# install directories
TARGET_DIR = /mytest
LOG_DIR = /mytest/processor/logs
TARGET_DATA_DIR = /mytest/processor/data/processor/trafficking
TARGET_CONF_DIR = $(TARGET_DIR)/conf
TARGET_LIB_DIR = $(TARGET_DIR)/libs
TARGET_BIN_DIR = $(TARGET_DIR)/bin
TARGET_SCRIPTS_DIR = $(TARGET_DIR)/scripts
TARGET_LOG_DIR = $(LOG_DIR)/{cores,processor/{app,archive,concat_logs}}
## Thrift autogeneration
THRIFT_EXEC = /usr/local/bin/thrift
CC= /usr/local/bin/qrintf gcc
CXX= /usr/local/bin/qrintf g++
PROTOCOL_DIR =../resources/schema
TEST_THRIFT =$(PROTOCOL_DIR)/test.thrift
GENERATED_THRIFT=generated/thrift
$(GENERATED_THRIFT)/gen-cpp/testservice.cpp: $(TEST_THRIFT)
mkdir -p $(GENERATED_THRIFT)
$(THRIFT_EXEC) -o $(GENERATED_THRIFT) --gen cpp $(TEST_THRIFT)
CRYPT_SRC_FILES = $(CRYPT)/src/utils.cpp $(CRYPT)/src/keyPair.cpp $(CRYPT)/src/keystore.cpp
DATASTORE_SRC = $(BASE_DIR)/$(SSSTORE)/$(SRC_DIR)
## Protobuf autogeneration
PROTOBUF_INSTALL_DIR = /usr/local
PROTOBUF_EXEC = $(PROTOBUF_INSTALL_DIR)/bin/protoc
COMMON_PROTO = common.proto
PROCESSOR_SCRIPT_FILES = $(SCRIPT_DIR)/test_logs.pl
PROCESSOR_CONF_FILES = $(CONF_DIR)/server.tmpl
SCHEMA_FILES = $(SSSTORE)/src/avro.click.schema
CI_SCRIPTS_DIR = scripts/CI
GENERATED_PROTOBUF=$(DATASTORE_SRC)/generated/proto
GENERATED_PROCESSOR_LOG_PROTO=generated/proto
$(GENERATED_PROTOBUF)/common.pb.cc: $(DATASTORE_SRC)/$(COMMON_PROTO)
mkdir -p $(GENERATED_PROTOBUF)
$(PROTOBUF_EXEC) --proto_path=$(DATASTORE_SRC) --cpp_out=$(GENERATED_PROTOBUF) $(DATASTORE_SRC)/$(COMMON_PROTO)
BUILT_SOURCES = $(GENERATED_THRIFT)/gen-cpp/testservice.cpp $(GENERATED_PROTOBUF)/common.pb.ccEDGE_DEFAULT_INCLUDES = -I$(INCLUDE_DIR) -I$(BASE_DIR)/$(CRYPT)/$(INCLUDE_DIR) \
-I$(BASE_DIR)/$(SSSTORE)/$(INCLUDE_DIR) \
-I$(BASE_DIR)/$(PREDICT)/$(INCLUDE_DIR) \
-I$(BASE_DIR)/$(COMMON)/$(INCLUDE_DIR) \
-I/usr/local/include/thrift \
-I$(GENERATED_THRIFT)/gen-cpp -DOPTIMIZE_RESPONSE_FOR_SIZE=1 \
-I$(PROTOBUF_INSTALL_DIR)/include/ \
-I$(GENERATED_PROTOBUF) -g -I${GENERATED_PROCESSOR_LOG_PROTO} -g
if CENTOS64
INCLUDES = $(EDGE_DEFAULT_INCLUDES) -I /usr/lib64/glib-2.0/include
endif
if CENTOS
INCLUDES = $(EDGE_DEFAULT_INCLUDES) -I /usr/lib/glib-2.0/include
endif
if DEBIAN64
INCLUDES = $(EDGE_DEFAULT_INCLUDES) -I /usr/lib/x86_64-linux-gnu/glib-2.0/include
endif
if DEBIAN
INCLUDES = $(EDGE_DEFAULT_INCLUDES) -I/usr/lib/i386-linux-gnu/glib-2.0/include
endifCOMMON_SRC = $(BASE_DIR)/$(COMMON)/$(SRC_DIR)
COMMON_SRC_FILES = $(COMMON_SRC)/mytest_config.c $(COMMON_SRC)/mytest_utils.c
DATASTORE_SRC_FILES = $(DATASTORE_SRC)/data_store.c
SRC = $(BASE_DIR)/$(VW)/$(SRC_DIR)
SRC_FILES = $(SRC)/predict_model.c $(SRC)/predict_variable_util.c $(SRC)/vw_predict_test.cc
ALL_SRC_FILES = $(SRC_DIR)/test_main.cpp \
$(COMMON_SRC_FILES) $(DATASTORE_SRC_FILES) $(SRC_FILES) $(CRYPT_SRC_FILES)bin_PROGRAMS = test
bindir = build
#all-local: $(bin_PROGRAMS)
# rm -rf *.o
## binary
test_SOURCES = $(ALL_SRC_FILES)
test_LDADD = $(VW_LIBS) -lthriftnb -lthrift -levent -lpthread -lm -lssl -lglib-2.0 -lstdc++ -lz -luuid -lcrypto -lcitrusleaf -lavro -lrt -lprotobuf
test_CXXFLAGS = $(INCLUDES) $(CXXFLAGS)
test_CFLAGS = $(INCLUDES) $(CFLAGS)
clean-local:
-rm -rf $(GENERATED_THRIFT)
install: test
mkdir -p $(TARGET_BIN_DIR) $(TARGET_CONF_DIR) $(TARGET_SCRIPTS_DIR) $(TARGET_DATA_DIR) $(TARGET_LOG_DIR)
install -t $(TARGET_BIN_DIR) test
install -t $(TARGET_BIN_DIR) $(CI_SCRIPTS_DIR)/*
install -t $(TARGET_CONF_DIR) $(PROCESSOR_CONF_FILES) $(SCHEMA_FILES)
install -t $(TARGET_SCRIPTS_DIR) $(PROCESSOR_SCRIPT_FILES)
EDIT2: как и предполагалось, мы сейчас используем vw_predict_test.cpp
и компиляция с использованием g ++. У нас есть liballreduce.a
, libvw.a
, libvw_c_wrapper.a
библиотеки, которые мы хотим связать с нашим исполняемым файлом, поэтому мы сделали следующее:
test_SOURCES = $(ALL_SRC_FILES)
test_LDADD = -lthriftnb -lthrift -levent -lpthread -lm -lssl -lglib-2.0 -lstdc++ -lz -luuid -lcrypto -lcitrusleaf -lavro -lrt -lprotobuf -lboost_program_options $(VW_HOME)/vowpalwabbit/.libs/liballreduce.a $(VW_HOME)/vowpalwabbit/.libs/libvw.a $(VW_HOME)/vowpalwabbit/.libs/libvw_c_wrapper.a
test_CXXFLAGS = $(INCLUDES) $(CXXFLAGS)
test_CFLAGS = $(INCLUDES) $(CFLAGS)
теперь мы получаем буст-исключения, такие как:
/vowpalwabbit/.libs/libvw.a(search_sequencetask.o): In function `SequenceSpanTask::initialize(Search::search&, unsigned long&, boost::program_options::variables_map&)':
search_sequencetask.cc:(.text+0x13f6): undefined reference to `boost::program_options::options_description::m_default_line_length'
search_sequencetask.cc:(.text+0x142e): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
Мы также добавили -lboost_program_options в LDADD, который не работал.
Задача ещё не решена.
Других решений пока нет …