12/11/2014

How to CMake MyProject together with ROOT GUI

I have MyProject composed of source files

myProject/c++/src/myMain.cpp
myProject/c++/include/myMain.h
myProject/c++/include/myMainLinkDef.h

to run on ROOT GUI. In myMain.cpp, a class MyMainGUI is called in a loop of  TApplication. In myMain.h,  this class is declared with the first line

    RQ_OBJECT("myMainGui").

myMainLinkDef.h includes pragma comment lines which look like

#pragma link C++ class MyMainGUI;
#pragma link C++ class mylib::MyFunction;

where mylib::MyFunction is a class used in ROOT GUI and given in

/somewhere/myLibrary/myLib.h
/somewhere/myLibrary/libmyLib.a

Problem: Compose a cmake package to build MyProject in an arbitrary directory myWKDIR.

I describe a solution in the following.

1. Prepare myProject/c++/CMakeLists.txt (presupposition: ROOT version 5.34):
==========================================================
cmake_minimum_required(VERSION 2.8)

set(CMAKE_VERBOSE_MAKEFILE 1)
#is convenient for debugging the make process.

project(MyProject)

set(CMAKE_CXX_COMPILER g++)
# since I used g++ to compile libmyLib.a

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/..)
#since I'm going to build MyProject in myWKDIR/build/
#so that ${PROJECT_BINARY_DIR}/.. means myWKDIR.

#Prepare for the ROOT GUI
#-------------------------------------
#imitating geant4/examples/analysis/AnaEx02
#/////////////////////////////////////////////////////////////////////
find_package(ROOT REQUIRED)
find_program(ROOT_CINT_EXECUTABLE rootcint PATHS ${ROOT_DIR}/bin NO_DEFAULT_PATH})

#External Libraries to be linked
#---------------------------------------
set(myLibrary_DIR /somewhere/myLibrary)
add_library(MyLib STATIC IMPORTED)
set_property(TARGET MyLib PROPERTY
IMPORTED_LOCATION ${myLibrary_DIR}/libmyLib.a)
#Other ways to include libmyLib.a in the ld process is to specify this library in
#CMAKE_EXE_LINKER_FLAGS as
#-L${myLibrary_DIR} -lmyLib
#or find_library(MyLib myLib PATHS ${myLibrary_DIR})
#and include MyLib in target_link_libraries.

#building a dictionary for ROOT GUI
#------------------------------------------------
set(INCLUDE_DIRECTORIES
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
${myLibrary_DIR}
${ROOT_INCLUDE_DIR}
)
include_directories(${INCLUDE_DIRECTORIES})

#generate the dictionary
#the following part is imported from http://lcio.desy.de/v01-60/cmake/MacroRootDict.cmake
set(MAINPRGM "myMain")
set(headers include/myMain.h)
set( _dict_includes )
FOREACH( _inc ${INCLUDE_DIRECTORIES} )
SET( _dict_includes "${_dict_includes}\t-I${_inc}")
ENDFOREACH()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${MAINPRGM}Dict.cpp ${CMAKE_CURRENT_BINARY_DIR}/${MAINPRGM}Dict.h
COMMAND ${ROOT_CINT_EXECUTABLE} -f ${CMAKE_CURRENT_BINARY_DIR}/${MAINPRGM}Dict.cpp -c ${_dict_includes} ${headers} include/${MAINPRGM}LinkDef.h
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS ${headers} include/${MAINPRGM}LinkDef.h
COMMENT "generating: ${MAINPRGM}Dict.cpp ${MAINPRGM}Dict.h"
)
list(APPEND headers ${CMAKE_CURRENT_BINARY_DIR}/${MAINPRGM}Dict.h)

#build the target
#-------------------------
#prepare for the ld flag
execute_process(COMMAND root-config --glibs OUTPUT_VARIABLE     
               ROOT_LD_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)                 
set(CMAKE_EXE_LINKER_FLAGS "${ROOT_LD_FLAGS}")

#destination
set(sources src/myMain.cpp
${CMAKE_CURRENT_BINARY_DIR}/${MAINPRGM}Dict.cpp
)
add_executable(${PROJECT_NAME}.exe ${sources} ${headers})
target_link_libraries(${PROJECT_NAME}.exe MyLib)

2. build MyProject in myWKDIR
============================
> mkdir myWKDIR
> mkdir myWKDIR/build
cd myWKDIR/build
myWKDIR/build> cmake /directory_path_to/myProject/c++
myWKDIR/build> make

Any comments are welcome.

No comments:

Post a Comment