Incostistency in building library with cmake for ROOT-5/6

There is inconsistency in cmake/modules/RootNewMacros.cmake scripts in root 5 and 6 for ROOT_LINKER_LIBRARY macro.

In ROOT-5.34.30, line 337

In ROOT-6.03.03, line 441

I guess in ROOT-5 it is incorrect, makes no logical sense to check for runtime location when installing library. Workaround in the CMakeFiles.txt for (my custom) library is to define both variables, but then I still consider it as a bug. I don’t know if changing it will break root-5 installation, was to lazy to recompile whole root just for fun.

Bonus question: why using autotools (./configure) does not install ${ROOTSYS}/cmake ? Using autotools does not mean that there will not be other users using cmake for building own code. Specially, that you install etc/cmake/FindRoot.cmake.

The macro ROOT_LINKER_LIBRARY() was intended for inernal consumption to build all the ROOT libraries and not for user consumption. The logic with CMAKE_RUNTIME_OUTPUT_DIRECTORY and ARG_TEST is to be able to use the same macro also for building ROOT tests. In case of building libraries used in tests we do not want them to be installed in the $ROOTSYS/lib, and thus the installation declaration is skip. The argument ARG_TEST is for the same purpose. If you specify ROOT_LINKER_LIBRARY(… TEST) the library will be build but not installed. Additionally, if CMAKE_RUNTIME_OUTPUT_DIRECTORY is not defined (the case for tests) the libraries are build in the current binary directory.

I am not sure that I would recommend to use ROOT_LINKER_LIBRARY() to build user libraries. This is why is not there for the configure/make case. The main reason is because I cannot make assumptions on way the user wants to control the installation, and other build steps. I think I would recommend is to use vanilla CMake as much as possible. For example:

# CMakeLists.txt for event package. It creates a library with dictionary and a main program
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(event)

# You need to tell CMake where to find the ROOT installation. This can be done in a number of ways:
#   - ROOT built with classic configure/make use the provided $ROOTSYS/etc/cmake/FindROOT.cmake
#   - ROOT built with CMake. Add in CMAKE_PREFIX_PATH the installation prefix for ROOT
list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})

#---Locate the ROOT package and defines a number of variables (e.g. ROOT_INCLUDE_DIRS)
find_package(ROOT REQUIRED COMPONENTS MathCore RIO Hist Tree Net)

#---Define useful ROOT functions and macros (e.g. ROOT_GENERATE_DICTIONARY)
include(${ROOT_USE_FILE})  # only defined if ROOT is built with CMake

include_directories(${CMAKE_SOURCE_DIR} ${ROOT_INCLUDE_DIRS})
add_definitions(${ROOT_CXX_FLAGS})

ROOT_GENERATE_DICTIONARY(G__Event Event.h LINKDEF EventLinkDef.h)

#---Create a shared library with geneated dictionary
add_library(Event SHARED Event.cxx G__Event.cxx)
target_link_libraries(Event ${ROOT_LIBRARIES})

#---Create  a main program using the library
add_executable(Main MainEvent.cxx)
target_link_libraries(Main Event)

Well, I found this macro very useful. In principle, it does all what I want to do when building my library. But I am not calling this directly, I am rather using ROOT_STANDARD_LIBRARY_PACKAGE to do so. Then I have dictionary generation, rootmap creation and installation of headers all-in-one, here is my example:
github.com/dziadu/SmartFactory/ … eLists.txt

I would really consider this as a very usefull macro for user consumption. It does all it need and reduces risk of possible errors.

Only what I found strange is that for root5 you use RUNTIME location and for root6 LIBRARY. I see the point that you want to use RUNTIME variable to control installation of test libraries, bit then, why one should do such workaround. Isn’t it better to backport solution from root6 to root5?

Pay attention, that you mixed the facts: ARG_TESTS is checked together with CMAKE_LIBRARY_OUTPUT_DIRECTORY in root6, not with CMAKE_RUNTIME_OUTPUT_DIRECTORY. The letter one is checked in root5 only. Maybe I don’t see all the details, but why can’t you use a CMAKE_LIBRARY_OUTPUT_DIRECTORY variable in root5 to determine whether library should be installed (for regular one) or not (for tests)? If I remember. this variable must by set because is utilised by dictionary generator, but then I would really go for ARGS_TEST in root 5. This solutions looks cleverest.

I didn’t notice the difference the first time. Thanks for reporting it. On the practical side it doesn’t have any effect since we set both when we build the ROOT libraries since we need to support Windows. The CMAKE_RUNTIME_OUTPUT_DIRECTORY is where the .dll files will be built.
I agree that the best will be to be explicit and use the argument TEST when there is no need to be installed. Or even better to define a new argument NO_INSTALL no make it even more clear. However using the high level macro ROOT_STANDARD_LIBRARY_PACKAGE will not be able to specify it.

JIRA ticket: sft.its.cern.ch/jira/browse/ROOT-7402

Are you sure your JIRA ticket belongs (in content) to this thread?

Corrected the JIRA number and committed fixes to GIT.