# - PackageSpecial # Some special thing about defining a package # SET(myindent "${myindent}\t") message(STATUS "${myindent}# \"PackageSpecial\" included!") if(__PackageSpecial_INCLUDED) return() endif() set(__PackageSpecial_INCLUDED TRUE) macro(icedust_package_special name version) message(STATUS "${myindent}==>macro(icedust_package_special ${name} ${version})") SET(myindent "${myindent}\t") message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Creating a projcet") # Add a project with the package name project(${package_name}) #----For some reason this is not set by calling 'project()' set(CMAKE_PROJECT_NAME ${package_name}) #--- Define the version of the project - can be used to generate sources, set(CMAKE_PROJECT_VERSION ${package_version} CACHE STRING "Version of the project") # TODO: Where does the ARGN come from? #--- Parse the other arguments on the # CMAKE_PARSE_ARGUMENTS(PROJECT "" "" "USE;DATA" ${ARGN}) # if (PROJECT_UNPARSED_ARGUMENTS) # message(FATAL_ERROR "Wrong arguments.") # endif() # TODO: be careful, we may need another version syntax if(NOT CMAKE_PROJECT_VERSION MATCHES "^HEAD.*") string(REGEX MATCH "v?([0-9]+)[r.]([0-9]+)([p.]([0-9]+))?" _version ${CMAKE_PROJECT_VERSION}) set(CMAKE_PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1} CACHE INTERNAL "Major version of project") set(CMAKE_PROJECT_VERSION_MINOR ${CMAKE_MATCH_2} CACHE INTERNAL "Minor version of project") set(CMAKE_PROJECT_VERSION_PATCH ${CMAKE_MATCH_4} CACHE INTERNAL "Patch version of project") else() # 'HEAD' version is special set(CMAKE_PROJECT_VERSION_MAJOR 999) set(CMAKE_PROJECT_VERSION_MINOR 999) set(CMAKE_PROJECT_VERSION_PATCH 0) endif() #--- Project Options and Global settings---------------------------------------------------------- option(BUILD_SHARED_LIBS "Set to OFF to build static libraries." ON) option(ICEDUST_BUILD_TESTS "Set to OFF to disable the build of the tests (libraries and executables)." ON) option(ICEDUST_HIDE_WARNINGS "Turn on or off options that are used to hide warning messages." ON) option(ICEDUST_USE_EXE_SUFFIX "Add the .exe suffix to executables on Unix systems (like CMT does)." ON) #------------------------------------------------------------------------------------------------- set(ICEDUST_DATA_SUFFIXES DBASE;PARAM;EXTRAPACKAGES CACHE STRING "List of (suffix) directories where to look for data packages.") message(STATUS "${myindent} ICEDUST_DATA_SUFFIXES = (${ICEDUST_DATA_SUFFIXES})") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) message(STATUS "${myindent} CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT") set(CMAKE_INSTALL_PREFIX ${package_dir}/build.${CMAKE_SYSTEM} CACHE PATH "Install path prefix, prepended onto install directories." FORCE ) endif() message(STATUS "${myindent} CMAKE_INSTALL_PREFIX = (${CMAKE_INSTALL_PREFIX})") set(CMAKE_BINARY_DIR ${CMAKE_INSTALL_PREFIX}) message(STATUS "${myindent} CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}") if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE STRING "Single build output directory for all executables" FORCE) endif() message(STATUS "${myindent} CMAKE_RUNTIME_OUTPUT_DIRECTORY = ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE STRING "Single build output directory for all libraries" FORCE) endif() message(STATUS "${myindent} CMAKE_LIBRARY_OUTPUT_DIRECTORY = ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") set(env_xml ${CMAKE_BINARY_DIR}/${project}BuildEnvironment.xml CACHE STRING "path to the XML file for the environment to be used in building and testing") set(env_release_xml ${CMAKE_BINARY_DIR}/${project}Environment.xml CACHE STRING "path to the XML file for the environment to be used once the project is installed") mark_as_advanced(CMAKE_RUNTIME_OUTPUT_DIRECTORY CMAKE_LIBRARY_OUTPUT_DIRECTORY env_xml env_release_xml) if(ICEDUST_BUILD_TESTS) message(STATUS "${myindent} enable_testing") enable_testing() endif() message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Deal with environment and control procedures") # About environment settings set(SETENVSH ${package_dir}/cmake/env.sh) message(STATUS "${myindent} SETENVSH=${SETENVSH}") string(TOUPPER ${package_name} PACKAGENAME) FILE(WRITE ${SETENVSH} "export ${PACKAGENAME}ROOT=\"${package_dir}\" export ${PACKAGENAME}_tag=\"${CMAKE_SYSTEM}\"") # paths where to locate scripts and executables # Note: it's a bit a duplicate of the one used in icedust_external_project_environment # but we need it here because the other one is meant to include also # the external libraries required by the subdirectories. set(binary_paths) # environment description set(project_environment) set(used_icedust_projects) # TODO: Do we need to specify project and package apart? # # Locate and import used projects. # message(STATUS "${myindent} PROJECT_USE = "${PROJECT_USE}) # if(PROJECT_USE) # _icedust_use_other_projects(${PROJECT_USE}) # endif() # if(used_icedust_projects) # list(REMOVE_DUPLICATES used_icedust_projects) # endif() # TODO: DO we need? # # Find the required data packages and add them to the environment. # message(STATUS "${myindent} PROJECT_DATA = "${PROJECT_DATA}) # _icedust_handle_data_packages(${PROJECT_DATA}) #--- commands required to build cached variable # (python scripts are located as such but run through python) # TODO: probably we need more directories set(binary_paths ${package_dir}/bin ${package_dir}/cmake/bin ${icedust_cmake_dir}/bin) message(STATUS "${myindent} binary_paths = ${binary_paths}") # TODO: We need to either modify this script or write another find_program(env_cmd env.py HINTS ${binary_paths}) set(env_cmd ${PYTHON_EXECUTABLE} ${env_cmd}) message(STATUS "${myindent} env_cmd = ${env_cmd}") # TODO: Do we need these functions? ## find_program(merge_cmd merge_files.py HINTS ${binary_paths}) ## set(merge_cmd ${PYTHON_EXECUTABLE} ${merge_cmd} --no-stamp) ## ## find_program(versheader_cmd createProjVersHeader.py HINTS ${binary_paths}) ## set(versheader_cmd ${PYTHON_EXECUTABLE} ${versheader_cmd}) ## ## find_program(genconfuser_cmd genconfuser.py HINTS ${binary_paths}) ## set(genconfuser_cmd ${PYTHON_EXECUTABLE} ${genconfuser_cmd}) ## ## find_program(zippythondir_cmd ZipPythonDir.py HINTS ${binary_paths}) ## set(zippythondir_cmd ${PYTHON_EXECUTABLE} ${zippythondir_cmd}) ## ## find_program(icedustrun_cmd icedustrun.py HINTS ${binary_paths}) ## set(icedustrun_cmd ${PYTHON_EXECUTABLE} ${icedustrun_cmd}) # TODO: what's the point of using genconf # # genconf is special because it must be known before we actually declare the # # target in IcedustKernel/src/Util (because we need to be dynamic and agnostic). # if(TARGET genconf) # message(STATUS "${myindent} (TARGET genconf)") # get_target_property(genconf_cmd genconf IMPORTED_LOCATION) # else() # message(STATUS "${myindent} !(TARGET genconf)") # if (NOT ICEDUST_USE_EXE_SUFFIX) # set(genconf_cmd ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/genconf) # message(STATUS "${myindent} !ICEDUST_USE_EXE_SUFFIX") # else() # message(STATUS "${myindent} ICEDUST_USE_EXE_SUFFIX") # set(genconf_cmd ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/genconf.exe) # endif() # endif() # message(STATUS "${myindent} genconf_cmd = "${genconf_cmd}) # # same as genconf (but it might never be built because it's needed only on WIN32) # if(TARGET genwindef) # message(STATUS "${myindent} (TARGET genwindef)") # get_target_property(genwindef_cmd genwindef IMPORTED_LOCATION) # else() # message(STATUS "${myindent} ! (TARGET genwindef)") # set(genwindef_cmd ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/genwindef.exe) # endif() # message(STATUS "${myindent} genwindef_cmd = "${genwindef_cmd}) # TODO: Do we need these functions? ## mark_as_advanced(env_cmd merge_cmd versheader_cmd genconfuser_cmd ## zippythondir_cmd icedustrun_cmd) mark_as_advanced(env_cmd) message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Deal with installation") # TODO: We need to add more things in #--- Package Installations------------------------------------------------------------------------ install(DIRECTORY cmake/ DESTINATION cmake FILES_MATCHING PATTERN "*.cmake" PATTERN ".svn" EXCLUDE) install(PROGRAMS cmake/env.py DESTINATION scripts OPTIONAL) install(DIRECTORY cmake/EnvConfig DESTINATION scripts FILES_MATCHING PATTERN "*.py" PATTERN "*.conf") #--- Global actions for the package message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Global actions for the package") include(IcedustBuildFlags) # TODO: if we need to generate a version header # Generate the version header for the package. string(TOUPPER ${package_name} _pkg) ## execute_process(COMMAND ## ${versheader_cmd} --quiet ## ${package_name} ${CMAKE_PROJECT_VERSION} ${CMAKE_BINARY_DIR}/include/${_pkg}_VERSION.h) ## install(FILES ${CMAKE_BINARY_DIR}/include/${_pkg}_VERSION.h DESTINATION include) # Add generated headers to the include path. include_directories(${CMAKE_BINARY_DIR}/include) #--- Collect settings for subdirectories message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Collect settings for subdirectories....") set(library_path) # TODO: Fix this part... #--- Special global targets for merging files. icedust_merge_files(ConfDB python ${CMAKE_PROJECT_NAME}_merged_confDb.py) icedust_merge_files(Rootmap lib ${CMAKE_PROJECT_NAME}.rootmap) icedust_merge_files(DictRootmap lib ${CMAKE_PROJECT_NAME}Dict.rootmap) # TODO: and this python zipping part # FIXME: it is not possible to produce the file python.zip at installation time # because the install scripts of the subdirectories are executed after those # of the parent project and we cannot have a post-install target because of # http://public.kitware.com/Bug/view.php?id=8438 # install(CODE "execute_process(COMMAND ${zippythondir_cmd} ${CMAKE_INSTALL_PREFIX}/python)") ## add_custom_target(python.zip ## COMMAND ${zippythondir_cmd} ${CMAKE_INSTALL_PREFIX}/python ## COMMENT "Zipping Python modules") #--- Prepare environment configuration message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Preparing environment configuration:") # - collect environment from externals icedust_external_project_environment() # (so far, the build and the release envirnoments are identical) set(project_build_environment ${project_environment}) # - collect internal environment # - project root (for relocatability) string(TOUPPER ${package_dir} _pkg) #set(project_environment ${project_environment} SET ${_pkg}_PROJECT_ROOT "${CMAKE_SOURCE_DIR}") file(RELATIVE_PATH _PROJECT_ROOT ${CMAKE_INSTALL_PREFIX} ${CMAKE_SOURCE_DIR}) message(STATUS "${myindent} _PROJECT_ROOT -> ${_PROJECT_ROOT}") # TODO: Something must be wrong with this setting set(project_environment ${project_environment} SET ${_proj}_PROJECT_ROOT "\${.}/${_PROJECT_ROOT}") set(project_build_environment ${project_build_environment} SET ${_proj}_PROJECT_ROOT "${CMAKE_SOURCE_DIR}") message(STATUS "${myindent} package:${package_reldir}") get_filename_component(_pack ${package_reldir} NAME) string(TOUPPER ${_pack} _PACK) # - roots (backward compatibility) set(project_environment ${project_environment} SET ${_PACK}ROOT \${${_proj}_PROJECT_ROOT}/${package_reldir}) set(project_environment ${project_environment} SET ${_PACK}_tag ${CMAKE_SYSTEM}) set(project_environment ${project_environment} SET ${_PACK}CONFIG ${CMAKE_SYSTEM}) set(project_build_environment ${project_build_environment} SET ${_PACK}ROOT \${${_proj}_PROJECT_ROOT}/${package_reldir}) set(project_build_environment ${project_build_environment} SET ${_PACK}_tag ${CMAKE_SYSTEM}) set(project_build_environment ${project_build_environment} SET ${_PACK}CONFIG ${CMAKE_SYSTEM}) # TODO: get_property is trying to retrieve property from every related packages, # but these properties were set by CMakeLists.txt in other packages. # Need to include them in. # probably using CMakeCache.txt? # Currently ALL get_property(DIRECTORY ...) lines are commented # - declared environments message(STATUS "${myindent}get_property(_pack_env DIRECTORY ${project_dir}/packages/${package_reldir}/cmake PROPERTY ENVIRONMENT") # get_property(_pack_env DIRECTORY ${project_dir}/packages/${package_reldir}/cmake PROPERTY ENVIRONMENT) if(_pack_env) set(project_environment ${project_environment} ${_pack_env}) set(project_build_environment ${project_build_environment} ${_pack_env}) endif() # (build env only) # get_property(_pack_env DIRECTORY ${project_dir}/packages/${package_reldir}/cmake PROPERTY BUILD_ENVIRONMENT) if(_pack_env) set(project_build_environment ${project_build_environment} ${_pack_env}) endif() # we need special handling of PYTHONPATH and PATH for the build-time environment set(_has_config NO) set(_has_python NO) if(EXISTS ${CMAKE_BINARY_DIR}/${package_reldir}/genConf OR TARGET ${_pack}ConfUserDB) set(project_build_environment ${project_build_environment} PREPEND PYTHONPATH ${CMAKE_BINARY_DIR}/${package_reldir}/genConf) set(_has_config YES) endif() if(EXISTS ${CMAKE_SOURCE_DIR}/${package_reldir}/python) set(project_build_environment ${project_build_environment} PREPEND PYTHONPATH \${${_proj}_PROJECT_ROOT}/${package_reldir}/python) set(_has_python YES) endif() if(_has_config AND _has_python) # we need to add a special fake __init__.py that allow import of modules # from different copies of the package get_filename_component(packname ${package_reldir} NAME) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/${packname}) file(WRITE ${CMAKE_BINARY_DIR}/python/${packname}/__init__.py "\nimport os, sys\n__path__ = filter(os.path.exists, [os.path.join(d, '${packname}') for d in sys.path if d])\n") if(EXISTS ${CMAKE_SOURCE_DIR}/${package_reldir}/python/${packname}/__init__.py) file(READ ${CMAKE_SOURCE_DIR}/${package_reldir}/python/${packname}/__init__.py _py_init_content) file(APPEND ${CMAKE_BINARY_DIR}/python/${packname}/__init__.py "${_py_init_content}") endif() endif() if(EXISTS ${CMAKE_SOURCE_DIR}/${package_reldir}/scripts) set(project_build_environment ${project_build_environment} PREPEND PATH \${${_proj}_PROJECT_ROOT}/${package_reldir}/scripts) endif() message(STATUS " environment for the package") # - installation dirs set(project_environment ${project_environment} PREPEND PATH \${.}/scripts PREPEND PATH \${.}/bin PREPEND LD_LIBRARY_PATH \${.}/lib PREPEND PYTHONPATH \${.}/python PREPEND PYTHONPATH \${.}/python/lib-dynload) # - build dirs set(project_build_environment ${project_build_environment} PREPEND PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} PREPEND LD_LIBRARY_PATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} PREPEND PYTHONPATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} PREPEND PYTHONPATH ${CMAKE_BINARY_DIR}/python) message(STATUS "${myindent} project_environment=${project_environment}") message(STATUS "${myindent} project_build_environment=${project_build_environment}") # - produce environment XML description # release version icedust_generate_env_conf(${env_release_xml} ${project_environment}) install(FILES ${env_release_xml} DESTINATION .) # build-time version icedust_generate_env_conf(${env_xml} ${project_build_environment}) # add a small wrapper script in the build directory to easily run anything set(_env_cmd_line) foreach(t ${env_cmd}) # transform the env_cmd list in a space separated string set(_env_cmd_line "${_env_cmd_line} ${t}") endforeach() if(UNIX) file(WRITE ${CMAKE_BINARY_DIR}/run "#!/bin/sh\nexec ${_env_cmd_line} --xml ${env_xml} \"$@\"\n") execute_process(COMMAND chmod a+x ${CMAKE_BINARY_DIR}/run) elseif(WIN32) file(WRITE ${CMAKE_BINARY_DIR}/run.bat "${_env_cmd_line} --xml ${env_xml} %1 %2 %3 %4 %5 %6 %7 %8 %9\n") endif() # ignore other systems message(STATUS "${myindent} #------------------------------------------------------------------") message(STATUS "${myindent} Other things:") # FIXME: How to avoid duplicated setting? #--- Special target to print the summary of QMTest runs. # if(ICEDUST_BUILD_TESTS) # add_custom_target(QMTestSummary) # add_custom_command(TARGET QMTestSummary # COMMAND ${env_cmd} --xml ${env_xml} # qmtest_summarize.py) # endif() #--- Generate config files to be imported by other projects. icedust_generate_project_config_version_file() icedust_generate_project_config_file() icedust_generate_project_platform_config_file() icedust_generate_exports(${sorted_packages}) #--- Generate the manifest.xml file. icedust_generate_project_manifest(${CMAKE_BINARY_DIR}/manifest.xml ${ARGV}) install(FILES ${CMAKE_BINARY_DIR}/manifest.xml DESTINATION .) #--- CPack configuration set(CPACK_PACKAGE_NAME ${project}) foreach(t MAJOR MINOR PATCH) set(CPACK_PACKAGE_VERSION_${t} ${CMAKE_PROJECT_VERSION_${t}}) endforeach() set(CPACK_SYSTEM_NAME ${BINARY_TAG}) set(CPACK_GENERATOR TGZ) message(STATUS "${myindent} CPack = ${CPack}") include(CPack) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_package_special ${name} ${version})") endmacro() #------------------------------------------------------------------------------- # icedust_merge_files(merge_tgt dest filename) # # Create a global target Merged${merge_tgt} that takes input files and dependencies # from the packages (declared with icedust_merge_files_append). #------------------------------------------------------------------------------- function(icedust_merge_files merge_tgt dest filename) message(STATUS "${myindent}==>function(icedust_merge_files ${merge_tgt} ${dest} ${filename})") SET(myindent "${myindent}\t") icedust_global_target_get_info(Merged${merge_tgt} deps parts) if(parts) # create the targets set(output ${CMAKE_BINARY_DIR}/${dest}/${filename}) ## add_custom_command(OUTPUT ${output} ## COMMAND ${merge_cmd} ${parts} ${output} ## DEPENDS ${parts}) add_custom_target(Merged${merge_tgt} ALL DEPENDS ${output}) # prepare the high level dependencies add_dependencies(Merged${merge_tgt} ${deps}) # target to generate a partial merged file ## add_custom_command(OUTPUT ${output}_force ## COMMAND ${merge_cmd} --ignore-missing ${parts} ${output}) add_custom_target(Merged${merge_tgt}_force DEPENDS ${output}_force) # ensure that we merge what we have before installing if the output was not # produced ## install(CODE "if(NOT EXISTS ${output}) ## message(WARNING \"creating partial ${output}\") ## execute_process(COMMAND ${merge_cmd} --ignore-missing ${parts} ${output}) ## endif()") # install rule for the merged DB install(FILES ${output} DESTINATION ${dest} OPTIONAL) endif() string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==function(icedust_merge_files ${merge_tgt} ${dest} ${filename})") endfunction() #------------------------------------------------------------------------------- # icedust_external_project_environment() # # Collect the environment details from the found packages and add them to the # variable project_environment. #------------------------------------------------------------------------------- macro(icedust_external_project_environment) message(STATUS "${myindent}==>macro(icedust_external_project_environment)") SET(myindent "${myindent}\t") # collecting environment infos set(python_path) set(binary_path) set(environment) set(library_path2) if(CMAKE_HOST_UNIX) # Guess the LD_LIBRARY_PATH required by the compiler we use (only Unix). #message(STATUS "${myindent} find libstdc++.so -> ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -print-file-name=libstdc++.so") set(_cmd "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -print-file-name=libstdc++.so") separate_arguments(_cmd) execute_process(COMMAND ${_cmd} OUTPUT_VARIABLE cpplib) get_filename_component(cpplib ${cpplib} REALPATH) get_filename_component(cpplib ${cpplib} PATH) # Special hack for the way gcc is installed onf AFS at CERN. string(REPLACE "contrib/gcc" "external/gcc" cpplib ${cpplib}) #message(STATUS "${myindent} C++ lib dir -> ${cpplib}") set(library_path2 ${cpplib}) message(STATUS "${myindent}library_path2=${library_path2}") endif() get_property(packages_found GLOBAL PROPERTY PACKAGES_FOUND) message(" packages_found: ${packages_found}") foreach(pack ${packages_found}) # Check that it is not a "Icedust project" (the environment is included in a # different way in icedust_generate_env_conf). list(FIND used_icedust_projects ${pack} icedust_project_idx) if((NOT pack STREQUAL IcedustProject) AND (icedust_project_idx EQUAL -1)) message(STATUS "${myindent} ${pack}") # this is needed to get the non-cache variables for the packages find_package(${pack} QUIET) if(pack STREQUAL PythonInterp OR pack STREQUAL PythonLibs) set(pack Python) endif() string(TOUPPER ${pack} _pack_upper) if(${_pack_upper}_EXECUTABLE) get_filename_component(bin_path ${${_pack_upper}_EXECUTABLE} PATH) list(APPEND binary_path ${bin_path}) endif() list(APPEND binary_path ${${pack}_BINARY_PATH}) list(APPEND python_path ${${pack}_PYTHON_PATH}) list(APPEND environment ${${pack}_ENVIRONMENT}) list(APPEND library_path2 ${${pack}_LIBRARY_DIR} ${${pack}_LIBRARY_DIRS}) # Try the version with the name of the package uppercase (unless the # package name is already uppercase). if(NOT pack STREQUAL _pack_upper) list(APPEND binary_path ${${_pack_upper}_BINARY_PATH}) list(APPEND python_path ${${_pack_upper}_PYTHON_PATH}) list(APPEND environment ${${_pack_upper}_ENVIRONMENT}) list(APPEND library_path2 ${${_pack_upper}_LIBRARY_DIR} ${${_pack_upper}_LIBRARY_DIRS}) endif() endif() endforeach() get_property(library_path GLOBAL PROPERTY LIBRARY_PATH) message(STATUS "${myindent} library_path=${library_path}, library_path2=${library_path2}") set(library_path ${library_path} ${library_path2}) # Remove system libraries from the library_path #list(REMOVE_ITEM library_path /usr/lib /lib /usr/lib64 /lib64 /usr/lib32 /lib32) set(old_library_path ${library_path}) set(library_path) foreach(d ${old_library_path}) if(NOT d MATCHES "^(/usr|/usr/local)?/lib(32/64)?") set(library_path ${library_path} ${d}) endif() endforeach() foreach(var library_path python_path binary_path) if(${var}) list(REMOVE_DUPLICATES ${var}) endif() endforeach() foreach(val ${python_path}) set(project_environment ${project_environment} PREPEND PYTHONPATH ${val}) endforeach() foreach(val ${binary_path}) set(project_environment ${project_environment} PREPEND PATH ${val}) endforeach() foreach(val ${library_path}) set(project_environment ${project_environment} PREPEND LD_LIBRARY_PATH ${val}) endforeach() set(project_environment ${project_environment} ${environment}) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_external_project_environment)") endmacro() #------------------------------------------------------------------------------- # icedust_global_target_get_info(global_target local_targets_var files_var) # (macro) # # Put the information to configure the global target 'global_target' in the # two variables local_targets_var and files_var. #------------------------------------------------------------------------------- macro(icedust_global_target_get_info global_target local_targets_var files_var) message(STATUS "${myindent}==>macro(icedust_global_target_get_info ${global_target} ${local_targets_var} ${files_var})") SET(myindent "${myindent}\t") get_property(${files_var} GLOBAL PROPERTY ${global_target}_SOURCES) get_property(${local_targets_var} GLOBAL PROPERTY ${global_target}_DEPENDS) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_global_target_get_info ${global_target} ${local_targets_var} ${files_var})") endmacro() #------------------------------------------------------------------------------- # icedust_generate_env_conf(filename ) # # Generate the XML file describing the changes to the environment required by # this project. #------------------------------------------------------------------------------- function(icedust_generate_env_conf filename) message(STATUS "${myindent}==>function(icedust_generate_env_conf ${filename})") SET(myindent "${myindent}\t") set(data " \n") # variables that need to be used to make the environment relative set(root_vars LCG_releases LCG_external) foreach(root_var ${root_vars}) set(data "${data} ${${root_var}}\n") endforeach() # include inherited environments foreach(other_project ${used_icedust_projects}) set(data "${data} ${other_project}Environment.xml\n") endforeach() set(commands ${ARGN}) #message(STATUS "${myindent} start - ${commands}") while(commands) #message(STATUS "${myindent} iter - ${commands}") _env_conf_pop_instruction(instr commands) # ensure that the variables in the value are not expanded when passing the arguments string(REPLACE "\$" "\\\$" instr "${instr}") _env_line(${instr} ln) set(data "${data} ${ln}\n") endwhile() set(data "${data}\n") get_filename_component(fn ${filename} NAME) message(STATUS "${myindent} Generating ${fn}") file(WRITE ${filename} "${data}") string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==function(icedust_generate_env_conf ${filename})") endfunction() #------------------------------------------------------------------------------- # _env_conf_pop_instruction(...) # # helper macro used by icedust_generate_env_conf. #------------------------------------------------------------------------------- macro(_env_conf_pop_instruction instr lst) message(STATUS "${myindent}==>macro(_env_conf_pop_instruction instr lst)") SET(myindent "${myindent}\t") #message(STATUS "${myindent} _env_conf_pop_instruction ${lst} => ${${lst}}") list(GET ${lst} 0 ${instr}) if(${instr} STREQUAL INCLUDE OR ${instr} STREQUAL UNSET) list(GET ${lst} 0 1 ${instr}) list(REMOVE_AT ${lst} 0 1) # even if the command expects only one argument, ${instr} must have 3 elements # because of the way it must be passed to _env_line() set(${instr} ${${instr}} _dummy_) else() list(GET ${lst} 0 1 2 ${instr}) list(REMOVE_AT ${lst} 0 1 2) endif() #message(STATUS "${myindent} _env_conf_pop_instruction ${instr} => ${${instr}}") #message(STATUS "${myindent} _env_conf_pop_instruction ${lst} => ${${lst}}") string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(_env_conf_pop_instruction instr lst)") endmacro() #------------------------------------------------------------------------------- # _env_line(...) # # helper macro used by icedust_generate_env_conf. #------------------------------------------------------------------------------- macro(_env_line cmd var val output) message(STATUS "${myindent}==>macro(_env_line cmd var val output)") SET(myindent "${myindent}\t") set(val_ ${val}) foreach(root_var ${root_vars}) if(${root_var}) if(val_ MATCHES "^${${root_var}}") file(RELATIVE_PATH val_ ${${root_var}} ${val_}) set(val_ \${${root_var}}/${val_}) endif() endif() endforeach() if(${cmd} STREQUAL "SET") set(${output} "${val_}") elseif(${cmd} STREQUAL "UNSET") set(${output} "") elseif(${cmd} STREQUAL "PREPEND") set(${output} "${val_}") elseif(${cmd} STREQUAL "APPEND") set(${output} "${val_}") elseif(${cmd} STREQUAL "REMOVE") set(${output} "${val_}") elseif(${cmd} STREQUAL "INCLUDE") get_filename_component(inc_name ${var} NAME) get_filename_component(inc_path ${var} PATH) set(${output} "${inc_name}") else() # message(FATAL_ERROR "Unknown environment command ${cmd}") endif() string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(_env_line cmd var val output)") endmacro() #------------------------------------------------------------------------------- # icedust_generate_project_config_version_file() # # Create the file used by CMake to check if the found version of a package # matches the requested one. #------------------------------------------------------------------------------- macro(icedust_generate_project_config_version_file) message(STATUS "${myindent}==>macro(icedust_generate_project_config_version_file)") SET(myindent "${myindent}\t") message(STATUS "${myindent} Generating ${CMAKE_PROJECT_NAME}ConfigVersion.cmake") if(CMAKE_PROJECT_VERSION_PATCH) set(vers_id ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) else() set(vers_id ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}) endif() file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/config) file(WRITE ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}ConfigVersion.cmake "set(PACKAGE_NAME ${CMAKE_PROJECT_NAME}) set(PACKAGE_VERSION ${vers_id}) if(PACKAGE_NAME STREQUAL PACKAGE_FIND_NAME) if(PACKAGE_VERSION STREQUAL PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_EXACT 1) set(PACKAGE_VERSION_COMPATIBLE 1) set(PACKAGE_VERSION_UNSUITABLE 0) elseif(PACKAGE_FIND_VERSION STREQUAL \"\") # No explicit version requested. set(PACKAGE_VERSION_EXACT 0) set(PACKAGE_VERSION_COMPATIBLE 1) set(PACKAGE_VERSION_UNSUITABLE 0) else() set(PACKAGE_VERSION_EXACT 0) set(PACKAGE_VERSION_COMPATIBLE 0) set(PACKAGE_VERSION_UNSUITABLE 1) endif() endif() ") install(FILES ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}ConfigVersion.cmake DESTINATION .) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_generate_project_config_version_file)") endmacro() #------------------------------------------------------------------------------- # icedust_generate_project_config_file() # # Generate the config file used by the other projects using this one. #------------------------------------------------------------------------------- macro(icedust_generate_project_config_file) message(STATUS "${myindent}==>macro(icedust_generate_project_config_file)") SET(myindent "${myindent}\t") # message(STATUS "${myindent} Generating ${CMAKE_PROJECT_NAME}Config.cmake") file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/config) file(WRITE ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}Config.cmake "# File automatically generated: DO NOT EDIT. set(${CMAKE_PROJECT_NAME}_heptools_version ${heptools_version}) set(${CMAKE_PROJECT_NAME}_heptools_system ${LCG_SYSTEM}) set(${CMAKE_PROJECT_NAME}_PLATFORM ${BINARY_TAG}) set(${CMAKE_PROJECT_NAME}_VERSION ${CMAKE_PROJECT_VERSION}) set(${CMAKE_PROJECT_NAME}_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR}) set(${CMAKE_PROJECT_NAME}_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR}) set(${CMAKE_PROJECT_NAME}_VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH}) set(${CMAKE_PROJECT_NAME}_USES ${PROJECT_USE}) list(INSERT CMAKE_MODULE_PATH 0 \${${CMAKE_PROJECT_NAME}_DIR}/cmake) include(${CMAKE_PROJECT_NAME}PlatformConfig) ") install(FILES ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}Config.cmake DESTINATION .) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_generate_project_config_file)") endmacro() #------------------------------------------------------------------------------- # icedust_generate_project_platform_config_file() # # Generate the platform(build)-specific config file included by the other # projects using this one. #------------------------------------------------------------------------------- macro(icedust_generate_project_platform_config_file) message(STATUS "${myindent}==>macro(icedust_generate_project_platform_config_file)") SET(myindent "${myindent}\t") message(STATUS "${myindent} Generating ${CMAKE_PROJECT_NAME}PlatformConfig.cmake") # collecting infos get_property(linker_libraries GLOBAL PROPERTY LINKER_LIBRARIES) get_property(component_libraries GLOBAL PROPERTY COMPONENT_LIBRARIES) string(REPLACE "\$" "\\\$" project_environment_string "${project_environment}") file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/config) set(filename ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}PlatformConfig.cmake) file(WRITE ${filename} "# File automatically generated: DO NOT EDIT. # Get the exported informations about the targets get_filename_component(_dir "\${CMAKE_CURRENT_LIST_FILE}" PATH) #include(\${_dir}/${CMAKE_PROJECT_NAME}Exports.cmake) # Set useful properties get_filename_component(_dir "\${_dir}" PATH) set(${CMAKE_PROJECT_NAME}_INCLUDE_DIRS \${_dir}/include) set(${CMAKE_PROJECT_NAME}_LIBRARY_DIRS \${_dir}/lib) set(${CMAKE_PROJECT_NAME}_BINARY_PATH \${_dir}/bin \${_dir}/scripts) set(${CMAKE_PROJECT_NAME}_PYTHON_PATH \${_dir}/python) set(${CMAKE_PROJECT_NAME}_COMPONENT_LIBRARIES ${component_libraries}) set(${CMAKE_PROJECT_NAME}_LINKER_LIBRARIES ${linker_libraries}) set(${CMAKE_PROJECT_NAME}_ENVIRONMENT ${project_environment_string}) set(${CMAKE_PROJECT_NAME}_EXPORTED_SUBDIRS) foreach(p ${packages}) get_filename_component(pn \${p} NAME) if(EXISTS \${_dir}/cmake###${pn}Export.cmake) set(${CMAKE_PROJECT_NAME}_EXPORTED_SUBDIRS \${${CMAKE_PROJECT_NAME}_EXPORTED_SUBDIRS} \${p}) endif() endforeach() set(${CMAKE_PROJECT_NAME}_OVERRIDDEN_SUBDIRS ${override_subdirs}) ") install(FILES ${CMAKE_BINARY_DIR}/config/${CMAKE_PROJECT_NAME}PlatformConfig.cmake DESTINATION cmake) string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_generate_project_platform_config_file)") endmacro() #------------------------------------------------------------------------------- # icedust_generate_exports(subdirs...) # # Internal function that generate the export data. #------------------------------------------------------------------------------- macro(icedust_generate_exports) message(STATUS "${myindent}==>macro(icedust_generate_exports)") SET(myindent "${myindent}\t") foreach(package ${ARGN}) # we do not use the "Hat" for the export names get_filename_component(pkgname ${package} NAME) # get_property(exported_libs DIRECTORY ${project_dir}/packages/${package}/cmake PROPERTY ICEDUST_EXPORTED_LIBRARY) # get_property(exported_execs DIRECTORY ${project_dir}/packages/${package}/cmake PROPERTY ICEDUST_EXPORTED_EXECUTABLE) # get_property(exported_mods DIRECTORY ${project_dir}/packages/${package}/cmake PROPERTY ICEDUST_EXPORTED_MODULE) # get_property(exported_cmake DIRECTORY ${project_dir}/packages/${package}/cmake PROPERTY ICEDUST_EXPORTED_CMAKE SET) # get_property(subdir_version DIRECTORY ${project_dir}/packages/${package}/cmake PROPERTY version) if (exported_libs OR exported_execs OR exported_mods OR exported_cmake OR ${package}_DEPENDENCIES OR subdir_version) set(pkg_exp_file ${pkgname}Export.cmake) message(STATUS "${myindent} Generating ${pkg_exp_file}") set(pkg_exp_file ${CMAKE_CURRENT_BINARY_DIR}/${pkg_exp_file}) file(WRITE ${pkg_exp_file} "# File automatically generated: DO NOT EDIT. # Compute the installation prefix relative to this file. get_filename_component(_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH) get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) ") foreach(library ${exported_libs}) file(APPEND ${pkg_exp_file} "add_library(${library} SHARED IMPORTED)\n") file(APPEND ${pkg_exp_file} "set_target_properties(${library} PROPERTIES\n") foreach(pn REQUIRED_INCLUDE_DIRS REQUIRED_LIBRARIES) get_property(prop TARGET ${library} PROPERTY ${pn}) if (prop) file(APPEND ${pkg_exp_file} " ${pn} \"${prop}\"\n") endif() endforeach() get_property(prop TARGET ${library} PROPERTY LOCATION) get_filename_component(prop ${prop} NAME) file(APPEND ${pkg_exp_file} " IMPORTED_SONAME \"${prop}\"\n") file(APPEND ${pkg_exp_file} " IMPORTED_LOCATION \"\${_IMPORT_PREFIX}/lib/${prop}\"\n") file(APPEND ${pkg_exp_file} " )\n") endforeach() foreach(executable ${exported_execs}) file(APPEND ${pkg_exp_file} "add_executable(${executable} IMPORTED)\n") file(APPEND ${pkg_exp_file} "set_target_properties(${executable} PROPERTIES\n") get_property(prop TARGET ${executable} PROPERTY LOCATION) get_filename_component(prop ${prop} NAME) file(APPEND ${pkg_exp_file} " IMPORTED_LOCATION \"\${_IMPORT_PREFIX}/bin/${prop}\"\n") file(APPEND ${pkg_exp_file} " )\n") endforeach() foreach(module ${exported_mods}) file(APPEND ${pkg_exp_file} "add_library(${module} MODULE IMPORTED)\n") endforeach() if(${package}_DEPENDENCIES) file(APPEND ${pkg_exp_file} "set(${package}_DEPENDENCIES ${${package}_DEPENDENCIES})\n") endif() if(subdir_version) file(APPEND ${pkg_exp_file} "set(${package}_VERSION ${subdir_version})\n") endif() endif() install(FILES ${pkg_exp_file} DESTINATION cmake) endforeach() string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==macro(icedust_generate_exports)") endmacro() #------------------------------------------------------------------------------- # icedust_generate_project_manifest() # # Internal function to generate project metadata like dependencies on other # projects and on external software libraries. #------------------------------------------------------------------------------- function(icedust_generate_project_manifest filename project version) message(STATUS "${myindent}==>function(icedust_generate_project_manifest ${filename} ${project} ${version})") SET(myindent "${myindent}\t") # FIXME: partial replication of function argument parsing done in icedust_project() CMAKE_PARSE_ARGUMENTS(PROJECT "" "" "USE;DATA" ${ARGN}) # Non need to check consistency because it's already done in icedust_project(). #header set(data " \n") # Project name and version set(data "${data} \n") # HEP toolchain infos if(heptools_version) set(data "${data} \n") # version set(data "${data} ${heptools_version}\n") # platform specifications set(data "${data} ${BINARY_TAG}\n") set(data "${data} ${LCG_SYSTEM}\n") set(data "${data} \n") endif() # Build options # FIXME: I need an explicit list of options to store # Used projects if(PROJECT_USE) set(data "${data} \n") while(PROJECT_USE) list(GET PROJECT_USE 0 n) list(GET PROJECT_USE 1 v) list(REMOVE_AT PROJECT_USE 0 1) set(data "${data} \n") endwhile() set(data "${data} \n") endif() # Used data packages if(PROJECT_DATA) set(data "${data} \n") while(PROJECT_DATA) list(GET PROJECT_DATA 0 n) list(REMOVE_AT PROJECT_DATA 0) set(v *) if(PROJECT_DATA) list(GET PROJECT_DATA 0 next) if(next STREQUAL VERSION) list(GET PROJECT_DATA 1 v) list(REMOVE_AT PROJECT_DATA 0 1) endif() endif() set(data "${data} \n") endwhile() set(data "${data} \n") endif() # trailer set(data "${data}\n") get_filename_component(fn ${filename} NAME) message(STATUS "${myindent} Generating ${fn}") file(WRITE ${filename} "${data}") string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}") message(STATUS "${myindent}<==function(icedust_generate_project_manifest ${filename} ${project} ${version})") endfunction() string(REGEX REPLACE "(\t*)\t" "\\1" myindent "${myindent}")