plustab(GaudiProjectConfig) # - GaudiProject # Define the macros used by Gaudi-based projects, namely: # GAUDI_PROJECT(project version) : declare a project with it's version number # GAUDI_USE_PROJECT(project version) : declare the dependency on another project # # Authors: Pere Mato, Marco Clemencic tabmessage("GaudiProjectConfig> ") cmake_minimum_required(VERSION 2.4.6) cmake_policy(SET CMP0003 NEW) # See "cmake --help-policy CMP0003" for more details cmake_policy(SET CMP0011 NEW) # See "cmake --help-policy CMP0011" for more details cmake_policy(SET CMP0009 NEW) # See "cmake --help-policy CMP0009" for more details # Add the directory containing this file to the modules search path #set(CMAKE_MODULE_PATH ${GaudiProject_DIR} ${CMAKE_MODULE_PATH}) if(WIN32) set(ld_library_path PATH) elseif(APPLE) set(ld_library_path DYLD_LIBRARY_PATH) else() set(ld_library_path LD_LIBRARY_PATH) endif() moinstab() #--------------------------------------------------------------------------------------------------- #---GAUDI_PROJECT(project version) #--------------------------------------------------------------------------------------------------- macro(GAUDI_PROJECT project_name version) plustab(GAUDI_PROJECT) set(GaudiProject_DIR ${CMAKE_SOURCE_DIR}) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) tabmessage("GAUDI_PROJECT> CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR} CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") string(TOUPPER ${project_name} project) project(${project}) tabmessage("GAUDI_PROJECT> GaudiProject_DIR=${GaudiProject_DIR}") set(CMAKE_PROJECT_NAME ${project}) #----For some reason this is not set by calling 'project()' #--- Define the version of the project - can be used to generate sources, tabmessage("GAUDI_PROJECT> Define the version of the project - version=${version}") set(${project}_VERSION ${version}) if( ${version} MATCHES "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)") string(REGEX REPLACE "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)" "\\1" major ${version}) string(REGEX REPLACE "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)" "\\2" minor ${version}) string(REGEX REPLACE "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)" "\\3" patch ${version}) elseif(${version} MATCHES "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)") string(REGEX REPLACE "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)" "\\1" major ${version}) string(REGEX REPLACE "[a-zA-Z]+([0-9]+)[a-zA-Z]+([0-9]+)" "\\2" minor ${version}) set( patch 0) endif() set(${project}_VERSION_MAJOR ${major}) set(${project}_VERSION_MINOR ${minor}) set(${project}_VERSION_PATCH ${patch}) #--- Project Options and Global settings---------------------------------------------------------- tabmessage("GAUDI_PROJECT> Project Options and Global settings") option(BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON) option(BUILD_TESTS "Set to ON to build the tests (libraries and executables)" OFF) option(HIDE_WARNINGS "Turn on or off options that are used to hide warning messages" ON) #------------------------------------------------------------------------------------------------- #--- Build type and tag strings------------------------------------------------------------------- tabmessage("GAUDI_PROJECT> Build type and tag strings") set(opt2buildtype Release) set(dbg2buildtype Debug) set(Debug2type dbg) set(Release2type opt) if(DEFINED ENV{CMAKECONFIG}) set(tag $ENV{CMAKECONFIG}) elseif(DEFINED ENV{CMTCONFIG}) set(tag $ENV{CMTCONFIG}) else() GAUDI_BINARY_TAG(tag) endif() string(REGEX MATCHALL "[^-]+" out "${tag}") tabmessage("GAUDI_PROJECT> out=${out}") list(GET out 0 arch) list(GET out 1 os) list(GET out 2 comp) list(GET out 3 type) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${${type}2buildtype} CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() set(BINARY_TAG_PREFIX ${arch}-${os}-${comp} CACHE STRING "Installation binary tag prefix. The final tag will be made using the BUILD_TYPE" ) set(BINARY_TAG ${BINARY_TAG_PREFIX}-${${CMAKE_BUILD_TYPE}2type}) tabmessage("GAUDI_PROJECT> BINARY_TAG=${BINARY_TAG}") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/InstallArea/${BINARY_TAG} CACHE PATH "Install path prefix, prepended onto install directories." FORCE ) endif() if(NOT BUILD_OUTPUT_PREFIX) set(BUILD_OUTPUT_PREFIX ${CMAKE_BINARY_DIR}/.build CACHE STRING "Base directory for generated files" FORCE) endif() if(NOT EXECUTABLE_OUTPUT_PATH) set(EXECUTABLE_OUTPUT_PATH ${BUILD_OUTPUT_PREFIX}/bin CACHE STRING "Single build output directory for all executables" FORCE) endif() tabmessage("GAUDI_PROJECT> EXECUTABLE_OUTPUT_PATH=${EXECUTABLE_OUTPUT_PATH}") if(NOT LIBRARY_OUTPUT_PATH) set(LIBRARY_OUTPUT_PATH ${BUILD_OUTPUT_PREFIX}/lib CACHE STRING "Single build output directory for all libraries" FORCE) endif() if(NOT PYTHON_OUTPUT_PATH) set(PYTHON_OUTPUT_PATH ${BUILD_OUTPUT_PREFIX}/python CACHE STRING "Single build output directory for all python files" FORCE) endif() if(BUILD_TESTS) enable_testing() endif() #--- Project Installations------------------------------------------------------------------------ tabmessage("GAUDI_PROJECT> (I) DIRECTORY cmake/ ") install(DIRECTORY cmake/ DESTINATION cmake FILES_MATCHING PATTERN "*.cmake" PATTERN ".svn" EXCLUDE ) tabmessage("GAUDI_PROJECT> (I) PROGRAMS cmake/testwrap.sh cmake/testwrap.csh cmake/testwrap.bat cmake/genCMake.py cmake/env.py") install(PROGRAMS cmake/testwrap.sh cmake/testwrap.csh cmake/testwrap.bat cmake/genCMake.py cmake/env.py DESTINATION scripts) #--- Global actions for the project tabmessage("GAUDI_PROJECT> Global actions for the project ") INCLUDE(GaudiPolicy) tabmessage("GAUDI_PROJECT> now call GAUDI_GET_PACKAGES") GAUDI_GET_PACKAGES(packages) #GAUDI_SORT_PACKAGES(packages ${packages}) foreach(package ${packages}) tabmessage("GAUDI_PROJECT> -- Adding directory ${package}") add_subdirectory(${package}) endforeach() tabmessage("GAUDI_PROJECT> now call GAUDI_PROJECT_VERSION_HEADER") GAUDI_PROJECT_VERSION_HEADER() tabmessage("GAUDI_PROJECT> now call GAUDI_BUILD_PROJECT_SETUP") GAUDI_BUILD_PROJECT_SETUP() tabmessage("GAUDI_PROJECT> now call GAUDI_MERGE_TARGET for ConfDB Rootmap DictRootmap") GAUDI_MERGE_TARGET(ConfDB python ${CMAKE_PROJECT_NAME}_merged_confDb.py) GAUDI_MERGE_TARGET(Rootmap lib ${CMAKE_PROJECT_NAME}.rootmap) GAUDI_MERGE_TARGET(DictRootmap lib ${CMAKE_PROJECT_NAME}Dict.rootmap) #GAUDI_USE_PACKAGE(QMtest) #GAUDI_USE_PACKAGE(pytools) #GAUDI_USE_PACKAGE(RELAX) #SET( QMtest_environment ${QMtest_environment} QMTEST_CLASS_PATH=${CMAKE_SOURCE_DIR}/GaudiPolicy/qmtest_classes ) #--- CPack configuration tabmessage("GAUDI_PROJECT> CPack configuration") set(CPACK_PACKAGE_NAME ${project_name}) foreach(t MAJOR MINOR PATCH) set(CPACK_PACKAGE_VERSION_${t} ${${project}_VERSION_${t}}) endforeach() set(CPACK_SYSTEM_NAME ${BINARY_TAG}) set(CPACK_GENERATOR TGZ) include(CPack) moinstab() endmacro() #--------------------------------------------------------------------------------------------------- #---GAUDI_BINARY_TAG() #--------------------------------------------------------------------------------------------------- function(GAUDI_BINARY_TAG) plustab(GAUDI_BINARY_TAG) tabmessage("GAUDI_BINARY_TAG> CMAKE_SYSTEM --> ${CMAKE_SYSTEM}") execute_process(COMMAND uname -i OUTPUT_VARIABLE arch) tabmessage("GAUDI_BINARY_TAG> arch --> ${arch}") moinstab() endfunction() #--------------------------------------------------------------------------------------------------- #---GAUDI_FIND_PROJECT(project version) #--------------------------------------------------------------------------------------------------- macro( GAUDI_FIND_PROJECT project version) plustab(GAUDI_FIND_PROJECT) file(TO_CMAKE_PATH "$ENV{CMAKEPROJECTPATH}" projectpath) foreach( path ${projectpath}) if(EXISTS ${path}/${project}) if(${version} STREQUAL "*") file(GLOB installations ${path}/${project}/${project}_* ) foreach( installation ${installations}) if(EXISTS ${installation}/InstallArea/${BINARY_TAG}/cmake ) set(${project}_installation ${installation}) break() endif() endforeach() else() if(EXISTS ${path}/${project}/${project}_${version}/InstallArea/${BINARY_TAG}/cmake) set(${project}_installation ${path}/${project}/${project}_${version}) break() endif() endif() endif() if(${project}_found) break() endif() endforeach() if( ${project}_installation ) tabmessage("GAUDI_FIND_PROJECT> Found project ${project} with version ${version} at ${${project}_installation}") set(${project}_found 1) set(${project}_installarea ${${project}_installation}/InstallArea) set(${project}_binaryarea ${${project}_installation}/InstallArea/${BINARY_TAG}) else() tabmessage(ERROR "GAUDI_FIND_PROJECT> Project ${project} with version ${version} not found!!") endif() moinstab() endmacro() #--------------------------------------------------------------------------------------------------- #---GAUDI_USE_PROJECT(project version) #--------------------------------------------------------------------------------------------------- macro( GAUDI_USE_PROJECT project version ) if( NOT ${project}_used ) GAUDI_FIND_PROJECT(${project} ${version}) if( ${project}_installation ) #------Set the list of variables to make a effective 'use' of the project----- get_property(projects GLOBAL PROPERTY PROJECTS_FOUND) set_property(GLOBAL PROPERTY PROJECTS_FOUND ${projects} ${project}) get_property(projects GLOBAL PROPERTY PROJECTS_FOUND) set(CMAKE_MODULE_PATH ${${project}_binaryarea}/cmake ${CMAKE_MODULE_PATH}) include_directories( ${${project}_binaryarea}/include ) link_directories( ${${project}_binaryarea}/lib ) set(${project}_environment ${ld_library_path}+=${${project}_binaryarea}/lib PATH+=${${project}_binaryarea}/bin PATH+=${${project}_binaryarea}/scripts PYTHONPATH+=${${project}_binaryarea}/python ) include(${project}Exports) set(${project}_used 1) #------------------------------------------------------------------------------ if( EXISTS ${${project}_installation}/CMakeLists.txt) file(READ ${${project}_installation}/CMakeLists.txt file_contents) string( REGEX MATCHALL "GAUDI_USE_PROJECT[ ]*[(][ ]*([^)])+" vars ${file_contents}) foreach( var ${vars}) string(REGEX REPLACE "GAUDI_USE_PROJECT[ ]*[(][ ]*([^)])" "\\1" p ${var}) separate_arguments(p) GAUDI_USE_PROJECT(${p}) endforeach() endif() endif() endif() endmacro() #--------------------------------------------------------------------------------------------------- #---GAUDI_SORT_PACKAGES #--------------------------------------------------------------------------------------------------- macro(__visit__ _p) if( NOT __${_p}_visited__) set(__${_p}_visited__ 1) #---list all dependent packages----- if( EXISTS ${CMAKE_SOURCE_DIR}/${_p}/CMakeLists.txt) file(READ ${CMAKE_SOURCE_DIR}/${_p}/CMakeLists.txt file_contents) string( REGEX MATCHALL "GAUDI_USE_PACKAGE[ ]*[(][ ]*([^ )])+" vars ${file_contents}) foreach( var ${vars}) string(REGEX REPLACE "GAUDI_USE_PACKAGE[ ]*[(][ ]*([^ )])" "\\1" __p ${var}) __visit__(${__p}) endforeach() set(out_packages ${out_packages} ${_p}) endif() endif() endmacro() function(GAUDI_SORT_PACKAGES var) set(out_packages) set(in_packages ${ARGN}) foreach(p ${in_packages}) __visit__(${p}) endforeach() set(${var} ${out_packages} PARENT_SCOPE) endfunction() #--------------------------------------------------------------------------------------------------- #---GAUDI_GET_PACKAGES #--------------------------------------------------------------------------------------------------- function( GAUDI_GET_PACKAGES var) plustab(GAUDI_GET_PACKAGES) set( packages ) file(GLOB_RECURSE cmakelist_files ${CMAKE_SOURCE_DIR} CMakeLists.txt) tabmessage("GAUDI_GET_PACKAGES> CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR} cmakelist_files=${cmakelist_files}") foreach( file ${cmakelist_files} ) get_filename_component(path ${file} PATH) if( NOT path STREQUAL ${CMAKE_SOURCE_DIR}) string(REPLACE ${CMAKE_SOURCE_DIR}/ "" package ${path}) SET(packages ${packages} ${package}) endif() endforeach() set(${var} ${packages} PARENT_SCOPE) moinstab() endfunction() #--------------------------------------------------------------------------------------------------- #---GAUDI_MERGE_TARGET #--------------------------------------------------------------------------------------------------- # Create a MergedXXX target that takes input files and dependencies from # properties of the packages function(GAUDI_MERGE_TARGET tgt dest filename) plustab(GAUDI_MERGE_TARGET) # Check if one of the packages produces files for this merge target get_property(needed GLOBAL PROPERTY Merged${tgt}_SOURCES SET) if(needed) # get the list of parts to merge get_property(parts GLOBAL PROPERTY Merged${tgt}_SOURCES) # create the targets set(output ${BUILD_OUTPUT_PREFIX}/${dest}/${filename}) tabmessage("GAUDI_MERGE_TARGET> (CC) ${merge_cmd} OUTPUT ${output}") add_custom_command(OUTPUT ${output} COMMAND ${merge_cmd} ${parts} ${output} DEPENDS ${parts}) tabmessage("GAUDI_MERGE_TARGET> (CT) Merged${tgt} ") add_custom_target(Merged${tgt} ALL DEPENDS ${output}) # prepare the high level dependencies get_property(deps GLOBAL PROPERTY Merged${tgt}_DEPENDS) tabmessage("GAUDI_MERGE_TARGET> (AD) Merged${tgt} ") add_dependencies(Merged${tgt} ${deps}) # install rule for the merged DB tabmessage("GAUDI_MERGE_TARGET> (I) FILES ${output} ") install(FILES ${output} DESTINATION ${dest}) endif() moinstab() endfunction()