{"action":"closed","issue":{"url":"https://api.github.com/repos/cmake-basis/BASIS/issues/555","repository_url":"https://api.github.com/repos/cmake-basis/BASIS","labels_url":"https://api.github.com/repos/cmake-basis/BASIS/issues/555/labels{/name}","comments_url":"https://api.github.com/repos/cmake-basis/BASIS/issues/555/comments","events_url":"https://api.github.com/repos/cmake-basis/BASIS/issues/555/events","html_url":"https://github.com/cmake-basis/BASIS/issues/555","id":148904618,"number":555,"title":"Support standalone build of project modules","user":{"login":"schuhschuh","id":975451,"avatar_url":"https://avatars.githubusercontent.com/u/975451?v=3","gravatar_id":"","url":"https://api.github.com/users/schuhschuh","html_url":"https://github.com/schuhschuh","followers_url":"https://api.github.com/users/schuhschuh/followers","following_url":"https://api.github.com/users/schuhschuh/following{/other_user}","gists_url":"https://api.github.com/users/schuhschuh/gists{/gist_id}","starred_url":"https://api.github.com/users/schuhschuh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/schuhschuh/subscriptions","organizations_url":"https://api.github.com/users/schuhschuh/orgs","repos_url":"https://api.github.com/users/schuhschuh/repos","events_url":"https://api.github.com/users/schuhschuh/events{/privacy}","received_events_url":"https://api.github.com/users/schuhschuh/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/cmake-basis/BASIS/labels/5%20-%20Completed","name":"5 - Completed","color":"bfe5bf"},{"url":"https://api.github.com/repos/cmake-basis/BASIS/labels/CMake","name":"CMake","color":"fbca04"},{"url":"https://api.github.com/repos/cmake-basis/BASIS/labels/Enhancement","name":"Enhancement","color":"84b6eb"}],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/cmake-basis/BASIS/milestones/23","html_url":"https://github.com/cmake-basis/BASIS/milestones/v3.3.0","labels_url":"https://api.github.com/repos/cmake-basis/BASIS/milestones/23/labels","id":1711675,"number":23,"title":"v3.3.0","description":"","creator":{"login":"schuhschuh","id":975451,"avatar_url":"https://avatars.githubusercontent.com/u/975451?v=3","gravatar_id":"","url":"https://api.github.com/users/schuhschuh","html_url":"https://github.com/schuhschuh","followers_url":"https://api.github.com/users/schuhschuh/followers","following_url":"https://api.github.com/users/schuhschuh/following{/other_user}","gists_url":"https://api.github.com/users/schuhschuh/gists{/gist_id}","starred_url":"https://api.github.com/users/schuhschuh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/schuhschuh/subscriptions","organizations_url":"https://api.github.com/users/schuhschuh/orgs","repos_url":"https://api.github.com/users/schuhschuh/repos","events_url":"https://api.github.com/users/schuhschuh/events{/privacy}","received_events_url":"https://api.github.com/users/schuhschuh/received_events","type":"User","site_admin":false},"open_issues":27,"closed_issues":30,"state":"open","created_at":"2016-04-16T20:18:02Z","updated_at":"2016-04-17T17:23:11Z","due_on":null,"closed_at":null},"comments":0,"created_at":"2016-04-17T00:19:46Z","updated_at":"2016-04-17T17:23:10Z","closed_at":"2016-04-17T17:23:10Z","body":"<a href=\"https://github.com/schuhschuh\"><img src=\"https://avatars.githubusercontent.com/u/975451?v=3\" align=\"left\" width=\"96\" height=\"96\" hspace=\"10\"></img></a> **Issue by [schuhschuh](https://github.com/schuhschuh)**\n_Thursday Mar 03, 2016 at 17:43 GMT_\n_Originally opened as https://github.com/cmake-basis/legacy/issues/555_\n\n----\n\nThe standalone build of project modules currently yields a different result than when the modules would have been built as part of the top-level project. This affects mainly the CMake files in the ```<prefix>/lib/cmake/<package>/``` directory. The standalone built of subprojects (see ```SUBPROJECT``` option of ```basis_project```) is a different subject and should work already. This issue is also concerned with module that are tightly coupled with the top-level project and other modules. These share a common namespace named after the top-level project (see ```PACKAGE``` option of ```basis_project```).\r\n\r\n- [x] Name module configuration files ```<Pkg><Module>Config.cmake``` instead of ```<Pkg>Config.cmake```\r\n- [x] Append module to ```<Pkg>_MODULES``` and ```<Pkg>_MODULES_ENABLED``` lists\r\n- [x] Include installed ```<Pkg><Module>InstallManifest.txt``` in uninstaller script\r\n- [x] Skip ```<prefix>/bin/uninstall-<pkg>``` and ```<prefix>/lib/cmake/<pkg>/<Pkg>Uninstall.cmake``` files\r\n- [x] Include exported targets in ```<Pkg><Module>Exports.cmake``` in ```<Pkg><Module>Use.cmake``` file which is to be included by ```<Pkg>Use.cmake``` file when the module was requested\r\n\r\n\r\nThoughts on the export/import of module targets\r\n---------------------------------------------------------------\r\n\r\nBest would be to write ```<Pkg><Module>Exports.cmake``` files for each module and include these in the respective ```<Pkg><Module>Config.cmake``` files. This, however, is not possible with CMake because it requires all (library) targets that depend on each other to be exported altogether. What can we do about this?\r\n\r\nCan/shall we make use of the following glob expression that CMake generates? But this would include the files ```<Pkg>Exports-<Module>-<config>.cmake``` twice, once in ```<Pkg>Exports-<Module>.cmake``` and another time in ```<Pkg>Exports.cmake```.\r\n\r\n```cmake\r\n# Load information for each installed configuration.\r\nget_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\r\nfile(GLOB CONFIG_FILES \"${_DIR}/MIRTKExports-*.cmake\")\r\nforeach(f ${CONFIG_FILES})\r\n  include(${f})\r\nendforeach()\r\n```\r\n\r\nIt seems the following code at the top of the generated exports file guards against multiple inclusions:\r\n```cmake\r\n# Protect against multiple inclusion, which would fail when already imported targets are added once more.\r\nset(_targetsDefined)\r\nset(_targetsNotDefined)\r\nset(_expectedTargets)\r\nforeach(_expectedTarget mirtk::lbfgs mirtk::LibNumerics)\r\n  list(APPEND _expectedTargets ${_expectedTarget})\r\n  if(NOT TARGET ${_expectedTarget})\r\n    list(APPEND _targetsNotDefined ${_expectedTarget})\r\n  endif()\r\n  if(TARGET ${_expectedTarget})\r\n    list(APPEND _targetsDefined ${_expectedTarget})\r\n  endif()\r\nendforeach()\r\nif(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\r\n  set(CMAKE_IMPORT_FILE_VERSION)\r\n  cmake_policy(POP)\r\n  return()\r\nendif()\r\nif(NOT \"${_targetsDefined}\" STREQUAL \"\")\r\n  message(FATAL_ERROR \"Some (but not all) targets in this export set were already defined.\\nTargets Defined: ${_targetsDefined}\\nTargets not yet defined: ${_targetsNotDefined}\\n\")\r\nendif()\r\nunset(_targetsDefined)\r\nunset(_targetsNotDefined)\r\nunset(_expectedTargets)\r\n```\r\n\r\nIt may be necessary to export all targets to a single file and then split this ```<Pkg>Exports.cmake``` into separate ```<Pkg><Module>Exports.cmake``` files using a Python script which filters only those parts that relate to the targets of the respective module.\r\n\r\nWhy not just including the ```<Pkg><Module>Exports.cmake``` file in the ```<Pkg><Module>Use.cmake``` file that is in turn included by ```<Pkg>Use.cmake``` file as long as the module is added to the list of requested modules. The ```<Pkg><Module>Exports.cmake``` file will only exist when the module was built and installed separate from the top-level <Pkg> project. When it is built and installed as part of the top-level project, its targets are in the ```<Pkg>Exports.cmake``` file which is included by the ```<Pkg>Use.cmake```.\n"}}