diff --git a/base.cmake b/base.cmake index f53544ff7..235d51d5a 100644 --- a/base.cmake +++ b/base.cmake @@ -115,6 +115,26 @@ # https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#generating-a-package-version-file # for further details. # +# .. variable:: PROJECT_AUTO_RUN_FINALIZE +# +# If set, to true or unset SETUP_PROJECT_FINALIZE run automatically at the end +# of the root CMakeLists.txt. If set to false, SETUP_PROJECT_FINALIZE must be +# called manually. This is helpful when creating a CMake workspace where the +# root CMakelists.txt don't belong to a project. +# +# .. variable:: PROJECT_PACKAGES_IN_WORKSPACE +# +# List of packages in the workspace. This must be defined in the root +# CMakeLists. These packages will not be searched with find_package and all +# target and variables defined in the module should be defined in a workspace +# projects. +# +# .. variable:: PROJECT_PYTHON_PACKAGES_IN_WORKSPACE +# +# List of paths to Python package in the workspace. This must be defined in the +# root CMakeLists.txt. Python package should be generated in a workspace +# projects. +# # Macros # ------ # @@ -134,6 +154,10 @@ set(PROJECT_JRL_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +if(NOT DEFINED PROJECT_AUTO_RUN_FINALIZE) + set(PROJECT_AUTO_RUN_FINALIZE TRUE) +endif() + # Please note that functions starting with an underscore are internal functions # and should not be used directly. @@ -218,20 +242,19 @@ set(CMAKE_PROJECT_${PROJECT_NAME}_INCLUDE # Set a hook to finalize the setup, CMake will set CMAKE_CURRENT_LIST_DIR to "" # at the end Based off # https://stackoverflow.com/questions/15760580/execute-command-or-macro-in-cmake-as-the-last-step-before-the-configure-step-f -variable_watch(CMAKE_CURRENT_LIST_DIR SETUP_PROJECT_FINALIZE_HOOK) -function(SETUP_PROJECT_FINALIZE_HOOK VARIABLE ACCESS) - if("${${VARIABLE}}" STREQUAL "") - set(CMAKE_CURRENT_LIST_DIR ${PROJECT_JRL_CMAKE_MODULE_DIR}) - set(JRL_CMAKEMODULE_LOGGING_FILENAME - "${PROJECT_JRL_CMAKE_BINARY_DIR}/config.log") - setup_project_finalize() - if(PROJECT_USE_CMAKE_EXPORT) - setup_project_package_finalize() +if(PROJECT_AUTO_RUN_FINALIZE) + variable_watch(CMAKE_CURRENT_LIST_DIR SETUP_PROJECT_FINALIZE_HOOK) + function(SETUP_PROJECT_FINALIZE_HOOK VARIABLE ACCESS) + if("${${VARIABLE}}" STREQUAL "") + set(CMAKE_CURRENT_LIST_DIR ${PROJECT_JRL_CMAKE_MODULE_DIR}) + set(JRL_CMAKEMODULE_LOGGING_FILENAME + "${PROJECT_JRL_CMAKE_BINARY_DIR}/config.log") + setup_project_finalize() + set(CMAKE_CURRENT_LIST_DIR "") # restore value + set(JRL_CMAKEMODULE_LOGGING_FILENAME "") # restore value endif() - set(CMAKE_CURRENT_LIST_DIR "") # restore value - set(JRL_CMAKEMODULE_LOGGING_FILENAME "") # restore value - endif() -endfunction() + endfunction() +endif() # --------------------- # Project configuration # --------------------- # @@ -332,6 +355,9 @@ macro(SETUP_PROJECT_FINALIZE) _install_project_data() logging_finalize() + if(PROJECT_USE_CMAKE_EXPORT) + setup_project_package_finalize() + endif() endmacro(SETUP_PROJECT_FINALIZE) # .rst: .. ifmode:: user diff --git a/coverage.cmake b/coverage.cmake index da4c989a1..55f971ed8 100644 --- a/coverage.cmake +++ b/coverage.cmake @@ -84,11 +84,16 @@ macro(_SETUP_COVERAGE_FINALIZE) message(STATUS "Python coverage will be generated") endif() + if(NOT TARGET coverage) + add_custom_target(coverage + COMMENT "Generating HTML report for code coverage") + endif() add_custom_target( - coverage + ${PROJECT_NAME}-coverage COMMAND ${_COVERAGE_HTML} -o ${_COVERAGE_DIR} ${_COVERAGE_FILES} DEPENDS ${_COVERAGE_FILES} BYPRODUCTS ${_COVERAGE_DIR} COMMENT "Generating HTML report for code coverage") + add_dependencies(coverage ${PROJECT_NAME}-coverage) endif() endmacro() diff --git a/debian.cmake b/debian.cmake index 6d3c89d05..a428a0178 100644 --- a/debian.cmake +++ b/debian.cmake @@ -102,16 +102,25 @@ endmacro(_SETUP_DEBIAN) macro(_SETUP_PROJECT_DEB) if(UNIX AND NOT APPLE) + if(NOT TARGET deb-src) + add_custom_target(deb-src COMMENT "Generating source Debian package...") + endif() add_custom_target( - deb-src + ${PROJECT_NAME}-deb-src COMMAND git-buildpackage --git-debian-branch=debian WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT "Generating source Debian package...") + add_dependencies(deb-src ${PROJECT_NAME}-deb-src) + + if(NOT TARGET deb) + add_custom_target(deb COMMENT "Generating Debian package...") + endif() add_custom_target( - deb + ${PROJECT_NAME}-deb COMMAND git-buildpackage --git-debian-branch=debian --git-builder="debuild -S -i.git -I.git" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT "Generating Debian package...") + add_dependencies(deb ${PROJECT_NAME}-deb) endif(UNIX AND NOT APPLE) endmacro(_SETUP_PROJECT_DEB) diff --git a/dist.cmake b/dist.cmake index e12a13e27..0099a3e08 100644 --- a/dist.cmake +++ b/dist.cmake @@ -35,97 +35,134 @@ macro(_SETUP_PROJECT_DIST) endif(APPLE) # Use git-archive-all.sh to generate distributable source code + if(NOT TARGET distdir) + add_custom_target(distdir COMMENT "Generating dist directory...") + endif() add_custom_target( - distdir + ${PROJECT_NAME}-distdir COMMAND - rm -f /tmp/${PROJECT_NAME}.tar && ${GIT_ARCHIVE_ALL} --prefix - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ ${PROJECT_NAME}.tar - && cd ${CMAKE_BINARY_DIR}/ && - (test - -d - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION} - && - find - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ - -type - d - -print0 - | - xargs - -0 - chmod - a+w - || - true) && rm -rf ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && - ${TAR} xf ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.tar && echo - "${PROJECT_VERSION}" > - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/.version - && ${PROJECT_JRL_CMAKE_MODULE_DIR}/gitlog-to-changelog > - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ChangeLog - && rm -f ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.tar + # cmake-format: off + rm -f /tmp/${PROJECT_NAME}.tar && + ${GIT_ARCHIVE_ALL} --prefix ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ + ${PROJECT_NAME}.tar && + cd ${PROJECT_BINARY_DIR}/ && + ( + test -d ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION} && + find ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ -type d -print0 | + xargs -0 chmod a+w || true + ) && + rm -rf ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && + ${TAR} xf ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.tar && + echo "${PROJECT_VERSION}" > + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/.version && + ${PROJECT_JRL_CMAKE_MODULE_DIR}/gitlog-to-changelog --srcdir ${PROJECT_SOURCE_DIR} > + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ChangeLog && + rm -f ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.tar + # cmake-format: on WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Generating dist directory...") + COMMENT "Generating dist directory for ${PROJECT_NAME}...") + add_dependencies(distdir ${PROJECT_NAME}-distdir) # Create a tar.gz tarball for the project, and generate the signature + if(NOT TARGET dist_targz) + add_custom_target( + dist_targz COMMENT "Generating tar.gz tarball and its signature...") + endif() add_custom_target( - dist_targz + ${PROJECT_NAME}-dist_targz COMMAND + # cmake-format: off ${TAR} -czf ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && ${GPG} - --detach-sign --armor -o - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz.sig - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating tar.gz tarball and its signature...") + ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && + ${GPG} --detach-sign --armor -o + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz.sig + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz + # cmake-format: on + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT + "Generating tar.gz tarball and its signature for ${PROJECT_NAME}...") + add_dependencies(dist_targz ${PROJECT_NAME}-dist_targz) # Create a tar.bz2 tarball for the project, and generate the signature + if(NOT TARGET dist_tarbz2) + add_custom_target( + dist_tarbz2 COMMENT "Generating tar.bz2 tarball and its signature...") + endif() add_custom_target( - dist_tarbz2 + ${PROJECT_NAME}-dist_tarbz2 COMMAND + # cmake-format: off ${TAR} -cjf ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.bz2 - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && ${GPG} - --detach-sign --armor -o - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.bz2.sig - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.bz2 - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating tar.bz2 tarball and its signature...") + ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && + ${GPG} --detach-sign --armor -o + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.bz2.sig + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.bz2 + # cmake-format: on + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT + "Generating tar.bz2 tarball and its signature for ${PROJECT_NAME}...") + add_dependencies(dist_tarbz2 ${PROJECT_NAME}-dist_tarbz2) # Create a tar.xz tarball for the project, and generate the signature + if(NOT TARGET dist_tarxz) + add_custom_target( + dist_tarxz COMMENT "Generating tar.xz tarball and its signature...") + endif() add_custom_target( - dist_tarxz + ${PROJECT_NAME}-dist_tarxz COMMAND + # cmake-format: off ${TAR} -cJf ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.xz - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && ${GPG} - --detach-sign --armor -o - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.xz.sig - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.xz - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating tar.xz tarball and its signature...") + ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ && + ${GPG} --detach-sign --armor -o + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.xz.sig + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.xz + # cmake-format: on + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT + "Generating tar.xz tarball and its signature for ${PROJECT_NAME}...") + add_dependencies(dist_tarxz ${PROJECT_NAME}-dist_tarxz) # Alias: dist = dist_targz (backward compatibility) - add_custom_target(dist DEPENDS dist_targz) + if(NOT TARGET dist) + add_custom_target(dist) + endif() + add_custom_target(${PROJECT_NAME}-dist DEPENDS ${PROJECT_NAME}-dist_targz) + add_dependencies(dist ${PROJECT_NAME}-dist) # TODO: call this during `make clean` + if(NOT TARGET distclean) + add_custom_target(distclean COMMENT "Cleaning dist sources...") + endif() add_custom_target( - distclean + ${PROJECT_NAME}-distclean COMMAND + # cmake-format: off rm -rf - ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Cleaning dist sources...") + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}/ + # cmake-format: on + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Cleaning dist sources for ${PROJECT_NAME}...") + add_dependencies(distclean ${PROJECT_NAME}-distclean) + if(NOT TARGET distorig) + add_custom_target(distorig COMMENT "Generating orig tarball...") + endif() add_custom_target( - distorig + ${PROJECT_NAME}-distorig COMMAND + # cmake-format: off cmake -E copy ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.tar.gz - ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.orig.tar.gz - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating orig tarball...") + ${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION}.orig.tar.gz + # cmake-format: on + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Generating orig tarball for ${PROJECT_NAME}...") + add_dependencies(distorig ${PROJECT_NAME}-distorig) - add_dependencies(dist_targz distdir) - add_dependencies(dist_tarbz2 distdir) - add_dependencies(dist_tarxz distdir) - add_dependencies(distorig dist) + add_dependencies(${PROJECT_NAME}-dist_targz ${PROJECT_NAME}-distdir) + add_dependencies(${PROJECT_NAME}-dist_tarbz2 ${PROJECT_NAME}-distdir) + add_dependencies(${PROJECT_NAME}-dist_tarxz ${PROJECT_NAME}-distdir) + add_dependencies(${PROJECT_NAME}-distorig ${PROJECT_NAME}-dist) else() # FIXME: what to do here? endif() diff --git a/distcheck.cmake b/distcheck.cmake index c2e60cc3e..ba9a2c0dd 100644 --- a/distcheck.cmake +++ b/distcheck.cmake @@ -63,8 +63,11 @@ macro(DISTCHECK_SETUP) string(REPLACE "${CMAKE_SOURCE_DIR}" "${SRCDIR}" NEW_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}") + if(NOT TARGET distcheck) + add_custom_target(distcheck COMMENT "Checking generated tarball...") + endif() add_custom_target( - distcheck + ${PROJECT_NAME}-distcheck COMMAND export LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} && export ${LD_LIBRARY_PATH_VARIABLE_NAME}=$ENV{${LD_LIBRARY_PATH_VARIABLE_NAME}} @@ -129,7 +132,8 @@ macro(DISTCHECK_SETUP) WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${PROJECT_NAME}${PROJECT_SUFFIX}-${PROJECT_VERSION} COMMENT "Checking generated tarball...") - add_dependencies(distcheck distdir) + add_dependencies(distcheck ${PROJECT_NAME}-distcheck) + add_dependencies(${PROJECT_NAME}-distcheck ${PROJECT_NAME}-distdir) unset(NEW_CMAKE_BINARY_DIR) unset(SRCDIR) diff --git a/doxygen.cmake b/doxygen.cmake index 7c7e1cf0c..74db9b4f5 100644 --- a/doxygen.cmake +++ b/doxygen.cmake @@ -518,17 +518,20 @@ macro(_SETUP_PROJECT_DOCUMENTATION) endif(DOXYGEN_DOT_FOUND) # Teach CMake how to generate the documentation. + if(NOT TARGET doc) + add_custom_target(doc ALL COMMENT "Generating Doxygen documentation") + endif() if(MSVC) # FIXME: it is impossible to trigger documentation installation at # install, so put the target in ALL instead. add_custom_target( - doc ALL + ${PROJECT_NAME}-doc COMMAND ${DOXYGEN_EXECUTABLE} ${JRL_CMAKEMODULE_DOXYFILE_PATH} WORKING_DIRECTORY doc COMMENT "Generating Doxygen documentation") else(MSVC) add_custom_target( - doc + ${PROJECT_NAME}-doc COMMAND ${DOXYGEN_EXECUTABLE} ${JRL_CMAKEMODULE_DOXYFILE_PATH} WORKING_DIRECTORY doc COMMENT "Generating Doxygen documentation") @@ -537,10 +540,14 @@ macro(_SETUP_PROJECT_DOCUMENTATION) install(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_MAKE_PROGRAM} doc)") endif(INSTALL_DOCUMENTATION) endif(MSVC) + add_dependencies(doc ${PROJECT_NAME}-doc) if(DOXYGEN_USE_TEMPLATE_CSS) + if(NOT TARGET generate-template-css) + add_custom_target(generate-template-css) + endif() add_custom_target( - generate-template-css + ${PROJECT_NAME}-generate-template-css COMMAND ${DOXYGEN_EXECUTABLE} -w html ${PROJECT_BINARY_DIR}/doc/header.html ${PROJECT_BINARY_DIR}/doc/footer.html @@ -548,7 +555,10 @@ macro(_SETUP_PROJECT_DOCUMENTATION) BYPRODUCTS ${PROJECT_BINARY_DIR}/doc/header.html ${PROJECT_BINARY_DIR}/doc/footer.html ${PROJECT_BINARY_DIR}/doc/doxygen.css) - add_dependencies(doc generate-template-css) + add_dependencies(generate-template-css + ${PROJECT_NAME}-generate-template-css) + add_dependencies(${PROJECT_NAME}-doc + ${PROJECT_NAME}-generate-template-css) _set_if_undefined(DOXYGEN_HTML_HEADER "${PROJECT_BINARY_DIR}/doc/header.html") _set_if_undefined(DOXYGEN_HTML_FOOTER diff --git a/package-config.cmake b/package-config.cmake index 7d8e8da41..7f664c4c1 100644 --- a/package-config.cmake +++ b/package-config.cmake @@ -57,11 +57,19 @@ macro(_SETUP_PROJECT_PACKAGE_INIT) CACHE INTERNAL "") endmacro(_SETUP_PROJECT_PACKAGE_INIT) -# .rst: .. command:: ADD_PROJECT_DEPENDENCY(ARGS [PKG_CONFIG_REQUIRES pkg] -# [FOR_COMPONENT component] [FIND_EXTERNAL pkg]) +# .rst: +# ~~~ +# .. command:: ADD_PROJECT_DEPENDENCY(ARGS +# [PKG_CONFIG_REQUIRES pkg] +# [FOR_COMPONENT component] +# [FIND_EXTERNAL pkg]) +# ~~~ # # This is a wrapper around find_package to add correct find_dependency calls in -# the generated config script. All arguments are passed to find_package. +# the generated config script. +# +# Packages not in the PROJECT_PACKAGES_IN_WORKSPACE are searched with +# find_package. # # In cases where find_package is not supported by a project, or only in recent # versions, one should provide a custom Config.cmake or use a more @@ -110,7 +118,10 @@ macro(ADD_PROJECT_DEPENDENCY) _add_to_list_if_not_present( _PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_DEPENDENCY "find_dependency(${PACKAGE_ARGS})") - find_package(${PARSED_ARGN_UNPARSED_ARGUMENTS}) + list(GET PARSED_ARGN_UNPARSED_ARGUMENTS 0 _package_name) + if(NOT ${_package_name} IN_LIST PROJECT_PACKAGES_IN_WORKSPACE) + find_package(${PARSED_ARGN_UNPARSED_ARGUMENTS}) + endif() # Propagate variables changes to the cached values set(_PACKAGE_CONFIG${component}_DEPENDENCIES_PROJECTS @@ -124,6 +135,23 @@ macro(ADD_PROJECT_DEPENDENCY) CACHE INTERNAL "") endmacro() +# .rst: +# ~~~ +# .. command:: ADD_PROJECT_PRIVATE_DEPENDENCY() +# ~~~ +# +# This is a wrapper around find_package. +# +# Packages not in the PROJECT_PACKAGES_IN_WORKSPACE are searched with +# find_package. +macro(ADD_PROJECT_PRIVATE_DEPENDENCY) + set(ALL_ARGUMENTS ${ARGN}) + list(GET ALL_ARGUMENTS 0 _package_name) + if(NOT ${_package_name} IN_LIST PROJECT_PACKAGES_IN_WORKSPACE) + find_package(${ALL_ARGUMENTS}) + endif() +endmacro() + # SETUP_PROJECT_PACKAGE_FINALIZE # ------------- # @@ -265,7 +293,8 @@ macro(PROJECT_INSTALL_COMPONENT COMPONENT) "${_PACKAGE_CONFIG_${COMPONENT}_DEPENDENCIES_FIND_PACKAGE}") string(REPLACE ";" "\n " COMPONENT_FIND_DEPENDENCY "${_PACKAGE_CONFIG_${COMPONENT}_DEPENDENCIES_FIND_DEPENDENCY}") - set(COMPONENT_CONFIG "${CMAKE_BINARY_DIR}/generated/${COMPONENT}Config.cmake") + set(COMPONENT_CONFIG + "${PROJECT_BINARY_DIR}/generated/${COMPONENT}Config.cmake") set(COMPONENT_EXTRA_MACRO "${PARSED_ARGN_EXTRA_MACRO}") include(CMakePackageConfigHelpers) configure_package_config_file( diff --git a/python-helpers.cmake b/python-helpers.cmake index bf8124834..16c7351aa 100644 --- a/python-helpers.cmake +++ b/python-helpers.cmake @@ -39,8 +39,9 @@ endmacro() # function(PYTHON_BUILD_GET_TARGET python_build_target) # Regex from IsValidTargetName in CMake/Source/cmGeneratorExpression.cxx - string(REGEX REPLACE "[^A-Za-z0-9_.+-]" "_" compile_pyc - "compile_pyc_${CMAKE_CURRENT_SOURCE_DIR}") + string(REGEX + REPLACE "[^A-Za-z0-9_.+-]" "_" compile_pyc + "${PROJECT_NAME}_compile_pyc_${CMAKE_CURRENT_SOURCE_DIR}") if(NOT TARGET ${compile_pyc}) add_custom_target(${compile_pyc} ALL) diff --git a/release.cmake b/release.cmake index d0171edfb..6214742bd 100644 --- a/release.cmake +++ b/release.cmake @@ -58,20 +58,27 @@ macro(RELEASE_SETUP) set(LD_LIBRARY_PATH_VARIABLE_NAME "LD_LIBRARY_PATH") endif(APPLE) + if(NOT TARGET release_package_xml) + add_custom_target(release_package_xml COMMENT "Update package.xml") + endif() add_custom_target( - release_package_xml + ${PROJECT_NAME}-release_package_xml WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Update package.xml" + COMMENT "Update package.xml for ${PROJECT_NAME}" COMMAND sed -i.back \"s|.*|$$VERSION|g\" package.xml && rm package.xml.back && ${GIT} add package.xml && ${GIT} commit -m "release: Update package.xml version to $$VERSION" && echo "Updated package.xml and committed") + add_dependencies(release_package_xml ${PROJECT_NAME}-release_package_xml) + if(NOT TARGET release_pyproject_toml) + add_custom_target(release_pyproject_toml COMMENT "Update pyproject.toml") + endif() add_custom_target( - release_pyproject_toml + ${PROJECT_NAME}-release_pyproject_toml WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Update pyproject.toml" + COMMENT "Update pyproject.toml for ${PROJECT_NAME}" COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_JRL_CMAKE_MODULE_DIR}/pyproject.py $$VERSION && if ! (git diff --quiet pyproject.toml) ; then @@ -86,11 +93,16 @@ macro(RELEASE_SETUP) && echo "Updated pyproject.toml and committed") ; fi) + add_dependencies(release_pyproject_toml + ${PROJECT_NAME}-release_pyproject_toml) + if(NOT TARGET release_changelog) + add_custom_target(release_changelog COMMENT "Update CHANGELOG.md") + endif() add_custom_target( - release_changelog + ${PROJECT_NAME}-release_changelog WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Update CHANGELOG.md" + COMMENT "Update CHANGELOG.md for ${PROJECT_NAME}" COMMAND sed -i.back "\"s|\#\# \\[Unreleased\\]|\#\# [Unreleased]\\n\\n\#\# [$$VERSION] - ${TODAY}|\"" @@ -108,11 +120,15 @@ macro(RELEASE_SETUP) && echo "Updated CHANGELOG.md and committed") ; fi) + add_dependencies(release_changelog ${PROJECT_NAME}-release_changelog) + if(NOT TARGET release_pixi_toml) + add_custom_target(release_pixi_toml COMMENT "Update pixi.toml") + endif() add_custom_target( - release_pixi_toml + ${PROJECT_NAME}-release_pixi_toml WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Update pixi.toml" + COMMENT "Update pixi.toml for ${PROJECT_NAME}" COMMAND # cmake-format: off ${PYTHON_EXECUTABLE} ${PROJECT_JRL_CMAKE_MODULE_DIR}/pixi.py $$VERSION && @@ -124,23 +140,31 @@ macro(RELEASE_SETUP) ) ; fi # cmake-format: on ) + add_dependencies(release_pixi_toml ${PROJECT_NAME}-release_pixi_toml) + if(NOT TARGET release_citation_cff) + add_custom_target(release_citation_cff COMMENT "Update CITATION.cff") + endif() add_custom_target( - release_citation_cff + ${PROJECT_NAME}-release_citation_cff WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Update CITATION.cff" + COMMENT "Update CITATION.cff for ${PROJECT_NAME}" COMMAND sed -i.back "\"s|^version:.*|version: $$VERSION|;s|^date-released:.*|date-released: \\\"${TODAY}\\\"|\"" CITATION.cff && rm CITATION.cff.back && ${GIT} add CITATION.cff && ${GIT} commit -m "release: Update CITATION.cff version to $$VERSION" && echo "Updated CITATION.cff and committed") + add_dependencies(release_citation_cff ${PROJECT_NAME}-release_citation_cff) - set(BUILD_CMD ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target) + set(BUILD_CMD ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR} --target) + if(NOT TARGET release) + add_custom_target(release COMMENT "Create a new release") + endif() add_custom_target( - release + ${PROJECT_NAME}-release WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Create a new release" + COMMENT "Create a new release for ${PROJECT_NAME}" COMMAND # cmake-format: off export LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} && @@ -148,31 +172,32 @@ macro(RELEASE_SETUP) export PYTHONPATH=$ENV{PYTHONPATH} && ! test x$$VERSION = x || (echo "Please set a version for this release" && false) && # Update version in package.xml if it exists - if [ -f "package.xml" ]; then (${BUILD_CMD} release_package_xml) ; fi && + if [ -f "package.xml" ]; then (${BUILD_CMD} ${PROJECT_NAME}-release_package_xml) ; fi && # Update version in pyproject.toml if it exists - if [ -f "pyproject.toml" ]; then (${BUILD_CMD} release_pyproject_toml) ; fi && + if [ -f "pyproject.toml" ]; then (${BUILD_CMD} ${PROJECT_NAME}-release_pyproject_toml) ; fi && # Update CHANGELOG.md if it exists - if [ -f "CHANGELOG.md" ]; then (${BUILD_CMD} release_changelog) ; fi && + if [ -f "CHANGELOG.md" ]; then (${BUILD_CMD} ${PROJECT_NAME}-release_changelog) ; fi && # Update version in pixi.toml if it exists - if [ -f "pixi.toml" ]; then (${BUILD_CMD} release_pixi_toml) ; fi && + if [ -f "pixi.toml" ]; then (${BUILD_CMD} ${PROJECT_NAME}-release_pixi_toml) ; fi && # Update date and version in CITATION.cff if it exists - if [ -f "CITATION.cff" ]; then (${BUILD_CMD} release_citation_cff) ; fi && + if [ -f "CITATION.cff" ]; then (${BUILD_CMD} ${PROJECT_NAME}-release_citation_cff) ; fi && ${GIT} tag -s v$$VERSION -m "Release of version $$VERSION." && - cd ${CMAKE_BINARY_DIR} && + cd ${PROJECT_BINARY_DIR} && cmake ${PROJECT_SOURCE_DIR} && - ${BUILD_CMD} distcheck || + ${BUILD_CMD} ${PROJECT_NAME}-distcheck || ( echo "Please fix distcheck first." && cd ${PROJECT_SOURCE_DIR} && ${GIT} tag -d v$$VERSION && - cd ${CMAKE_BINARY_DIR} && + cd ${PROJECT_BINARY_DIR} && cmake ${PROJECT_SOURCE_DIR} && false ) && - ${BUILD_CMD} dist && - ${BUILD_CMD} distclean && + ${BUILD_CMD} ${PROJECT_NAME}-dist && + ${BUILD_CMD} ${PROJECT_NAME}-distclean && echo "Please, run 'git push --tags' and upload the tarball to github to finalize this release." # cmake-format: on ) + add_dependencies(release ${PROJECT_NAME}-release) endif() endmacro() diff --git a/sphinx.cmake b/sphinx.cmake index 620fecf51..52337b171 100644 --- a/sphinx.cmake +++ b/sphinx.cmake @@ -39,11 +39,15 @@ macro(SPHINX_SETUP) WARNING "Failed to find sphinx, documentation will not be generated.") else(NOT SPHINX_BUILD) + if(NOT TARGET sphinx-doc) + add_custom_target(sphinx-doc ALL + COMMENT "Generating sphinx documentation") + endif() if(MSVC) # FIXME: it is impossible to trigger documentation installation at # install, so put the target in ALL instead. add_custom_target( - sphinx-doc ALL + ${PROJECT_NAME}-sphinx-doc COMMAND ${PYTHON_EXECUTABLE} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/sphinx @@ -55,7 +59,7 @@ macro(SPHINX_SETUP) set(EXTRA_LD_PATH "\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\":") set(EXTRA_LD_PATH "${EXTRA_LD_PATH}\"${DYNAMIC_GRAPH_PLUGINDIR}\":") add_custom_target( - sphinx-doc + ${PROJECT_NAME}-sphinx-doc COMMAND export DYLD_LIBRARY_PATH=${EXTRA_LD_PATH}:\$DYLD_LIBRARY_PATH \; ${PYTHON_EXECUTABLE} ${SPHINX_BUILD} -b html @@ -73,7 +77,7 @@ macro(SPHINX_SETUP) set(EXTRA_LD_PATH "\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\":") set(EXTRA_LD_PATH "${EXTRA_LD_PATH}\"${DYNAMIC_GRAPH_PLUGINDIR}\":") add_custom_target( - sphinx-doc + ${PROJECT_NAME}-sphinx-doc COMMAND export LD_LIBRARY_PATH=${EXTRA_LD_PATH}:$$LD_LIBRARY_PATH \; ${PYTHON_EXECUTABLE} ${SPHINX_BUILD} -b html @@ -86,9 +90,10 @@ macro(SPHINX_SETUP) CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_MAKE_PROGRAM} sphinx-doc)") endif(INSTALL_DOCUMENTATION) endif(MSVC) + add_dependencies(sphinx-doc ${PROJECT_NAME}-sphinx-doc) add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/doc/sphinx-html + OUTPUT ${PROJECT_BINARY_DIR}/doc/sphinx-html COMMAND ${PYTHON_EXECUTABLE} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/sphinx @@ -99,11 +104,12 @@ macro(SPHINX_SETUP) set_property( DIRECTORY APPEND - PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/doc/sphinx-html) + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES + ${PROJECT_BINARY_DIR}/doc/sphinx-html) # Install generated files. if(INSTALL_DOCUMENTATION) - install(DIRECTORY ${CMAKE_BINARY_DIR}/doc/sphinx-html + install(DIRECTORY ${PROJECT_BINARY_DIR}/doc/sphinx-html DESTINATION share/doc/${PROJECT_NAME}) if(EXISTS ${PROJECT_SOURCE_DIR}/doc/pictures) diff --git a/stubs.cmake b/stubs.cmake index 31a76bc3d..b46998471 100644 --- a/stubs.cmake +++ b/stubs.cmake @@ -85,10 +85,12 @@ function(GENERATE_STUBS module_path module_name module_install_dir) # Regex from IsValidTargetName in CMake/Source/cmGeneratorExpression.cxx if(NOT module_path) string(REGEX REPLACE "[^A-Za-z0-9_.+-]" "_" target_name - "generate_stubs_${module_name}") + "${PROJECT_NAME}-generate_stubs_${module_name}") else() - string(REGEX REPLACE "[^A-Za-z0-9_.+-]" "_" target_name - "generate_stubs_${module_path}_${module_name}") + string( + REGEX + REPLACE "[^A-Za-z0-9_.+-]" "_" target_name + "${PROJECT_NAME}-generate_stubs_${module_path}_${module_name}") endif() if($ENV{PYTHONPATH}) diff --git a/test.cmake b/test.cmake index 7b51fe3f4..9cb9dbb3b 100644 --- a/test.cmake +++ b/test.cmake @@ -50,10 +50,14 @@ endif() # Add new target 'run_tests' to improve integration with build tooling if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode" AND NOT TARGET run_tests) + if(NOT TARGET run_tests) + add_custom_target(run_tests) + endif() add_custom_target( - run_tests + ${PROJECT_NAME}-run_tests COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -V VERBATIM) + add_dependencies(run_tests ${PROJECT_NAME}-run_tests) endif() if(NOT DEFINED ctest_build_tests_exists) @@ -73,7 +77,7 @@ macro(CREATE_CTEST_BUILD_TESTS_TARGET) ctest_build_tests "${CMAKE_COMMAND}" --build - ${CMAKE_BINARY_DIR} + ${PROJECT_BINARY_DIR} --target build_tests -- @@ -121,7 +125,9 @@ endmacro( # # Fill `result` with all necessary environment variables (`PYTHONPATH`, # `LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`) to load the `MODULES` in -# `CMAKE_BINARY_DIR` (`CMAKE_BINARY_DIR/MODULE_PATH`) +# `PROJECT_BINARY_DIR` (`PROJECT_BINARY_DIR/MODULE_PATH`) +# +# Path in PROJECT_PYTHON_PACKAGES_IN_WORKSPACE are added to the PYTHONPATH. # # .. note:: :command:`FINDPYTHON` should have been called first. # @@ -129,9 +135,9 @@ function(COMPUTE_PYTHONPATH result) set(MODULES "${ARGN}") # ARGN is not a variable foreach(MODULE_PATH IN LISTS MODULES) if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode") - list(APPEND PYTHONPATH "${CMAKE_BINARY_DIR}/${MODULE_PATH}/$") + list(APPEND PYTHONPATH "${PROJECT_BINARY_DIR}/${MODULE_PATH}/$") else() - list(APPEND PYTHONPATH "${CMAKE_BINARY_DIR}/${MODULE_PATH}") + list(APPEND PYTHONPATH "${PROJECT_BINARY_DIR}/${MODULE_PATH}") endif() endforeach(MODULE_PATH IN LISTS MODULES) @@ -139,6 +145,8 @@ function(COMPUTE_PYTHONPATH result) list(APPEND PYTHONPATH "$ENV{PYTHONPATH}") endif(DEFINED ENV{PYTHONPATH}) + list(APPEND PYTHONPATH ${PROJECT_PYTHON_PACKAGES_IN_WORKSPACE}) + # get path separator to join those paths execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-c" "import os; print(os.pathsep)" @@ -167,8 +175,8 @@ endfunction() # .rst: .. command:: ADD_PYTHON_UNIT_TEST (NAME SOURCE [MODULES...]) # # Add a test called `NAME` that runs an equivalent of ``python ${SOURCE}``, -# optionnaly with a `PYTHONPATH` set to `CMAKE_BINARY_DIR/MODULE_PATH` for each -# MODULES `SOURCE` is relative to `PROJECT_SOURCE_DIR` +# optionnaly with a `PYTHONPATH` set to `PROJECT_BINARY_DIR/MODULE_PATH` for +# each MODULES `SOURCE` is relative to `PROJECT_SOURCE_DIR` # # .. note:: :command:`FINDPYTHON` should have been called first. # @@ -199,7 +207,7 @@ endmacro( # # Add a test called `NAME` that runs an equivalent of ``valgrind -- python # ${SOURCE}``, optionnaly with a `PYTHONPATH` set to -# `CMAKE_BINARY_DIR/MODULE_PATH` for each MODULES. `SOURCE` is relative to +# `PROJECT_BINARY_DIR/MODULE_PATH` for each MODULES. `SOURCE` is relative to # `PROJECT_SOURCE_DIR`. # # .. note:: :command:`FINDPYTHON` should have been called first. .. note:: Only @@ -229,7 +237,7 @@ endmacro() # source dir. # # :param MODULES: Set the `PYTHONPATH` environment variable to -# `CMAKE_BINARY_DIR/...`. +# `PROJECT_BINARY_DIR/...`. # # .. note:: :command:`FINDPYTHON` should have been called first. # diff --git a/uninstall.cmake b/uninstall.cmake index 5a60ec08c..1d5312ed6 100644 --- a/uninstall.cmake +++ b/uninstall.cmake @@ -42,11 +42,15 @@ macro(_SETUP_PROJECT_UNINSTALL) "${CMAKE_CURRENT_LIST_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" @ONLY) + if(NOT TARGET uninstall) + add_custom_target(uninstall) + endif() add_custom_target( - uninstall + ${PROJECT_NAME}-uninstall "${CMAKE_COMMAND}" -DPACKAGE_CREATES_DOT_CATKIN=${PACKAGE_CREATES_DOT_CATKIN} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake") + add_dependencies(uninstall ${PROJECT_NAME}-uninstall) configure_file( "${CMAKE_CURRENT_LIST_DIR}/cmake_reinstall.cmake.in" @@ -62,10 +66,15 @@ macro(_SETUP_PROJECT_UNINSTALL) GENERATE OUTPUT "${PROJECT_BINARY_DIR}/cmake/$/cmake_reinstall.cmake" INPUT "${PROJECT_BINARY_DIR}/cmake/cmake_reinstall.cmake.configured") + + if(NOT TARGET reinstall) + add_custom_target(reinstall) + endif() add_custom_target( - reinstall + ${PROJECT_NAME}-reinstall "${CMAKE_COMMAND}" -P "${PROJECT_BINARY_DIR}/cmake/$/cmake_reinstall.cmake") + add_dependencies(reinstall ${PROJECT_NAME}-reinstall) endmacro(_SETUP_PROJECT_UNINSTALL) # We setup the auto-uninstall target here, it is early enough that we can ensure diff --git a/version.cmake b/version.cmake index 4a7fb1a8f..faa666156 100644 --- a/version.cmake +++ b/version.cmake @@ -204,6 +204,7 @@ macro(VERSION_COMPUTE) set(PROJECT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") endif() endif() + if(NOT DEFINED PROJECT_VERSION_COMPUTATION_METHODS) list(APPEND PROJECT_VERSION_COMPUTATION_METHODS "ROS_PACKAGE_XML_FILE" "DOT_VERSION_FILE" "GIT_DESCRIBE")