Добавление OpenCL.so библиотека в файл makefile, я получаю ошибку «неопределенная ссылка на»

#ubuntu #gcc #makefile #compiler-errors #linker

Вопрос:

Я пытаюсь скомпилировать свой исходный код из Windows в систему Ubuntu, используя библиотеки OpenCL. Я могу подтвердить, что библиотека OpenCL была успешно установлена в /usr/lib/x86_64-linux-gnu/libOpenCL.так что

Когда make release я получаю «неопределенную ссылку на» , несмотря на то, что я связал файл OpenCL, который находится по адресу /usr/lib/x86_64-linux-gnu/libOpenCL.so .

Я родом из мира Visual Studio, поэтому все, что я сделал соответственно,- это добавил в исходный файл makefile путь к библиотеке, используя параметры-L для переменных DYN_RELEASE_LIBS и STAT_RELEASE_LIBS.

 user75@server:~/source/build/linux$ make release
make -C lib/TLibVideoIO              release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/lib/TLibVideoIO'
make[1]: Leaving directory `/home/user75/source/build/linux/lib/TLibVideoIO'
make -C lib/TLibCommon               release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/lib/TLibCommon'
make[1]: Leaving directory `/home/user75/source/build/linux/lib/TLibCommon'
make -C lib/TLibDecoder              release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/lib/TLibDecoder'
make[1]: Leaving directory `/home/user75/source/build/linux/lib/TLibDecoder'
make -C lib/TLibEncoder              release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/lib/TLibEncoder'
make[1]: Leaving directory `/home/user75/source/build/linux/lib/TLibEncoder'
make -C lib/TAppCommon               release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/lib/TAppCommon'
make[1]: Leaving directory `/home/user75/source/build/linux/lib/TAppCommon'
make -C app/TAppDecoder              release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/app/TAppDecoder'
make[1]: Leaving directory `/home/user75/source/build/linux/app/TAppDecoder'
make -C app/TAppEncoder              release MM32=0
make[1]: Entering directory `/home/user75/source/build/linux/app/TAppEncoder'
g  -4.8 -o ../../../../bin/Linux/TAppEncoderStatic -Wall  ./objects/encmain.r.o ./objects/TAppEncCfg.r.o ./objects/TAppEncTop.r.o -L../../../../lib /usr/lib/x86_64-linux-gnu/libOpenCL.so -ldl  -lpthread  -lTLibEncoderStatic -lTLibCommonStatic -lTLibVideoIOStatic -lTAppCommonStatic -L/usr/lib/x86_64-linux-gnu/libOpenCL.so
../../../../lib/libTLibEncoderStatic.a(TEncTop.r.o): In function `TEncTop::xInitOpenCL(int)':
TEncTop.cpp:(.text 0x4264): undefined reference to `TEncOpenCL::findDevice(int)'
TEncTop.cpp:(.text 0x4285): undefined reference to `TEncOpenCL::compileOneKernelSource(char const*, char const*)'
TEncTop.cpp:(.text 0x42e3): undefined reference to `TEncOpenCL::setCTUs_and_SearchRange(unsigned int, unsigned int, int)'
../../../../lib/libTLibEncoderStatic.a(TEncTop.r.o): In function `TEncTop::TEncTop()':
TEncTop.cpp:(.text 0x5597): undefined reference to `TEncOpenCL::TEncOpenCL()'
TEncTop.cpp:(.text 0x58fc): undefined reference to `TEncOpenCL::~TEncOpenCL()'
../../../../lib/libTLibEncoderStatic.a(TEncTop.r.o): In function `TEncTop::~TEncTop()':
TEncTop.cpp:(.text 0x5b74): undefined reference to `TEncOpenCL::~TEncOpenCL()'
TEncTop.cpp:(.text 0x5d47): undefined reference to `TEncOpenCL::~TEncOpenCL()'
../../../../lib/libTLibEncoderStatic.a(TEncSearch.r.o): In function `TEncSearch::xMotionEstimation(TComDataCU*, TComYuv*, int, RefPicList, TComMv*, int, TComMvamp;, unsigned intamp;, unsigned intamp;, TComMv (*) [33][593], unsigned int (*) [33][593], bool, unsigned long, bool)':
TEncSearch.cpp:(.text 0xf28d): undefined reference to `TEncOpenCL::calcMotionVectors(short*, short*, int, int, int, TComMv*, unsigned long, int)'
TEncSearch.cpp:(.text 0xf46f): undefined reference to `TEncOpenCL::FreeMemory(int)'
../../../../lib/libTLibEncoderStatic.a(TEncSearch.r.o): In function `TEncSearch::xMotionEstimation(TComDataCU*, TComYuv*, int, RefPicList, TComMv*, int, TComMvamp;, unsigned intamp;, unsigned intamp;, TComMv (*) [33][593], unsigned int (*) [33][593], bool, unsigned long, bool) [clone .constprop.186]':
TEncSearch.cpp:(.text 0xfd32): undefined reference to `TEncOpenCL::calcMotionVectors(short*, short*, int, int, int, TComMv*, unsigned long, int)'
TEncSearch.cpp:(.text 0xff39): undefined reference to `TEncOpenCL::FreeMemory(int)'
collect2: error: ld returned 1 exit status
make[1]: *** [../../../../bin/Linux/TAppEncoderStatic] Error 1
make[1]: Leaving directory `/home/user75/source/build/linux/app/TAppEncoder'
make: *** [release] Error 2
 

Исходный код Makefile приведен ниже. Изменения, которые я внес, касались переменных USER_LIB_DIRS и DYN_RELEASE_LIBS и STAT_RELEASE_LIBS.

 # the SOURCE definiton lets you move your makefile to another position
CONFIG              = CONSOLE

# set directories to your wanted values
SRC_DIR             = ../../../../source/App/TAppEncoder
INC_DIR             = ../../../../source/Lib
LIB_DIR             = ../../../../lib
BIN_DIR             = ../../../../bin

SRC_DIR1        =
SRC_DIR2        =
SRC_DIR3        =
SRC_DIR4        =

USER_INC_DIRS   = -I$(SRC_DIR)
USER_LIB_DIRS   = /usr/lib/x86_64-linux-gnu/libOpenCL.so

ifeq ($(HIGHBITDEPTH), 1)
HBD=HighBitDepth
else
HBD=
endif

# intermediate directory for object files
OBJ_DIR             = ./objects$(HBD)

# set executable name
PRJ_NAME            = TAppEncoder$(HBD)

# defines to set
DEFS                = -DMSYS_LINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DMSYS_UNIX_LARGEFILE

# set objects
OBJS                =   
                    $(OBJ_DIR)/encmain.o 
                    $(OBJ_DIR)/TAppEncCfg.o 
                    $(OBJ_DIR)/TAppEncTop.o 

# set libs to link with
LIBS                = -ldl

DEBUG_LIBS          =
RELEASE_LIBS        =

STAT_LIBS           = -lpthread 
DYN_LIBS            =


DYN_DEBUG_LIBS      = -lTLibEncoder$(HBD)d -lTLibCommon$(HBD)d -lTLibVideoIO$(HBD)d -lTAppCommon$(HBD)d
DYN_DEBUG_PREREQS       = $(LIB_DIR)/libTLibEncoder$(HBD)d.a $(LIB_DIR)/libTLibCommon$(HBD)d.a $(LIB_DIR)/libTLibVideoIO$(HBD)d.a $(LIB_DIR)/libTAppCommon$(HBD)d.a
STAT_DEBUG_LIBS     = -lTLibEncoder$(HBD)Staticd -lTLibCommon$(HBD)Staticd -lTLibVideoIO$(HBD)Staticd -lTAppCommon$(HBD)Staticd
STAT_DEBUG_PREREQS      = $(LIB_DIR)/libTLibEncoder$(HBD)Staticd.a $(LIB_DIR)/libTLibCommon$(HBD)Staticd.a $(LIB_DIR)/libTLibVideoIO$(HBD)Staticd.a $(LIB_DIR)/libTAppCommon$(HBD)Staticd.a

DYN_RELEASE_LIBS    = -lTLibEncoder$(HBD) -lTLibCommon$(HBD) -lTLibVideoIO$(HBD) -lTAppCommon$(HBD) -l/usr/lib/x86_64-linux-gnu/libOpenCL.so 
DYN_RELEASE_PREREQS = $(LIB_DIR)/libTLibEncoder$(HBD).a $(LIB_DIR)/libTLibCommon$(HBD).a $(LIB_DIR)/libTLibVideoIO$(HBD).a $(LIB_DIR)/libTAppCommon$(HBD).a
STAT_RELEASE_LIBS   = -lTLibEncoder$(HBD)Static -lTLibCommon$(HBD)Static -lTLibVideoIO$(HBD)Static -lTAppCommon$(HBD)Static -l/usr/lib/x86_64-linux-gnu/libOpenCL.so 
STAT_RELEASE_PREREQS    = $(LIB_DIR)/libTLibEncoder$(HBD)Static.a $(LIB_DIR)/libTLibCommon$(HBD)Static.a $(LIB_DIR)/libTLibVideoIO$(HBD)Static.a $(LIB_DIR)/libTAppCommon$(HBD)Static.a

ifeq ($(EXTENSION_360_VIDEO), 1)
  DYN_DEBUG_LIBS       = -lTAppEncHelper360$(HBD)d -lTLib360$(HBD)d
  DYN_DEBUG_PREREQS    = $(LIB_DIR)/libTAppEncHelper360$(HBD)d.a $(LIB_DIR)/libTLib360$(HBD)d.a
  STAT_DEBUG_LIBS      = -lTAppEncHelper360$(HBD)Staticd -lTLib360$(HBD)Staticd
  STAT_DEBUG_PREREQS   = $(LIB_DIR)/libTAppEncHelper360$(HBD)Staticd.a $(LIB_DIR)/libTLib360$(HBD)Staticd.a
  DYN_RELEASE_LIBS     = -lTAppEncHelper360$(HBD) -lTLib360$(HBD)
  DYN_RELEASE_PREREQS  = $(LIB_DIR)/libTAppEncHelper360$(HBD).a $(LIB_DIR)/libTLib360$(HBD).a
  STAT_RELEASE_LIBS    = -lTAppEncHelper360$(HBD)Static -lTLib360$(HBD)Static
  STAT_RELEASE_PREREQS = $(LIB_DIR)/libTAppEncHelper360$(HBD)Static.a $(LIB_DIR)/libTLib360$(HBD)Static.a
endif

# name of the base makefile
MAKE_FILE_NAME      = ../../common/makefile.base

# include the base makefile
include $(MAKE_FILE_NAME)
 

Итак, вопросы 1) является ли это ошибкой ссылки? 2) как успешно добавить библиотеку *.so?

Исходные полные файлы makefile находятся по адресу https://hevc.hhi.fraunhofer.de/svn/svn_HEVCSoftware/branches/HM-dev/build/linux/

С уважением,

Комментарии:

1. TEncTop.cpp:(.текст 0x4264): неопределенная ссылка на «TEncOpenCL::findDevice(int)» где находится реализация findDevice()?

2. @гарри Внутри пути sourceLibTLibEncoder есть два файла (TEncOpenCL.cpp и TEncOpenCL.h) как расширение исходного проекта, который уже включен в файл makefile. PS: Может ли это быть ошибкой, потому что *.so являются динамическими, и компилятор пытается создать статический исполняемый файл? make[1]: *** [../../../../bin/Linux/TAppEncoderStatic] Error 1

3. Я добавил в свой оригинальный пост оригинальные файлы создания

Ответ №1:

  1. Ваша командная строка: g -4.8 -o ../../../../bin/Linux/TAppEncoderStatic -Wall ./objects/encmain.r.o ./objects/TAppEncCfg.r.o ./objects/TAppEncTop.r.o -L../../../../lib /usr/lib/x86_64-linux-gnu/libOpenCL.so -ldl -lpthread -lTLibEncoderStatic -lTLibCommonStatic -lTLibVideoIOStatic -lTAppCommonStatic -L/usr/lib/x86_64-linux-gnu/libOpenCL.so неверна.

    Вы должны удалить -L/usr/lib/x86_64-linux-gnu/libOpenCL.so , заменить /usr/lib/x86_64-linux-gnu/libOpenCL.so на -lOpenCL и переместить его ближе к концу. Также удалите -lpthread и добавьте -pthread вместо этого.

    Команда должна выглядеть примерно так:
    g -4.8 -pthread -o ... -lOpenCL -ldl

  2. Ваша проблема не имеет ничего общего с libOpenCL неразрешенными символами, такими как TEncOpenCL::findDevice(int) и т. Д. выглядят как ваши собственные символы.

    Это, вероятно , означает либо то, что порядок libTLibEncoderStatic libTLibCommonStatic , и т.д. неверен (прочитайте это, чтобы понять правильный порядок), либо то, что вам просто не хватает некоторых объектных файлов в этих библиотеках.

    Запуск nm -AC lib/lib*.a | grep TEncOpenCL::findDevice(int) должен помочь выяснить, какая библиотека (если таковая имеется) определяет этот символ.

Комментарии:

1. привет, я изменил команду g -4.8 -o ../../../../bin/Linux/TAppEncoderStatic -Wall ./objects/encmain.r.o ./objects/TAppEncCfg.r.o ./objects/TAppEncTop.r.o -L../../../../lib -pthread -lOpenCL -ldl -lTLibEncoderStatic -lTLibCommonStatic -lTLibVideoIOStatic -lTAppCommonStatic , но у меня все та же ошибка. 1) Должен ли я где-нибудь объявить путь к OpenCL *.чтобы библиотека или компилятор могли найти его автоматически? 2) Когда вы говорите «проблема с моими собственными символами», что именно вы имеете в виду? Запустив команду nm -AC lib/lib*.a | grep TEncOpenCL::findDevice , я получаю nm: 'lib/lib*.a': No such file

2. Спасибо всем вам за ваш ответ. Основной корень проблемы заключался в том, что я не установил (OBJ_DIR)/TEncOpenCL.o список переменных внутри OBJ в файле TLibEncodermakefile для создания obj….. Я была такой неловкой. С наилучшими пожеланиями всем.

Ответ №2:

общая библиотека должна быть добавлена как

 LDFLAGS  = -L/usr/lib/x86_64-linux-gnu/libOpenCL.so
LDLIBS  = -lOpenCL
 

Комментарии:

1. Спасибо, но, похоже, это не работает. Я получаю ту же ошибку.

2. Вы не указываете имя файла в -L опции. Вы помещаете каталог для поиска в -L опцию. Предполагая, что путь к libOpenCL.so существует, он должен быть -L/usr/lib/x86-64-linux-gnu . Тем не менее, я почти уверен, что поиск по каталогу выполняется по умолчанию, так что это не проблема.