CMake 'неопределенная ссылка' ошибка с CERN-ROOT - PullRequest
0 голосов
/ 30 сентября 2019

Я пишу небольшое дополнение к CERN ROOT и теперь не могу избавиться от ошибки 'undefined reference' для каждой функции из ROOT, которую я использую (и мои классы тоже). Не могу найти способ исправить это, поэтому обращаюсь за помощью здесь)

Моя ОС - Linux Mint 19. Я использую g ++ в качестве компилятора c ++, однако я пробовал clang ++, и не было никакой разницы. Я загрузил исходники ROOT с их github и теперь собрал на нем мой компьютер. Вывод root --version таков:

ROOT Version: 6.19/01
Built for linuxx8664gcc on Sep 29 2019, 14:25:35
From heads/master@v6-19-01-1167-gbec9f2d1f7

Это структура моего проекта:

ParentFolder
--CMakeLists.txt
--General
----include/...
----source/...
----CMakeLists.txt
----LinkDef.h
--Test
----include/...
----source/...
----CMakeLists.txt

Важные строки из верхнего уровня CMakeLists.txt:

find_package(ROOT REQUIRED)
list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})
include(${ROOT_USE_FILE})

add_subdirectory("./General")
add_subdirectory("./Test")

Из файла Test / CmakeLists.txt:

add_executable(Test source/test_main.cpp)

target_include_directories(Test PUBLIC "./include")

target_link_libraries(Test PUBLIC General GTest::GTest GTest::Main ${ROOT_LIBRARIES})

Из файла General / CmakeLists.txt:

file(GLOB_RECURSE SOURCES . source/*.cpp)

ROOT_GENERATE_DICTIONARY(GeoManagerExtractor LINKDEF LinkDef.h)

add_library(General SHARED ${SOURCES} GeoManagerExtractor.cxx)

target_link_libraries(General ${ROOT_LIBRARIES})

target_include_directories(General PUBLIC "./include")

Вот несколько первых строк, созданных CMake (при использовании clang ++)

CMakeFiles/Test.dir/source/test_main.cpp.o: In function `main':
test_main.cpp:(.text+0x37): undefined reference to `TGeoManager::Import(char const*, char const*, char const*)'
test_main.cpp:(.text+0x3f): undefined reference to `gGeoManager'
test_main.cpp:(.text+0x8c): undefined reference to `gGeoManager'
CMakeFiles/Test.dir/source/test_main.cpp.o: In function `TGeoManagerExporter::~TGeoManagerExporter()':
test_main.cpp:(.text._ZN19TGeoManagerExporterD2Ev[_ZN19TGeoManagerExporterD2Ev]+0xa): undefined reference to `vtable for TGeoManagerExporter'
../General/libGeneral.so: undefined reference to `ROOT::GenerateInitInstance(TGeoManagerExporter const*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Вот несколько строк из test_main.cpp:

TGeoManager::Import("../root_tests/geofile_full.root");
    if (gGeoManager == nullptr) {
        std::cerr << "Can't find TGeoManager in file" << std::endl;
        return 0;
    }

UPD: забыл упомянуть, что для создания моих файлов CMakeLists.txt я использовал эти два источника: https://root.cern.ch/how/integrate-root-my-project-cmake https://cliutils.gitlab.io/modern-cmake/chapters/packages/ROOT.html

1 Ответ

0 голосов
/ 04 октября 2019

Мне удалось скомпилировать мой проект.
Как оказалось, файл .so, содержащий реализацию TGeoManager, не был включен в ROOT_LIBRARIES (спасибо, Камил Кук, за то, что обратил мое внимание на эту переменную) скриптом, предоставленным ROOTРазработчики. Трудно было найти, так как этот класс работал должным образом в Cling (интерпретатор c ++ включен в ROOT), и этот класс является почти единственным из ROOT, который я использую в проекте, поэтому я предположил, что вся библиотека ROOT не связывалась должным образом,После того как я обнаружил эту проблему, я исправил свои файлы CMake следующим образом (это из General / CmakeLists.txt):

file(GLOB_RECURSE SOURCES2 . $ENV{ROOTSYS}/lib/*.so)
add_library(General SHARED ${SOURCES} ${SOURCES2} GeoManagerExtractor.cxx)

Это устраняет все «неопределенные ссылки на« gGeoManager »и т. Д., Но"неопределенная ссылка на` vtable для TGeoManagerExporter '"(TGeoManagerExporter - мой собственный класс) остается. Однако я выяснил, что эта ошибка вызвана функцией отражения, поэтому в качестве временного решения я просто не активирую ее. Я отправлю комментарий здесь, если я решу эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...