diff --git a/.github/workflows/root-ci-config/buildconfig/alma10.txt b/.github/workflows/root-ci-config/buildconfig/alma10.txt index d754dc5054ca3..33571ade4c16b 100644 --- a/.github/workflows/root-ci-config/buildconfig/alma10.txt +++ b/.github/workflows/root-ci-config/buildconfig/alma10.txt @@ -1,3 +1,4 @@ builtin_civetweb=ON builtin_vdt=ON pythia8=ON +symlink_libs=OFF diff --git a/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py index bc311f630f634..27fbe9295b373 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py @@ -109,10 +109,10 @@ def activate(self): self.active = True if self.firstActivation: if platform.system() == "Windows": - dlOpenRint = 'gInterpreter->LoadFile("libRint.dll");' + dlOpenRint = 'gInterpreter->LoadFile("libROOTRint.dll");' else: utils.declareCppCode('#include "dlfcn.h"') - dlOpenRint = 'dlopen("libRint.so",RTLD_NOW);' + dlOpenRint = 'dlopen("libROOTRint.so",RTLD_NOW);' utils.processCppCode(dlOpenRint) utils.declareCppCode(_TTabComHookCode) self.hook = ROOT._TTabComHook diff --git a/cmake/modules/RootBuildOptions.cmake b/cmake/modules/RootBuildOptions.cmake index 3107e1850f363..ad39de05b55f5 100644 --- a/cmake/modules/RootBuildOptions.cmake +++ b/cmake/modules/RootBuildOptions.cmake @@ -163,6 +163,7 @@ ROOT_BUILD_OPTION(soversion OFF "Set version number in sonames for shared librar ROOT_BUILD_OPTION(spectrum ON "Enable support for TSpectrum") ROOT_BUILD_OPTION(sqlite ON "Enable support for SQLite") ROOT_BUILD_OPTION(ssl ON "Enable support for SSL encryption via OpenSSL") +ROOT_BUILD_OPTION(symlink_libs ON "Build backward compatibility symlinks for historical libnames (eg. point libCore.so to libROOTCore.so).") ROOT_BUILD_OPTION(test_distrdf_dask OFF "Enable distributed RDataFrame tests that use dask") ROOT_BUILD_OPTION(test_distrdf_pyspark OFF "Enable distributed RDataFrame tests that use pyspark") ROOT_BUILD_OPTION(testsupport OFF "Build the ROOT::TestSupport library required to use all features of ROOT_ADD_GTEST and similar macros (requires gtest at build time)") diff --git a/cmake/modules/RootConfiguration.cmake b/cmake/modules/RootConfiguration.cmake index dd73530daa6fd..a69d24d9d82a0 100644 --- a/cmake/modules/RootConfiguration.cmake +++ b/cmake/modules/RootConfiguration.cmake @@ -721,7 +721,7 @@ else() ${CMAKE_BINARY_DIR}/ginclude/compiledata.h "${CMAKE_CXX_COMPILER}" "${CMAKE_CXX_FLAGS_RELEASE}" "${CMAKE_CXX_FLAGS_DEBUG}" "${CMAKE_CXX_ACLIC_FLAGS}" "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}" "${CMAKE_EXE_LINKER_FLAGS}" "so" - "${libdir}" "-lCore" "-lRint" "" "" "${ROOT_ARCHITECTURE}" "${ROOTBUILD}" + "${libdir}" "-lCore" "-lROOTRint" "" "" "${ROOT_ARCHITECTURE}" "${ROOTBUILD}" "${local_ROOT_COMPILEDATA_IGNORE_BUILD_NODE_CHANGES}") endif() diff --git a/cmake/modules/RootMacros.cmake b/cmake/modules/RootMacros.cmake index c24c3b7e9f54a..466c53b7651c4 100644 --- a/cmake/modules/RootMacros.cmake +++ b/cmake/modules/RootMacros.cmake @@ -580,7 +580,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) set(pcm_name ${library_output_dir}/${libprefix}${library_output_name}_${dictionary}_rdict.pcm) set(rootmap_name ${library_output_dir}/${libprefix}${library_output_name}32.rootmap) else() - set(cpp_module ${library_target_name}) + set(cpp_module ${library_output_name}) endif(ARG_MULTIDICT) if(runtime_cxxmodules) @@ -607,7 +607,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) unset(cpp_module) unset(cpp_module_file) else() - list(APPEND local_modules_idx_deps ${cpp_module}) + list(APPEND local_modules_idx_deps ${library_target_name}) set_property(GLOBAL PROPERTY modules_idx_deps_property "${local_modules_idx_deps}") endif(ARG_NO_CXXMODULE) @@ -628,9 +628,20 @@ function(ROOT_GENERATE_DICTIONARY dictionary) # dependency below are independent of configuration order and expand to # nothing for a dictionary-less library. set(dep_has_dict "$") - set(dependent_pcm ${libprefix}${dep}_rdict.pcm) + + # Determine the true output library name if the target defines an OUTPUT_NAME property + if(TARGET ${dep}) + get_target_property(dep_out_name ${dep} OUTPUT_NAME) + if(NOT dep_out_name) + set(dep_out_name ${dep}) + endif() + else() + set(dep_out_name ${dep}) + endif() + + set(dependent_pcm ${libprefix}${dep_out_name}_rdict.pcm) if (runtime_cxxmodules AND NOT dep IN_LIST local_no_cxxmodules) - set(dependent_pcm ${dep}.pcm) + set(dependent_pcm ${dep_out_name}.pcm) list(APPEND pcm_dependencies "$<${dep_has_dict}:$>") endif() set(newargs ${newargs} "$<${dep_has_dict}:-m>" "$<${dep_has_dict}:${dependent_pcm}>") @@ -1339,7 +1350,7 @@ macro(ROOT_CREATE_HEADER_COPY_TARGETS) endmacro() #--------------------------------------------------------------------------------------------------- -#---ROOT_STANDARD_LIBRARY_PACKAGE(libname +#---ROOT_STANDARD_LIBRARY_PACKAGE(libname : the name of the CMake target. If OUTPUT_NAME not specified, will be also name on disk eg lib${libname}.so. # [NO_INSTALL_HEADERS] : don't install headers for this package # [NO_GLOB_HEADERS] : don't glob for headers, only install listed ones # [STAGE1] : use rootcling_stage1 for generating @@ -1351,6 +1362,9 @@ endmacro() # [OBJECT_LIBRARY] : use ROOT_OBJECT_LIBRARY to generate object files # and then use those for linking. # LIBRARIES lib1 lib2 : private arguments for target_link_library() +# OUTPUT_NAME outname : if specified, outname is the name of the lib when written do disk (eg "ROOTCore" so that libROOTCore.so is installed). If not set, libname will be used. +# EXPORT_NAME exportname : if specified, exportname is the name of the CMake target when downstream projects find_package(ROOT) and want to +# link against it. For example "Core" so that ROOT::Core can be linked against. If not set, libname will be used. # DEPENDENCIES lib1 lib2 : PUBLIC arguments for target_link_library() such as Core, MathCore # BUILTINS builtin1 builtin2 : builtins like xxhash # LINKDEF LinkDef.h : linkdef file, default value is "LinkDef.h" @@ -1361,7 +1375,7 @@ endmacro() #--------------------------------------------------------------------------------------------------- function(ROOT_STANDARD_LIBRARY_PACKAGE libname) set(options NO_INSTALL_HEADERS NO_GLOB_HEADERS STAGE1 NO_HEADERS NO_SOURCES OBJECT_LIBRARY NO_CXXMODULE) - set(oneValueArgs LINKDEF) + set(oneValueArgs LINKDEF OUTPUT_NAME EXPORT_NAME) set(multiValueArgs DEPENDENCIES HEADERS NODEPHEADERS SOURCES BUILTINS LIBRARIES DICTIONARY_OPTIONS INSTALL_OPTIONS) CMAKE_PARSE_ARGUMENTS(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -1445,6 +1459,18 @@ function(ROOT_STANDARD_LIBRARY_PACKAGE libname) "dictionary will be empty. Consider using ROOT_LINKER_LIBRARY instead.") endif() + + if (ARG_OUTPUT_NAME) + # this must go before ROOT_GENERATE_DICTIONARY since that function depends on OUTPUT_NAME target property + set_target_properties(${libname} PROPERTIES OUTPUT_NAME ${ARG_OUTPUT_NAME}) + if (NOT ARG_OUTPUT_NAME STREQUAL "${libname}") + ROOT_SYMLINK_LIBRARY_NAME(${libname} ${ARG_OUTPUT_NAME} ${libname}) # historicalname matches libname + endif() + endif() + if (ARG_EXPORT_NAME) + set_target_properties(${libname} PROPERTIES EXPORT_NAME ${ARG_EXPORT_NAME}) + endif() + ROOT_GENERATE_DICTIONARY(G__${libname} ${ARG_HEADERS} ${NO_CXXMODULE_FLAG} ${STAGE1_FLAG} @@ -1472,6 +1498,7 @@ function(ROOT_STANDARD_LIBRARY_PACKAGE libname) ROOT_INSTALL_HEADERS(${ARG_INSTALL_OPTIONS}) endif() endif() + endfunction() #--------------------------------------------------------------------------------------------------- @@ -3704,3 +3731,37 @@ function (ROOT_GET_CLANG_LIBRARIES clang_libraries) endforeach(extra_lib) SET(${clang_libraries} "${found_libraries}" PARENT_SCOPE) endfunction(ROOT_GET_CLANG_LIBRARIES) + +#--------------------------------------------------------------------------------------------------- +# ROOT_SYMLINK_LIBRARY_NAME( tgt outputname historicalname ) +# +# This function is used when the output name of a target, for example libROOTCore for the +# ROOT::Core target does not match the CMake target name: for backward compatibility, +# it creates a symlink to old historical name, if ROOT built with -Dsymlink_libs=ON (default) +# tgt: the CMake target, for example "Core" +# outputname: the name of the lib when written do disk (eg "ROOTCore" so that libROOTCore.so is installed) +# historicalname: the output-name of the lib being written to disk in CMake target historically. +# Usually, this name was just the name of the CMake target since no separate outputname was set. +#--------------------------------------------------------------------------------------------------- +function (ROOT_SYMLINK_LIBRARY_NAME tgt outputname historicalname) + if (symlink_libs) + get_target_property(target_type ${tgt} TYPE) + if(NOT target_type STREQUAL "INTERFACE_LIBRARY") + add_custom_command(TARGET ${tgt} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink $ ${LIB_PREFIX}${historicalname}${LIB_SUFFIX} + WORKING_DIRECTORY $ + COMMENT "Creating bw-compatibility symlink for target ${tgt}: ${LIB_PREFIX}${historicalname}${LIB_SUFFIX} -> $" + ) + install(CODE " + set(LIB_DIR \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\") + set(NEW_NAME \"${CMAKE_SHARED_LIBRARY_PREFIX}${outputname}${CMAKE_SHARED_LIBRARY_SUFFIX}\") + set(OLD_NAME \"${CMAKE_SHARED_LIBRARY_PREFIX}${historicalname}${CMAKE_SHARED_LIBRARY_SUFFIX}\") + message(STATUS \"Creating symlink for target ${tgt}: \${OLD_NAME} -> \${NEW_NAME}\") + execute_process( + COMMAND \${CMAKE_COMMAND} -E create_symlink \${NEW_NAME} \${OLD_NAME} + WORKING_DIRECTORY \${LIB_DIR} + ) + ") + endif() + endif() +endfunction(ROOT_SYMLINK_LIBRARY_NAME) diff --git a/config/root-config.bat.in b/config/root-config.bat.in index 94ec19363690c..a5cde64035405 100644 --- a/config/root-config.bat.in +++ b/config/root-config.bat.in @@ -59,7 +59,7 @@ set cxxflags=!cxxflags:-FIsehmap.h=-FI"sehmap.h"! set rootglibs=libGui.lib set rootevelibs=libEve.lib libEG.lib libGeom.lib libGed.lib libRGL.lib -set rootlibs=libCore.lib libImt.lib libRIO.lib libNet.lib libHist.lib libGraf.lib libGraf3d.lib libGpad.lib libROOTVecOps.lib libTree.lib libTreePlayer.lib libRint.lib libPostscript.lib libMatrix.lib libPhysics.lib libMathCore.lib libThread.lib +set rootlibs=libCore.lib libImt.lib libRIO.lib libNet.lib libHist.lib libGraf.lib libGraf3d.lib libGpad.lib libROOTVecOps.lib libTree.lib libTreePlayer.lib libROOTRint.lib libPostscript.lib libMatrix.lib libPhysics.lib libMathCore.lib libThread.lib set out= set err=0 diff --git a/config/root-config.in b/config/root-config.in index 55a80b22e8f70..9e9c4848a7569 100755 --- a/config/root-config.in +++ b/config/root-config.in @@ -71,7 +71,7 @@ newlib="-lNew" rootglibs="-lGui" rootevelibs="-lEve -lEG -lGeom -lGed -lRGL" rootlibs="-lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer\ - -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lROOTNTuple -lROOTNTupleUtil" + -lROOTRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lROOTNTuple -lROOTNTupleUtil" # MultiProc is not supported on Windows if test "$platform" != "win32"; then diff --git a/core/README b/core/README index 93e56e5df1e3f..a9cb1bf985f65 100644 --- a/core/README +++ b/core/README @@ -44,7 +44,7 @@ libThread depends on libCore and contains: libNew depends on libCore and contains: - newdelete -libRint depends on libCore and contains: +libROOTRint depends on libCore and contains: - rint libMultiProc depends on explicitly on libCore, libNet, libTreePlayer and diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx index 4603c0bf6979e..552980a0c6323 100644 --- a/core/base/src/TROOT.cxx +++ b/core/base/src/TROOT.cxx @@ -394,7 +394,7 @@ namespace Internal { // // The order of loading for is: // libCore.so - // libRint.so + // libROOTRint.so // ... anything other library hard linked to the executable ... // ... for example libEvent // libCling.so diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 022cc1ddba473..a28ca58c6658f 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -2005,7 +2005,7 @@ bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath, //////////////////////////////////////////////////////////////////////////////// /// List of dicts that have the PCM information already in the PCH. static const std::unordered_set gIgnoredPCMNames = {"libCore", - "libRint", + "libROOTRint", "libThread", "libRIO", "libImt", diff --git a/core/rint/CMakeLists.txt b/core/rint/CMakeLists.txt index 80e9aea0e0fe6..fbf98dfb84ac1 100644 --- a/core/rint/CMakeLists.txt +++ b/core/rint/CMakeLists.txt @@ -16,12 +16,15 @@ ROOT_STANDARD_LIBRARY_PACKAGE(Rint SOURCES src/TRint.cxx src/TTabCom.cxx + OUTPUT_NAME + ROOTRint + EXPORT_NAME + Rint DICTIONARY_OPTIONS -writeEmptyRootPCM DEPENDENCIES Core ) - target_include_directories(Core PRIVATE inc) ROOT_ADD_TEST_SUBDIRECTORY(test) diff --git a/roottest/CMakeLists.txt b/roottest/CMakeLists.txt index 3134f42508411..81c3fa04826e8 100644 --- a/roottest/CMakeLists.txt +++ b/roottest/CMakeLists.txt @@ -55,7 +55,7 @@ if(MSVC) if(CMAKE_GENERATOR MATCHES Ninja) set(ROOT_LIBRARIES Core RIO Net Hist Gpad Graf Tree Rint Matrix MathCore) else() - set(ROOT_LIBRARIES libCore libRIO libNet libHist libGpad libGraf libTree libRint libMatrix libMathCore) + set(ROOT_LIBRARIES libCore libRIO libNet libHist libGpad libGraf libTree libROOTRint libMatrix libMathCore) endif() else() # We can not use CMAKE_SHARED_LIBRARY_SUFFIX as on macos it uses the standard dylib rather than the .so diff --git a/roottest/root/rint/CMakeLists.txt b/roottest/root/rint/CMakeLists.txt index 6d3d442dbe2ec..d7b0449805171 100644 --- a/roottest/root/rint/CMakeLists.txt +++ b/roottest/root/rint/CMakeLists.txt @@ -2,7 +2,7 @@ if (NOT MSVC) # ROOT-5843 ROOTTEST_ADD_TEST(dotLibraries COMMAND $ -b -q -e ".libraries" - PASSREGEX "libRint") + PASSREGEX "libROOTRint") ROOTTEST_ADD_TEST(TabCom COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/driveTabCom.py