Compiling a CMake project using ROOT not compiled with CMake

Hi,

I am not sure if this is the right place to post this or if you prefer this to be posted in JIRA (should JIRA be used for any issue instead of rootalk or just for bug reporst?).

I have an analysis framework that I am developing and now I have moved to compile with CMake and I am having issues including ROOT as library of the project. What I am doing, and works perfectly, is to add this to my main CMakeLists.txt

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

Nonetheless this only works if ROOT has been compiled with CMake instead of the old configure/make install. This is not the case in some systems where the framework is being used due to old version of CMake. I have tried including the FindRoot.cmake macro in this way:

# Add ROOT
if(EXISTS "$ENV{ROOTSYS}/CMakeFiles")
    # ROOT has been compiled with CMake
    list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})
else()
    #ROOT has been compiled with traditional configure/make
    include($ENV{ROOTSYS}/etc/cmake/FindROOT.cmake)
endif()

This should be able to tell which compilation method was used and properly choose the proper way of including root, this is whay I assume but this is not the case. When I try to compile I get erro like these:

CMake Error at /share/apps/root_v6.04.08/etc/cmake/FindROOT.cmake:49 (list):
  list sub-command REMOVE_ITEM requires list to be present.
Call Stack (most recent call first):
  CMakeLists.txt:20 (include)

So I am thinking that either this is not the proper way of including root libraries inside the project or that I cannot use the Root CMake macros because of an old version of CMake. I cannot require CMake version to be the same as ROOT’s since this will make the compilation not possible in such system.

What would be the proper way of handling this when ROOT has not been compiled with CMake? And how should I add the proper flags and libraries to be used?

Thanks!
Juanpe.

Hi again,

I have changed the code to this:

# Check that ROOT in installed in the system
if(EXISTS "$ENV{ROOTSYS}/CMakeFiles")
    # ROOT has been compiled with CMake
    list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})
else()
    #ROOT has been compiled with traditional configure/make
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "$ENV{ROOTSYS}/ect/cmake/")
endif()
find_package(ROOT REQUIRED)

which now is not throwing any error (I am sure I was doing it wrong before). Nonetheless the compilation now fails saying that atomic is not a file or a directory and several erros that seem to me that things are not being properly included. I am attaching the top level CMakeLists and one of the subidrectories as well as the compilation errors.

Thanks!
Juanpe.
errorlog.txt (48.2 KB)
SubdirCMakeLists.txt (384 Bytes)
TopLevelCMakeLists.txt (1.02 KB)

Hi Juanpe,

It is the right place. JIRA should be reserved for issues that are agreed to be bugs or new features to be implemented. For support questions this forum is the adequate media.

Have a look at the Howto page root.cern.ch/how/integrate-root … ject-cmake
In both cases you need to use find_package(ROOT …), what changes is the setting of CMAKE_PREFIX_PATH or CMAKE_MODULE_PATH. Something like this should work:

# You need to tell CMake where to find the ROOT installation. This can be done in a number of ways:
if(EXISTS $ENV{ROOTSYS/cmake/ROOTConfig.cmake)
  list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})
else()
  list(APPEND CMAKE_MODULE_PATH $ENV{ROOTSYS}/etc/cmake
endif()

find_package(ROOT REQUIRED COMPONENTS RIO Net)
include(${ROOT_USE_FILE})

Cheers, Pere

Hi Mato,

thanks a lot for the quick reply. Sorry I posted shortly after my first comment but as you see I think I found the issue with my previous setup and now I am using what you mention. The only difference is that I didn’t include ROOT_USE_FILE, what is it that it does? If I don’t include it I get the error messages I attached in my previous comment but if I use it I get this error

-- Build files have been written to: /home/jaraque/npatest/build
Scanning dependencies of target NPATools
[  5%] Building CXX object tools/CMakeFiles/NPATools.dir/NPALog.cxx.o
cc1plus: error: unrecognized command line option "-std=c++11"
cc1plus: error: unrecognized command line option "-std=c++11"
make[2]: *** [tools/CMakeFiles/NPATools.dir/NPALog.cxx.o] Error 1
make[1]: *** [tools/CMakeFiles/NPATools.dir/all] Error 2
make: *** [all] Error 2

which is odd since it seems to me that it points to the compiler not supporting C++11 but it does:

14:55 $ g++ --version
g++ (GCC) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Do you know what I might be missing?

Thanks again,
Juanpe.

It extends the compilation flags, include and libraries with the ROOT ones (in particular -std=c++11)

#---Set Link and include directories--------------------------------------------------------------
include_directories(${ROOT_INCLUDE_DIRS})
link_directories(${ROOT_LIBRARY_DIR})

#---Set Flags-------------------------------------------------------------------------------------
add_definitions(${ROOT_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ROOT_CXX_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ROOT_C_FLAGS}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${ROOT_fortran_FLAGS}")

My only explanation is that you are not using the compiler you think you are using. What the output of cmake says on a clean build area?
Cheers, Pere

Hi Pere,

you are right, I have been trying different things and when doing cmake VERBOSE=1 I see that the compiler being used is /usr/bin/c++ which an older version. In a clean build area I get this

15:39 $ cmake ..
-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler: /usr/bin/cc
...

But in this system /usr/bin/cc is an old compiler. I have my own compiler version installed in my home in that system which is properly loaded in PATH and when I was using autotools previously to compile this code the proper compiler was being used. I am not sure why CMake is not finding it.

I tested to see if it was an issue with the ordering (i.e. PATH=mygcc:$PATH vs PATH=$PATH:mygcc) but it doesn’t matter how I put it, it never finds my the proper version of gcc…

I know that his question is no longer related with ROOT but do you know how could I fix this or have you seen this happening before? I am sure you are much more experienced with CMake that I am (which just learned it some days ago :slight_smile:)

Thanks a lot!
Juanpe.

Basically you have two options:

  • Set the compiler explicitly in the cmake command
-DCMAKE_C_COMPILER=/path/to/your/c/compiler/executable \
-DCMAKE_CXX_COMPILER=/path/to/your/cpp/compiler/executable
  • Or set the CC and CXX environment variables before invoking cmake
export CC=/path/to/your/c/compiler/executable
export CXX=/path/to/your/cpp/compiler/executable

Cheers, Pere

Hi again Pere,

it seems that I can manually specify the compiler without having to force it int he CMakeLists.txt and to the following

16:05 $ cmake -D CMAKE_CXX_COMPILER=gcc ..
-- Configuring done
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_CXX_COMPILER= gcc

-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /home/jaraque/gcc48/bin/gcc
-- Check for working CXX compiler: /home/jaraque/gcc48/bin/gcc -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jaraque/npatest/build

In that way it seems to find it and compile. I find it weird that having added the line

set(CMAKE_CXX_STANDARD_REQUIRED 11)

to the file and having a valid gcc compiler CMake seems unable to find it… I am not sure if there is something else I should be doing but I thought that CMake would be smart enough to identify the proper compiler with the required options.

Well, it seems that we can live for now. I still have to keep checking that everything seems to work well in any case.

Thanks!
Juanpe.

EDIT: It seems that you answered before I posted this comment. Thanks a lot!