ChatGPT gave me a solution that works but idk why?

While trying to compile code that uses ROOT, fastjet, Apache-arrow and another pre-compiled shared library, I ran into an issue when I added SoftDrop functionalities using the RecursiveTools library from fastjet contrib, where virtual functions were not read properly. Here is the CMake file that works:

cmake_minimum_required(VERSION 3.16)

set(CMAKE_CXX_STANDARD 20)

project(embeddingJetMaker)

set(ROOT_DIR "/home/tanmaypani/heplibs/root/root")

find_package(Arrow REQUIRED)
find_package(ROOT 6.34 REQUIRED)

find_library(TSTAR_LIB NAME TStarEventClass PATHS "/home/tanmaypani/star-workspace/libs/TStarEventClass" NO_DEFAULT_PATH REQUIRED)
find_library(FASTJET_LIB NAME fastjet PATHS "/home/tanmaypani/heplibs/fastjet-install/lib" NO_DEFAULT_PATH REQUIRED)
find_library(FASTJET_TOOLS_LIB NAME fastjettools PATHS "/home/tanmaypani/heplibs/fastjet-install/lib" NO_DEFAULT_PATH REQUIRED)
find_library(RECURSIVE_TOOLS_LIB NAME RecursiveTools PATHS "/home/tanmaypani/heplibs/fastjet-install/lib" NO_DEFAULT_PATH REQUIRED)

# Get compiler and linker flags
execute_process(COMMAND /home/tanmaypani/heplibs/fastjet-install/bin/fastjet-config --libs OUTPUT_VARIABLE FASTJET_LDFLAGS)
string(REPLACE "\n" " " FASTJET_LDFLAGS "${FASTJET_LDFLAGS}")

set(LDFLAGS "-Wl,--copy-dt-needed-entries ${FASTJET_LDFLAGS} -lRecursiveTools -no-pie")

add_executable(${PROJECT_NAME} embeddingJetMaker.cpp dataSerializer.hh)

# Include directories
target_include_directories(${PROJECT_NAME} PUBLIC "/home/tanmaypani/star-workspace/preprocessing/embedding")
target_include_directories(${PROJECT_NAME} PUBLIC "/home/tanmaypani/heplibs/fastjet-install/include")
target_include_directories(${PROJECT_NAME} PUBLIC "/home/tanmaypani/star-workspace/libs/TStarEventClass")

# Link libraries
target_link_libraries(${PROJECT_NAME} PUBLIC ROOT::ROOTDataFrame ROOT::EG ${TSTAR_LIB})
target_link_libraries(${PROJECT_NAME} PUBLIC ${FASTJET_LIB} ${FASTJET_TOOLS_LIB} ${RECURSIVE_TOOLS_LIB})
target_link_libraries(${PROJECT_NAME} PRIVATE Arrow::arrow_shared)
target_link_libraries(${PROJECT_NAME} PRIVATE ${LDFLAGS})

The libraries are found okay using find_library
. If you comment the lines using LDFLAGS (21 and 34) the error:

/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): warning: relocation against `_ZTVN7fastjet9ReclusterE' in read-only section `.text.unlikely'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::contrib::RecursiveSymmetryCutBase::_recluster_if_needed(fastjet::PseudoJet const&) const':
/home/tanmaypani/heplibs/fastjet-install/fjcontrib-1.100/RecursiveTools/RecursiveSymmetryCutBase.cc:341: undefined reference to `fastjet::Recluster::Recluster(fastjet::JetAlgorithm, double, fastjet::Recluster::Keep)'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::FunctionOfPseudoJet<fastjet::PseudoJet>::operator()(fastjet::PseudoJet const&) const':
/home/tanmaypani/heplibs/fastjet-install/include/fastjet/FunctionOfPseudoJet.hh:75: undefined reference to `fastjet::Recluster::result(fastjet::PseudoJet const&) const'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::Recluster::~Recluster()':
/home/tanmaypani/heplibs/fastjet-install/include/fastjet/tools/Recluster.hh:134: undefined reference to `vtable for fastjet::Recluster'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::Recluster::Recluster(fastjet::JetDefinition const&, bool, fastjet::Recluster::Keep)':
/home/tanmaypani/heplibs/fastjet-install/include/fastjet/tools/Recluster.hh:108: undefined reference to `vtable for fastjet::Recluster'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::FunctionOfPseudoJet<fastjet::PseudoJet>::operator()(fastjet::PseudoJet const&) const':
/home/tanmaypani/heplibs/fastjet-install/include/fastjet/FunctionOfPseudoJet.hh:75: undefined reference to `fastjet::Recluster::result(fastjet::PseudoJet const&) const'
/usr/bin/ld: /home/tanmaypani/heplibs/fastjet-install/lib/libRecursiveTools.a(RecursiveSymmetryCutBase.o): in function `fastjet::Recluster::~Recluster()':
/home/tanmaypani/heplibs/fastjet-install/include/fastjet/tools/Recluster.hh:134: undefined reference to `vtable for fastjet::Recluster'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/embeddingJetMaker.dir/build.make:126: embeddingJetMaker] Error 1
make[1]: *** [CMakeFiles/Makefile2:87: CMakeFiles/embeddingJetMaker.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Output of fastjet-config --libs:

-Wl,-rpath,/home/tanmaypani/heplibs/fastjet-install/lib -L/home/tanmaypani/heplibs/fastjet-install/lib -lfastjettools -lfastjet -lm

I just dont understand why exactly I need those lines if I already have the “target_link_libraries” lines. I added those lines after asking chatgpt what to do but obviously got no good explanation. There has to be a better, CMake only solution right?

The order of linking things together matters. With your LDFLAGS, you are linking libfastjet after libRecursiveTools which resolves the missing symbols.