diff --git a/.github/workflows/generate-conda-packages.yaml b/.github/workflows/generate-conda-packages.yaml new file mode 100644 index 000000000..06a5304dc --- /dev/null +++ b/.github/workflows/generate-conda-packages.yaml @@ -0,0 +1,112 @@ +name: Generate conda packages +# This action automatically generate conda packages for the packages in the robotology-superbuild +# Check doc/conda-recipe-generation.md for more info + +on: + workflow_dispatch: + schedule: + # Run the job once a week + - cron: '0 0 * * 2' + +jobs: + generate-conda-packages: + name: "Generate conda packages @${{ matrix.os }}" + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + conda_platform: linux-64 + - os: macos-latest + conda_platform: osx-64 + - os: windows-2019 + conda_platform: win-64 + + steps: + - uses: actions/checkout@v2 + + - uses: conda-incubator/setup-miniconda@v2 + with: + mamba-version: "*" + channels: conda-forge + channel-priority: true + python-version: "3.8" + + - name: Install files to enable compilation of mex files [Conda/Linux] + if: contains(matrix.os, 'ubuntu') + run: | + curl -L -O https://github.com/robotology/robotology-vcpkg-ports/releases/download/storage/msdk_R2020b_mexa64.zip + unzip msdk_R2020b_mexa64.zip + rm msdk_R2020b_mexa64.zip + echo "GHA_Matlab_ROOT_DIR=${GITHUB_WORKSPACE}/msdk_R2020b_mexa64" >> $GITHUB_ENV + echo "GHA_Matlab_MEX_EXTENSION=mexa64" >> $GITHUB_ENV + + - name: Install files to enable compilation of mex files [Conda/macOS] + if: contains(matrix.os, 'macos') + run: | + curl -L -O https://github.com/robotology/robotology-vcpkg-ports/releases/download/storage/msdk_R2020a_mexmaci64.zip + unzip msdk_R2020a_mexmaci64.zip + rm msdk_R2020a_mexmaci64.zip + echo "GHA_Matlab_ROOT_DIR=${GITHUB_WORKSPACE}/msdk_R2020a_mexmaci64" >> $GITHUB_ENV + echo "GHA_Matlab_MEX_EXTENSION=mexmaci64" >> $GITHUB_ENV + + - name: Install files to enable compilation of mex files [Conda/Windows] + if: contains(matrix.os, 'windows') + shell: bash + run: | + curl -L -O https://github.com/robotology/robotology-vcpkg-ports/releases/download/storage/msdk_R2020a_mexw64.zip + unzip msdk_R2020a_mexw64.zip + rm msdk_R2020a_mexw64.zip + echo "GHA_Matlab_ROOT_DIR=${GITHUB_WORKSPACE}/msdk_R2020a_mexw64" >> $GITHUB_ENV + echo "GHA_Matlab_MEX_EXTENSION=mexw64" >> $GITHUB_ENV + + # Python 3.8 is required by https://github.com/Anaconda-Platform/anaconda-client/pull/551 + - name: Dependencies for conda recipes generation and upload + shell: bash -l {0} + run: | + mamba install pyyaml jinja2 conda-build ninja anaconda-client + python -m pip install git+https://github.com/wolfv/multisheller.git@0cc03c68d0c68d2f9cf7b07ddb68afa531419a6d + + - name: Generate recipes [Linux&macOS] + if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') + shell: bash -l {0} + run: | + mkdir build + cd build + cmake -GNinja -C ${GITHUB_WORKSPACE}/.ci/initial-cache.gh.cmake -DYCM_EP_ADDITIONAL_CMAKE_ARGS:STRING="-DMatlab_ROOT_DIR:PATH=${GHA_Matlab_ROOT_DIR} -DMatlab_MEX_EXTENSION:STRING=${GHA_Matlab_MEX_EXTENSION}" -DROBOTOLOGY_USES_MATLAB:BOOL=ON -DROBOTOLOGY_PROJECT_TAGS=LatestRelease -DROBOTOLOGY_GENERATE_CONDA_RECIPES:BOOL=ON .. + + - name: Generate recipes [Windows] + if: contains(matrix.os, 'windows') + shell: bash -l {0} + run: | + mkdir build + cd build + cmake -G"Visual Studio 16 2019" -C ${GITHUB_WORKSPACE}/.ci/initial-cache.gh.cmake -DYCM_EP_ADDITIONAL_CMAKE_ARGS:STRING="-DMatlab_ROOT_DIR:PATH=${GHA_Matlab_ROOT_DIR} -DMatlab_MEX_EXTENSION:STRING=${GHA_Matlab_MEX_EXTENSION}" -DROBOTOLOGY_USES_MATLAB:BOOL=ON -DROBOTOLOGY_PROJECT_TAGS=LatestRelease -DROBOTOLOGY_GENERATE_CONDA_RECIPES:BOOL=ON .. + + # Disable options not tested on Conda for now + # Reference issue: https://github.com/robotology/robotology-superbuild/issues/563 + - name: Disable options not supported in conda + shell: bash -l {0} + run: | + # Cleanup recipes + rm -rf build/conda/generated_recipes + # Re-generate + cd build + cmake -DROBOTOLOGY_USES_OCTAVE:BOOL=OFF -DROBOTOLOGY_USES_PYTHON:BOOL=OFF . + + - name: Build conda packages + shell: bash -l {0} + run: | + cd build/conda/generated_recipes + conda build -m ${GITHUB_WORKSPACE}/conda/conda_build_config.yml . + - name: Upload conda packages + shell: bash -l {0} + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + run: | + cd ${CONDA_PREFIX}/conda-bld/${{ matrix.conda_platform}}/ + ls *.tar.bz2 + anaconda upload --skip-existing *.tar.bz2 + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b0a64b26..07092d090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,15 @@ include(RobotologySuperbuildOptions) set(YCM_FOLDER src) set(YCM_COMPONENT core) set(YCM_MINIMUM_VERSION 0.11.1) + +# Include logic for generating Conda recipes (by default it is disabled) and exit +if(ROBOTOLOGY_GENERATE_CONDA_RECIPES) + message(STATUS "ROBOTOLOGY_GENERATE_CONDA_RECIPES CMake option enabled, generating conda recipes.") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/conda/cmake") + include(RobotologySuperbuildGenerateCondaRecipes) + return() +endif() + include(YCMBootstrap) include(FindOrBuildPackage) @@ -44,6 +53,7 @@ include(YCMEPHelper) # depending on which profiles are enabled include(RobotologySuperbuildLogic) + if(ROBOTOLOGY_USES_MATLAB) # The following line is to properly configure the matlab and simulink software installed by the superbuild configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/template/startup_robotology_superbuild.m.in ${CMAKE_BINARY_DIR}/startup_robotology_superbuild.m) diff --git a/cmake/BuildCppAD.cmake b/cmake/BuildCppAD.cmake index b0cb87cad..e2cf05e99 100644 --- a/cmake/BuildCppAD.cmake +++ b/cmake/BuildCppAD.cmake @@ -10,3 +10,6 @@ ycm_ep_helper(CppAD TYPE GIT TAG master COMPONENT external FOLDER src) + +set(CppAD_CONDA_PKG_NAME cppad) +set(CppAD_CONDA_PKG_CONDA_FORGE_OVERRIDE ON) diff --git a/cmake/BuildGazeboYARPPlugins.cmake b/cmake/BuildGazeboYARPPlugins.cmake index 09f23606d..811c4f565 100644 --- a/cmake/BuildGazeboYARPPlugins.cmake +++ b/cmake/BuildGazeboYARPPlugins.cmake @@ -40,3 +40,5 @@ ycm_ep_helper(GazeboYARPPlugins TYPE GIT DEPENDS YARP gazebo CMAKE_ARGS -DGAZEBO_YARP_PLUGINS_HAS_OPENCV:BOOL=ON) + +set(GazeboYARPPlugins_CONDA_DEPENDENCIES opencv gazebo) diff --git a/cmake/BuildICUB.cmake b/cmake/BuildICUB.cmake index ef72fe983..21607fb54 100644 --- a/cmake/BuildICUB.cmake +++ b/cmake/BuildICUB.cmake @@ -8,6 +8,7 @@ include(FindOrBuildPackage) find_or_build_package(YARP QUIET) set(ICUB_DEPENDS "") +list(APPEND ICUB_DEPENDS YCM) list(APPEND ICUB_DEPENDS YARP) if(ROBOTOLOGY_ENABLE_ICUB_HEAD) @@ -81,3 +82,16 @@ ycm_ep_helper(ICUB TYPE GIT -DENABLE_icubmod_socketcan:BOOL=${ENABLE_icubmod_socketcan} -DICUB_USE_icub_firmware_shared:BOOL=${ROBOTOLOGY_ENABLE_ICUB_HEAD} -DICUBMAIN_COMPILE_SIMULATORS:BOOL=${ICUBMAIN_COMPILE_SIMULATORS}) + +# Options related to generation of conda binary packages +set(ICUB_CONDA_DEPENDENCIES ace opencv gsl ipopt libode qt sdl) +if(NOT (APPLE OR WIN32)) + list(APPEND ICUB_CONDA_DEPENDENCIES libdc1394) +endif() + +if(NOT APPLE) + list(APPEND ICUB_CONDA_DEPENDENCIES freeglut) +endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND ICUB_CONDA_DEPENDENCIES libglu) +endif() diff --git a/cmake/BuildLieGroupControllers.cmake b/cmake/BuildLieGroupControllers.cmake index e89154dc0..9dba63d61 100644 --- a/cmake/BuildLieGroupControllers.cmake +++ b/cmake/BuildLieGroupControllers.cmake @@ -13,3 +13,5 @@ ycm_ep_helper(LieGroupControllers TYPE GIT COMPONENT dynamics FOLDER src DEPENDS manif) + +set(LieGroupControllers_CONDA_DEPENDENCIES eigen) diff --git a/cmake/BuildOsqpEigen.cmake b/cmake/BuildOsqpEigen.cmake index fc2e74d15..a8efcacc3 100644 --- a/cmake/BuildOsqpEigen.cmake +++ b/cmake/BuildOsqpEigen.cmake @@ -14,3 +14,5 @@ ycm_ep_helper(OsqpEigen TYPE GIT FOLDER src CMAKE_ARGS -DBUILD_TESTING:BOOL=OFF DEPENDS osqp) + +set(OsqpEigen_CONDA_DEPENDENCIES "eigen") \ No newline at end of file diff --git a/cmake/BuildUnicyclePlanner.cmake b/cmake/BuildUnicyclePlanner.cmake index 0489b028e..4152ee094 100644 --- a/cmake/BuildUnicyclePlanner.cmake +++ b/cmake/BuildUnicyclePlanner.cmake @@ -14,3 +14,5 @@ ycm_ep_helper(UnicyclePlanner TYPE GIT COMPONENT dynamics FOLDER src DEPENDS iDynTree) + +set(UnicyclePlanner_CONDA_DEPENDENCIES eigen) diff --git a/cmake/BuildWBToolbox.cmake b/cmake/BuildWBToolbox.cmake index f17f96516..237fdbbb6 100644 --- a/cmake/BuildWBToolbox.cmake +++ b/cmake/BuildWBToolbox.cmake @@ -23,3 +23,5 @@ ycm_ep_helper(WBToolbox TYPE GIT iDynTree qpOASES BlockFactory) + +set(WBToolbox_CONDA_DEPENDENCIES eigen) diff --git a/cmake/BuildYARP.cmake b/cmake/BuildYARP.cmake index 04e1da2a2..84331bb46 100644 --- a/cmake/BuildYARP.cmake +++ b/cmake/BuildYARP.cmake @@ -5,10 +5,6 @@ include(YCMEPHelper) include(FindOrBuildPackage) -find_package(ACE QUIET) -find_package(SQLite QUIET) -find_package(Eigen3 QUIET) - set(YARP_OPTIONAL_DEPS "") if(ROBOTOLOGY_ENABLE_ROBOT_TESTING) find_or_build_package(RobotTestingFramework QUIET) @@ -17,8 +13,6 @@ endif() # Workaround for https://github.com/robotology/robotology-superbuild/issues/377 if(NOT APPLE) - find_package(SQLite QUIET) - list(APPEND YARP_OPTIONAL_DEPS SQLite) set(YARP_OPTIONAL_CMAKE_ARGS "") else() set(YARP_OPTIONAL_CMAKE_ARGS "-DYARP_USE_SYSTEM_SQLite:BOOL=OFF") @@ -51,8 +45,6 @@ ycm_ep_helper(YARP TYPE GIT COMPONENT core FOLDER src DEPENDS YCM - ACE - Eigen3 ${YARP_OPTIONAL_DEPS} CMAKE_ARGS -DYARP_COMPILE_GUIS:BOOL=ON -DYARP_USE_SYSTEM_SQLite:BOOL=ON @@ -89,3 +81,5 @@ ycm_ep_helper(YARP TYPE GIT -DCREATE_LUA:BOOL=${ROBOTOLOGY_USES_LUA} -DENABLE_yarpmod_usbCamera:BOOL=${ENABLE_USBCAMERA} ${YARP_OPTIONAL_CMAKE_ARGS}) + +set(YARP_CONDA_DEPENDENCIES ace opencv tinyxml qt eigen sdl sdl2 sqlite libjpeg-turbo) diff --git a/cmake/Buildbipedal-locomotion-framework.cmake b/cmake/Buildbipedal-locomotion-framework.cmake index 8be4b39cf..4d8ed2e41 100644 --- a/cmake/Buildbipedal-locomotion-framework.cmake +++ b/cmake/Buildbipedal-locomotion-framework.cmake @@ -45,3 +45,5 @@ ycm_ep_helper(bipedal-locomotion-framework TYPE GIT -DFRAMEWORK_USE_casadi:BOOL=${ROBOTOLOGY_ENABLE_DYNAMICS_FULL_DEPS} -DFRAMEWORK_USE_LieGroupControllers:BOOL=${ROBOTOLOGY_ENABLE_DYNAMICS_FULL_DEPS} DEPENDS ${bipedal-locomotion-framework_DEPENDS}) + +set(bipedal-locomotion-framework_CONDA_DEPENDENCIES eigen) diff --git a/cmake/Buildblocktest-yarp-plugins.cmake b/cmake/Buildblocktest-yarp-plugins.cmake index 5a6052f81..1b2b2db75 100644 --- a/cmake/Buildblocktest-yarp-plugins.cmake +++ b/cmake/Buildblocktest-yarp-plugins.cmake @@ -17,3 +17,6 @@ ycm_ep_helper(blocktest-yarp-plugins TYPE GIT DEPENDS YARP blocktestcore CMAKE_CACHE_ARGS -DENABLE_MSVC_WARNINGS:BOOL=OFF) + +set(blocktest-yarp-plugins_CONDA_DEPENDENCIES boost-cpp) +set(blocktest-yarp-plugins_CONDA_VERSION "1.1.0.1") diff --git a/cmake/Buildblocktestcore.cmake b/cmake/Buildblocktestcore.cmake index 75f70c23f..cbfe189b7 100644 --- a/cmake/Buildblocktestcore.cmake +++ b/cmake/Buildblocktestcore.cmake @@ -14,3 +14,6 @@ ycm_ep_helper(blocktestcore TYPE GIT FOLDER src CMAKE_CACHE_ARGS -DENABLE_MSVC_WARNINGS:BOOL=OFF DEPENDS YCM) + +set(blocktestcore_CONDA_DEPENDENCIES qt boost-cpp) +set(blocktestcore_CONDA_VERSION "2.3.0.1") diff --git a/cmake/Buildcasadi.cmake b/cmake/Buildcasadi.cmake index 7898adc2d..472bc2c22 100644 --- a/cmake/Buildcasadi.cmake +++ b/cmake/Buildcasadi.cmake @@ -22,3 +22,6 @@ ycm_ep_helper(casadi TYPE GIT -DLIB_PREFIX:PATH=lib -DBIN_PREFIX:PATH=bin DEPENDS osqp) + +set(casadi_CONDA_PKG_NAME casadi) +set(casadi_CONDA_PKG_CONDA_FORGE_OVERRIDE ON) diff --git a/cmake/Buildhuman-dynamics-estimation.cmake b/cmake/Buildhuman-dynamics-estimation.cmake index a71e0f310..d13cf1c06 100644 --- a/cmake/Buildhuman-dynamics-estimation.cmake +++ b/cmake/Buildhuman-dynamics-estimation.cmake @@ -21,3 +21,5 @@ ycm_ep_helper(human-dynamics-estimation TYPE GIT wearables osqp OsqpEigen) + +set(human-dynamics-estimation_CONDA_DEPENDENCIES eigen) diff --git a/cmake/BuildiDynTree.cmake b/cmake/BuildiDynTree.cmake index dcbc3521a..3ef998445 100644 --- a/cmake/BuildiDynTree.cmake +++ b/cmake/BuildiDynTree.cmake @@ -29,3 +29,5 @@ ycm_ep_helper(iDynTree TYPE GIT -DIDYNTREE_USES_PYTHON:BOOL=${ROBOTOLOGY_USES_PYTHON} -DIDYNTREE_USES_OCTAVE:BOOL=${ROBOTOLOGY_USES_OCTAVE} DEPENDS ${iDynTree_DEPENDS}) + +set(iDynTree_CONDA_DEPENDENCIES libxml2 ipopt eigen qt irrlicht) diff --git a/cmake/Buildicub-basic-demos.cmake b/cmake/Buildicub-basic-demos.cmake index 6f48540bd..7082535fc 100644 --- a/cmake/Buildicub-basic-demos.cmake +++ b/cmake/Buildicub-basic-demos.cmake @@ -16,3 +16,5 @@ ycm_ep_helper(icub-basic-demos TYPE GIT DEPENDS YARP ICUB ICUBcontrib) + +set(icub-basic-demos_CONDA_DEPENDENCIES opencv qt) diff --git a/cmake/Buildicub_firmware_shared.cmake b/cmake/Buildicub_firmware_shared.cmake index 791e4c7a9..908c3b4fb 100644 --- a/cmake/Buildicub_firmware_shared.cmake +++ b/cmake/Buildicub_firmware_shared.cmake @@ -5,8 +5,11 @@ include(YCMEPHelper) include(FindOrBuildPackage) +find_or_build_package(YCM QUIET) + ycm_ep_helper(icub_firmware_shared TYPE GIT STYLE GITHUB REPOSITORY robotology/icub-firmware-shared.git COMPONENT iCub - FOLDER src) + FOLDER src + DEPENDS YCM) diff --git a/cmake/Buildmanif.cmake b/cmake/Buildmanif.cmake index cbda4c12c..1c85a2073 100644 --- a/cmake/Buildmanif.cmake +++ b/cmake/Buildmanif.cmake @@ -11,3 +11,6 @@ ycm_ep_helper(manif TYPE GIT COMPONENT external FOLDER src CMAKE_ARGS -DBUILD_TESTING:BOOL=OFF -DBUILD_EXAMPLES:BOOL=OFF) + +set(manif_CONDA_PKG_NAME manif) +set(manif_CONDA_PKG_CONDA_FORGE_OVERRIDE ON) diff --git a/cmake/Buildmatio-cpp.cmake b/cmake/Buildmatio-cpp.cmake index 33e621ef5..d9351d546 100644 --- a/cmake/Buildmatio-cpp.cmake +++ b/cmake/Buildmatio-cpp.cmake @@ -10,3 +10,5 @@ ycm_ep_helper(matio-cpp TYPE GIT COMPONENT dynamics FOLDER src CMAKE_ARGS -DBUILD_TESTING:BOOL=OFF) + +set(matio-cpp_CONDA_DEPENDENCIES "libmatio") diff --git a/cmake/Buildosqp.cmake b/cmake/Buildosqp.cmake index be69044e7..f39e7cdc5 100644 --- a/cmake/Buildosqp.cmake +++ b/cmake/Buildosqp.cmake @@ -11,3 +11,6 @@ ycm_ep_helper(osqp TYPE GIT COMPONENT external FOLDER src CMAKE_ARGS -DUNITTESTS:BOOL=OFF) + +set(osqp_CONDA_PKG_NAME libosqp) +set(osqp_CONDA_PKG_CONDA_FORGE_OVERRIDE ON) diff --git a/cmake/Buildqhull.cmake b/cmake/Buildqhull.cmake index 47a47c902..8831f69f5 100644 --- a/cmake/Buildqhull.cmake +++ b/cmake/Buildqhull.cmake @@ -11,3 +11,6 @@ ycm_ep_helper(qhull TYPE GIT COMPONENT external FOLDER src CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON) + +set(qhull_CONDA_PKG_NAME qhull) +set(qhull_CONDA_PKG_CONDA_FORGE_OVERRIDE ON) diff --git a/cmake/BuildqpOASES.cmake b/cmake/BuildqpOASES.cmake index f4640f57b..78b8a648d 100644 --- a/cmake/BuildqpOASES.cmake +++ b/cmake/BuildqpOASES.cmake @@ -28,3 +28,5 @@ ycm_ep_helper(qpOASES TYPE GIT COMPONENT external FOLDER src CMAKE_ARGS -DQPOASES_BUILD_BINDINGS_MATLAB:BOOL=OFF) + +set(qpOASES_CONDA_PKG_NAME "qpoases") diff --git a/cmake/Buildwalking-controllers.cmake b/cmake/Buildwalking-controllers.cmake index e6321aacd..a86e7d288 100644 --- a/cmake/Buildwalking-controllers.cmake +++ b/cmake/Buildwalking-controllers.cmake @@ -24,8 +24,10 @@ list(APPEND walking-controllers_DEPENDS ICUBcontrib) ycm_ep_helper(walking-controllers TYPE GIT STYLE GITHUB - REPOSITORY robotology/walking-controllers + REPOSITORY robotology/walking-controllers.git TAG master COMPONENT dynamics FOLDER src DEPENDS ${walking-controllers_DEPENDS}) + +set(walking-controllers_CONDA_DEPENDENCIES "eigen") diff --git a/cmake/Buildwalking-teleoperation.cmake b/cmake/Buildwalking-teleoperation.cmake index 503c13efc..c7e6b772c 100644 --- a/cmake/Buildwalking-teleoperation.cmake +++ b/cmake/Buildwalking-teleoperation.cmake @@ -17,3 +17,6 @@ ycm_ep_helper(walking-teleoperation TYPE GIT DEPENDS iDynTree ICUB YARP) + +set(walking-teleoperation_CONDA_DEPENDENCIES "eigen") +set(walking-teleoperation_CONDA_VERSION "0.0.1") diff --git a/cmake/Buildwhole-body-estimators.cmake b/cmake/Buildwhole-body-estimators.cmake index d082f7128..dfa117b86 100644 --- a/cmake/Buildwhole-body-estimators.cmake +++ b/cmake/Buildwhole-body-estimators.cmake @@ -22,3 +22,5 @@ ycm_ep_helper(whole-body-estimators TYPE GIT COMPONENT dynamics FOLDER src DEPENDS ${whole-body-estimators_DEPENDS}) + +set(whole-body-estimators_CONDA_DEPENDENCIES "eigen") diff --git a/cmake/RobotologySuperbuildOptions.cmake b/cmake/RobotologySuperbuildOptions.cmake index 4d4f20c24..d994c39dd 100644 --- a/cmake/RobotologySuperbuildOptions.cmake +++ b/cmake/RobotologySuperbuildOptions.cmake @@ -67,16 +67,19 @@ if(NOT CMAKE_CONFIGURATION_TYPES) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${ROBOTOLOGY_BUILD_TYPES}) endif() -set(ROBOTOLOGY_PROJECT_TAGS "Stable" CACHE STRING "The tags to be used for the robotology projects: Stable, Unstable or Custom. This can be changed only before the first configuration.") +set(ROBOTOLOGY_PROJECT_TAGS "Stable" CACHE STRING "The tags to be used for the robotology projects: Stable, Unstable, LatestRelease or Custom. This can be changed only before the first configuration.") mark_as_advanced(ROBOTOLOGY_PROJECT_TAGS) set(ROBOTOLOGY_PROJECT_TAGS_CUSTOM_FILE CACHE FILEPATH "If ROBOTOLOGY_PROJECT_TAGS is custom, this file will be loaded to specify the tags of the projects to use.") mark_as_advanced(ROBOTOLOGY_PROJECT_TAGS_CUSTOM_FILE) -set_property(CACHE ROBOTOLOGY_PROJECT_TAGS PROPERTY STRINGS "Stable" "Unstable" "Custom") +set_property(CACHE ROBOTOLOGY_PROJECT_TAGS PROPERTY STRINGS "Stable" "Unstable" "LatestRelease" "Custom") if(ROBOTOLOGY_PROJECT_TAGS STREQUAL "Stable") include(ProjectsTagsStable) elseif(ROBOTOLOGY_PROJECT_TAGS STREQUAL "Unstable") include(ProjectsTagsUnstable) +elseif(ROBOTOLOGY_PROJECT_TAGS STREQUAL "LatestRelease") + include(YCMLoadVcsYamlInfo) + ycm_load_vcs_yaml_info(YAML_FILE ${PROJECT_SOURCE_DIR}/releases/latest.releases.yaml VERBOSE) elseif(ROBOTOLOGY_PROJECT_TAGS STREQUAL "Custom") if(ROBOTOLOGY_PROJECT_TAGS_CUSTOM_FILE MATCHES ".yaml$" OR ROBOTOLOGY_PROJECT_TAGS_CUSTOM_FILE MATCHES ".repos$") @@ -88,3 +91,6 @@ elseif(ROBOTOLOGY_PROJECT_TAGS STREQUAL "Custom") else() message(FATAL_ERROR "The ROBOTOLOGY_PROJECT_TAGS variable can be Stable, Unstable or Custom. ${ROBOTOLOGY_PROJECT_TAGS} value is not supported.") endif() + +option(ROBOTOLOGY_GENERATE_CONDA_RECIPES "If enabled, generate conda recipes instead of building the superbuild. This should not be used by end users." OFF) +mark_as_advanced(ROBOTOLOGY_GENERATE_CONDA_RECIPES) diff --git a/conda/cmake/CondaGenerationOptions.cmake b/conda/cmake/CondaGenerationOptions.cmake new file mode 100644 index 000000000..9ab496a41 --- /dev/null +++ b/conda/cmake/CondaGenerationOptions.cmake @@ -0,0 +1,7 @@ +# This number needs to be increased at each full rebuild, +# to ensure that binaries belonging to different rebuilds +# can be distinguished even if the version number is the same +set(CONDA_BUILD_NUMBER 0) + +# For more conda generation options, check the specific project Build.cmake +# file for variables that start with `_CONDA` diff --git a/conda/cmake/FindOrBuildPackage.cmake b/conda/cmake/FindOrBuildPackage.cmake new file mode 100644 index 000000000..e69de29bb diff --git a/conda/cmake/RobotologySuperbuildGenerateCondaRecipes.cmake b/conda/cmake/RobotologySuperbuildGenerateCondaRecipes.cmake new file mode 100644 index 000000000..73f877f54 --- /dev/null +++ b/conda/cmake/RobotologySuperbuildGenerateCondaRecipes.cmake @@ -0,0 +1,195 @@ +# Copyright (C) Fondazione Istituto Italiano di Tecnologia +# CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT + +# Redefine find_or_build_package and ycm_ep_helper +# functions to extract metadata necessary for conda recipe +# generation from the RobotologySuperbuildLogic file +macro(ycm_ep_helper _name) + # Check arguments + set(_options ) + set(_oneValueArgs TYPE + STYLE + COMPONENT + FOLDER + EXCLUDE_FROM_ALL + REPOSITORY # GIT, SVN and HG + TAG # GIT and HG only + REVISION # SVN only + USERNAME # SVN only + PASSWORD # SVN only + TRUST_CERT # SVN only + TEST_BEFORE_INSTALL + TEST_AFTER_INSTALL + TEST_EXCLUDE_FROM_MAIN + CONFIGURE_SOURCE_DIR # DEPRECATED Since YCM 0.10 + SOURCE_SUBDIR) + set(_multiValueArgs CMAKE_ARGS + CMAKE_CACHE_ARGS + CMAKE_CACHE_DEFAULT_ARGS + DEPENDS + DOWNLOAD_COMMAND + UPDATE_COMMAND + PATCH_COMMAND + CONFIGURE_COMMAND + BUILD_COMMAND + INSTALL_COMMAND + TEST_COMMAND + CLEAN_COMMAND) + + cmake_parse_arguments(_YH_${_name} "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" "${ARGN}") + + get_property(_projects GLOBAL PROPERTY YCM_PROJECTS) + list(APPEND _projects ${_name}) + list(REMOVE_DUPLICATES _projects) + set_property(GLOBAL PROPERTY YCM_PROJECTS ${_projects}) +endmacro() + +macro(find_or_build_package _pkg) + get_property(_superbuild_pkgs GLOBAL PROPERTY YCM_PROJECTS) + if(NOT ${_pkg} IN_LIST _superbuild_pkgs) + include(Build${_pkg}) + endif() +endmacro() + +set(metametadata_file ${CMAKE_CURRENT_BINARY_DIR}/conda/robotology-superbuild-conda-metametadata.yaml) + +macro(generate_metametadata_file) + # Metametadata file name + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/conda) + set(metametadata_file_contents "conda-packages-metametadata:\n") + + get_property(_superbuild_pkgs GLOBAL PROPERTY YCM_PROJECTS) + foreach(_cmake_pkg IN LISTS _superbuild_pkgs) + # If a package is already available in conda-forge, we use + # that one by defining appropriately the <_cmake_pkg>_CONDA_PACKAGE_NAME + # and <_cmake_pkg>_CONDA_PKG_CONDA_FORGE_OVERRIDE variables + if(DEFINED ${_cmake_pkg}_CONDA_PKG_CONDA_FORGE_OVERRIDE AND + "${${_cmake_pkg}_CONDA_PKG_CONDA_FORGE_OVERRIDE}") + continue() + endif() + + # Compute conda version + if(DEFINED ${_cmake_pkg}_TAG) + set(${_cmake_pkg}_CONDA_TAG ${${_cmake_pkg}_TAG}) + else() + set(${_cmake_pkg}_CONDA_TAG ${_YH_${_cmake_pkg}_TAG}) + endif() + + if(NOT DEFINED ${_cmake_pkg}_CONDA_VERSION) + set(${_cmake_pkg}_CONDA_VERSION ${${_cmake_pkg}_CONDA_TAG}) + endif() + + # Compute conda CMake options + set(${_cmake_pkg}_CONDA_CMAKE_ARGS ${_YH_${_cmake_pkg}_CMAKE_ARGS}) + list(APPEND ${_cmake_pkg}_CONDA_CMAKE_ARGS ${_YH_${_cmake_pkg}_CMAKE_CACHE_ARGS}) + list(APPEND ${_cmake_pkg}_CONDA_CMAKE_ARGS ${_YH_${_cmake_pkg}_CMAKE_CACHE_DEFAULT_ARGS}) + # Convert YCM_EP_ADDITIONAL_CMAKE_ARGS to list + string(REPLACE " " ";" YCM_EP_ADDITIONAL_CMAKE_ARGS_AS_LIST "${YCM_EP_ADDITIONAL_CMAKE_ARGS}") + list(APPEND ${_cmake_pkg}_CONDA_CMAKE_ARGS ${YCM_EP_ADDITIONAL_CMAKE_ARGS_AS_LIST}) + + # Escape backlash for insertion in yaml + string(REPLACE "\\" "\\\\" ${_cmake_pkg}_CONDA_CMAKE_ARGS "${${_cmake_pkg}_CONDA_CMAKE_ARGS}") + + + # Compute conda dependencies + # Always append so dependencies not tracked by the superbuild can be injected by + # defining a ${_cmake_pkg}_CONDA_DEPENDENCIES in CondaGenerationOptions.cmake + foreach(_cmake_dep IN LISTS _YH_${_cmake_pkg}_DEPENDS) + list(APPEND ${_cmake_pkg}_CONDA_DEPENDENCIES ${${_cmake_dep}_CONDA_PKG_NAME}) + endforeach() + + # Compute conda github repository + # We remove the trailing .git (if present) + string(REPLACE ".git" "" ${_cmake_pkg}_CONDA_GIHUB_REPO "${_YH_${_cmake_pkg}_REPOSITORY}") + + # Dump metametadata in yaml format + string(APPEND metametadata_file_contents " ${${_cmake_pkg}_CONDA_PKG_NAME}:\n") + string(APPEND metametadata_file_contents " name: ${${_cmake_pkg}_CONDA_PKG_NAME}\n") + string(APPEND metametadata_file_contents " version: ${${_cmake_pkg}_CONDA_VERSION}\n") + string(APPEND metametadata_file_contents " github_repo: ${${_cmake_pkg}_CONDA_GIHUB_REPO}\n") + string(APPEND metametadata_file_contents " github_tag: ${${_cmake_pkg}_CONDA_TAG}\n") + string(APPEND metametadata_file_contents " conda_build_number: ${CONDA_BUILD_NUMBER}\n") + + if(NOT "${${_cmake_pkg}_CONDA_CMAKE_ARGS}" STREQUAL "") + string(APPEND metametadata_file_contents " cmake_args:\n") + foreach(_cmake_arg IN LISTS ${_cmake_pkg}_CONDA_CMAKE_ARGS) + string(APPEND metametadata_file_contents " - \"${_cmake_arg}\"\n") + endforeach() + endif() + + if(NOT "${${_cmake_pkg}_CONDA_DEPENDENCIES}" STREQUAL "") + string(APPEND metametadata_file_contents " dependencies:\n") + foreach(_dep IN LISTS ${_cmake_pkg}_CONDA_DEPENDENCIES) + string(APPEND metametadata_file_contents " - ${_dep}\n") + endforeach() + endif() + + # If some dependency require opengl to build and we are on Linux, add the required packages + # See https://conda-forge.org/docs/maintainer/knowledge_base.html?#libgl + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + if("qt" IN_LIST ${_cmake_pkg}_CONDA_DEPENDENCIES OR + "freeglut" IN_LIST ${_cmake_pkg}_CONDA_DEPENDENCIES OR + "irrlicht" IN_LIST ${_cmake_pkg}_CONDA_DEPENDENCIES) + string(APPEND metametadata_file_contents " require_opengl_linux: true\n") + endif() + endif() + + string(APPEND metametadata_file_contents "\n") + endforeach() + + file(WRITE ${metametadata_file} ${metametadata_file_contents}) + message(STATUS "Saved metametadata in ${metametadata_file}") +endmacro() + +macro(generate_conda_recipes) + set(python_generation_script "${CMAKE_CURRENT_SOURCE_DIR}/conda/python/generate_conda_recipes_from_metadatadata.py") + set(generated_conda_recipes_dir "${CMAKE_CURRENT_BINARY_DIR}/conda/generated_recipes") + file(MAKE_DIRECTORY ${generated_conda_recipes_dir}) + execute_process(COMMAND python ${python_generation_script} -i ${metametadata_file} -o ${generated_conda_recipes_dir} RESULT_VARIABLE CONDA_GENERATION_SCRIPT_RETURN_VALUE) + message(STATUS "CONDA_GENERATION_SCRIPT_RETURN_VALUE: ${CONDA_GENERATION_SCRIPT_RETURN_VALUE}") + if(CONDA_GENERATION_SCRIPT_RETURN_VALUE STREQUAL "0") + message(STATUS "conda recipes correctly generated in ${generated_conda_recipes_dir}.") + message(STATUS "To build the generated conda recipes, navigate to the directory and run conda build . in it.") + else() + message(FATAL_ERROR "Error in execution of script ${python_generation_script}") + endif() +endmacro() + + +# Explicitly add YCM as it is not handled as other projects +get_property(_projects GLOBAL PROPERTY YCM_PROJECTS) +list(APPEND _projects YCM) +set_property(GLOBAL PROPERTY YCM_PROJECTS ${_projects}) +set(_YH_YCM_REPOSITORY robotology/ycm.git) +# Use ycm-cmake-modules as name as in debian +set(YCM_CONDA_PKG_NAME ycm-cmake-modules) + +include(RobotologySuperbuildLogic) +include(CondaGenerationOptions) + +get_property(_superbuild_pkgs GLOBAL PROPERTY YCM_PROJECTS) + +# First of all: define the conda package name of each cmake project +# This needs to be done first for all packages as it is used later +# when referring to dependencies +foreach(_cmake_pkg IN LISTS _superbuild_pkgs) + # Unless the <_cmake_pkg>_CONDA_PKG_NAME variable is explicitly defined, + # we use the git repo name as the conda pkg name as the convention are similar + # (lowercase names, separated by dash) + if(NOT DEFINED ${_cmake_pkg}_CONDA_PKG_NAME) + string(REGEX MATCH "^[^\/:]+\/([^\/:]+).git$" UNUSED_REGEX_MATCH_OUTPUT "${_YH_${_cmake_pkg}_REPOSITORY}") + set(${_cmake_pkg}_CONDA_PKG_NAME ${CMAKE_MATCH_1}) + if("${${_cmake_pkg}_CONDA_PKG_NAME}" STREQUAL "") + message(FATAL_ERROR "Error in extracting conda package name for CMake package ${_cmake_pkg} with repo ${_YH_${_cmake_pkg}_REPOSITORY}") + endif() + endif() +endforeach() + +# Second step: generate the ${CMAKE_CURRENT_BINARY_DIR}/conda/robotology-superbuild-conda-metametadata.yaml, +# that contains in yaml form the dependencies and options information contained +# in the CMake scripts of the robotology-superbuild +generate_metametadata_file() + +# Third step: generate the conda recipes from the metametadata in +# ${CMAKE_CURRENT_BINARY_DIR}/conda/generate_recipes +generate_conda_recipes() diff --git a/conda/cmake/YCMEPHelper.cmake b/conda/cmake/YCMEPHelper.cmake new file mode 100644 index 000000000..e69de29bb diff --git a/conda/conda_build_config.yml b/conda/conda_build_config.yml new file mode 100644 index 000000000..d4e14d048 --- /dev/null +++ b/conda/conda_build_config.yml @@ -0,0 +1,3 @@ +# bipedal-locomotion-framework requires 10.13 for std::bad_cast_any +MACOSX_DEPLOYMENT_TARGET: # [osx and x86_64] + - 10.13 # [osx and x86_64] diff --git a/conda/multisheller/blockfactory_activate.msh b/conda/multisheller/blockfactory_activate.msh new file mode 100644 index 000000000..1bb669806 --- /dev/null +++ b/conda/multisheller/blockfactory_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("BLOCKFACTORY_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin\\blockfactory")) +]).else_([ + sys.list_append("BLOCKFACTORY_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/blockfactory")) +]) diff --git a/conda/multisheller/blockfactory_deactivate.msh b/conda/multisheller/blockfactory_deactivate.msh new file mode 100644 index 000000000..2cef2f33c --- /dev/null +++ b/conda/multisheller/blockfactory_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("BLOCKFACTORY_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin\\blockfactory")) +]).else_([ + sys.list_remove("BLOCKFACTORY_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/blockfactory")) +]) diff --git a/conda/multisheller/blocktest_activate.msh b/conda/multisheller/blocktest_activate.msh new file mode 100644 index 000000000..0af698d50 --- /dev/null +++ b/conda/multisheller/blocktest_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("BLOCKTEST_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin")) +]).else_([ + sys.list_append("BLOCKTEST_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "bin")) +]) diff --git a/conda/multisheller/blocktest_deactivate.msh b/conda/multisheller/blocktest_deactivate.msh new file mode 100644 index 000000000..9a8bca691 --- /dev/null +++ b/conda/multisheller/blocktest_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("BLOCKTEST_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin")) +]).else_([ + sys.list_remove("BLOCKTEST_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "bin")) +]) diff --git a/conda/multisheller/gazebo-yarp-plugins_activate.msh b/conda/multisheller/gazebo-yarp-plugins_activate.msh new file mode 100644 index 000000000..bbcb034a4 --- /dev/null +++ b/conda/multisheller/gazebo-yarp-plugins_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("GAZEBO_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin")) +]).else_([ + sys.list_append("GAZEBO_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib")) +]) diff --git a/conda/multisheller/gazebo-yarp-plugins_deactivate.msh b/conda/multisheller/gazebo-yarp-plugins_deactivate.msh new file mode 100644 index 000000000..83c2501f2 --- /dev/null +++ b/conda/multisheller/gazebo-yarp-plugins_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("GAZEBO_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\bin")) +]).else_([ + sys.list_remove("GAZEBO_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib")) +]) diff --git a/conda/multisheller/human-dynamics-estimation_activate.msh b/conda/multisheller/human-dynamics-estimation_activate.msh new file mode 100644 index 000000000..2d97853d6 --- /dev/null +++ b/conda/multisheller/human-dynamics-estimation_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\HumanDynamicsEstihumation")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/HumanDynamicsEstimation")) +]) diff --git a/conda/multisheller/human-dynamics-estimation_deactivate.msh b/conda/multisheller/human-dynamics-estimation_deactivate.msh new file mode 100644 index 000000000..800737dd8 --- /dev/null +++ b/conda/multisheller/human-dynamics-estimation_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\HumanDynamicsEstimation")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/HumanDynamicsEstimation")) +]) diff --git a/conda/multisheller/human-gazebo_activate.msh b/conda/multisheller/human-gazebo_activate.msh new file mode 100644 index 000000000..413c0674a --- /dev/null +++ b/conda/multisheller/human-gazebo_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\human-gazebo")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/human-gazebo")) +]) diff --git a/conda/multisheller/human-gazebo_deactivate.msh b/conda/multisheller/human-gazebo_deactivate.msh new file mode 100644 index 000000000..8c4b48e78 --- /dev/null +++ b/conda/multisheller/human-gazebo_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\human-gazebo")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/human-gazebo")) +]) diff --git a/conda/multisheller/icub-contrib-common_activate.msh b/conda/multisheller/icub-contrib-common_activate.msh new file mode 100644 index 000000000..5807cb26d --- /dev/null +++ b/conda/multisheller/icub-contrib-common_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\ICUBcontrib")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/ICUBcontrib")) +]) diff --git a/conda/multisheller/icub-contrib-common_deactivate.msh b/conda/multisheller/icub-contrib-common_deactivate.msh new file mode 100644 index 000000000..29655d4a4 --- /dev/null +++ b/conda/multisheller/icub-contrib-common_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\ICUBcontrib")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/ICUBcontrib")) +]) diff --git a/conda/multisheller/icub-main_activate.msh b/conda/multisheller/icub-main_activate.msh new file mode 100644 index 000000000..5219a7ea3 --- /dev/null +++ b/conda/multisheller/icub-main_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/iCub")) +]) diff --git a/conda/multisheller/icub-main_deactivate.msh b/conda/multisheller/icub-main_deactivate.msh new file mode 100644 index 000000000..8a9f3eac1 --- /dev/null +++ b/conda/multisheller/icub-main_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/iCub")) +]) diff --git a/conda/multisheller/icub-models_activate.msh b/conda/multisheller/icub-models_activate.msh new file mode 100644 index 000000000..d09a52302 --- /dev/null +++ b/conda/multisheller/icub-models_activate.msh @@ -0,0 +1,27 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub")), + sys.list_append("ROS_PACKAGE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")), + sys.list_append("AMENT_PREFIX_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")), + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\gazebo\\models")), + sys.list_append("GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\gazebo\\worls")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/iCub")), + sys.list_append("ROS_PACKAGE_PATH", path.join(env("CONDA_PREFIX"), "share")), + sys.list_append("AMENT_PREFIX_PATH", path.join(env("CONDA_PREFIX"), "share")), + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share/gazebo/models")), + sys.list_append("GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "share/gazebo/worls")) +]) + +# For some reason setting two times the same variable inside the same if does not work in command prompt +# As a workaround, we move each GAZEBO_MODEL_PATH set to a separate if +if_(is_set("COMSPEC")).then_([ + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub\\robots")) +]).else_([ + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share/iCub/robots")) +]) + +if_(is_set("COMSPEC")).then_([ + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")) +]).else_([ + sys.list_append("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share")) +]) \ No newline at end of file diff --git a/conda/multisheller/icub-models_deactivate.msh b/conda/multisheller/icub-models_deactivate.msh new file mode 100644 index 000000000..58a7da015 --- /dev/null +++ b/conda/multisheller/icub-models_deactivate.msh @@ -0,0 +1,29 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub")), + sys.list_remove("ROS_PACKAGE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")), + sys.list_remove("AMENT_PREFIX_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")), + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\gazebo\\models")), + sys.list_remove("GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\gazebo\\worls")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/iCub")), + sys.list_remove("ROS_PACKAGE_PATH", path.join(env("CONDA_PREFIX"), "share")), + sys.list_remove("AMENT_PREFIX_PATH", path.join(env("CONDA_PREFIX"), "share")), + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share/gazebo/models")), + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share/iCub/robots")), + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share")), + sys.list_remove("GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "share/gazebo/worls")) +]) + +# For some reason setting two times the same variable inside the same if does not work in command prompt +# As a workaround, we move each GAZEBO_MODEL_PATH set to a separate if +if_(is_set("COMSPEC")).then_([ + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\iCub\\robots")) +]).else_([ + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share/iCub/robots")) +]) + +if_(is_set("COMSPEC")).then_([ + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "Library\\share")) +]).else_([ + sys.list_remove("GAZEBO_MODEL_PATH", path.join(env("CONDA_PREFIX"), "share")) +]) \ No newline at end of file diff --git a/conda/multisheller/idyntree_activate.msh b/conda/multisheller/idyntree_activate.msh new file mode 100644 index 000000000..32825b3ac --- /dev/null +++ b/conda/multisheller/idyntree_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/idyntree_deactivate.msh b/conda/multisheller/idyntree_deactivate.msh new file mode 100644 index 000000000..96b2936f2 --- /dev/null +++ b/conda/multisheller/idyntree_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/osqp-matlab_activate.msh b/conda/multisheller/osqp-matlab_activate.msh new file mode 100644 index 000000000..32825b3ac --- /dev/null +++ b/conda/multisheller/osqp-matlab_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/osqp-matlab_deactivate.msh b/conda/multisheller/osqp-matlab_deactivate.msh new file mode 100644 index 000000000..96b2936f2 --- /dev/null +++ b/conda/multisheller/osqp-matlab_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/wb-toolbox_activate.msh b/conda/multisheller/wb-toolbox_activate.msh new file mode 100644 index 000000000..97d6e1780 --- /dev/null +++ b/conda/multisheller/wb-toolbox_activate.msh @@ -0,0 +1,7 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\share\\WBToolbox")), + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\share\\WBToolbox\\images")) +]).else_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "share/WBToolbox")), + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "share/WBToolbox/images")) +]) diff --git a/conda/multisheller/wb-toolbox_deactivate.msh b/conda/multisheller/wb-toolbox_deactivate.msh new file mode 100644 index 000000000..eaceb2905 --- /dev/null +++ b/conda/multisheller/wb-toolbox_deactivate.msh @@ -0,0 +1,7 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\share\\WBToolbox")), + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\share\\WBToolbox\\images")) +]).else_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "share/WBToolbox")), + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "share/WBToolbox/images")) +]) diff --git a/conda/multisheller/wearables_activate.msh b/conda/multisheller/wearables_activate.msh new file mode 100644 index 000000000..6572a37c9 --- /dev/null +++ b/conda/multisheller/wearables_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\Wearables")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/Wearables")) +]) diff --git a/conda/multisheller/wearables_deactivate.msh b/conda/multisheller/wearables_deactivate.msh new file mode 100644 index 000000000..96cc7c271 --- /dev/null +++ b/conda/multisheller/wearables_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\Wearables")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/Wearables")) +]) diff --git a/conda/multisheller/whole-body-controllers_activate.msh b/conda/multisheller/whole-body-controllers_activate.msh new file mode 100644 index 000000000..2e2e29a51 --- /dev/null +++ b/conda/multisheller/whole-body-controllers_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex\\+wbc\\simulink")) +]).else_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex/+wbc/simulink")) +]) diff --git a/conda/multisheller/whole-body-controllers_deactivate.msh b/conda/multisheller/whole-body-controllers_deactivate.msh new file mode 100644 index 000000000..7777919b1 --- /dev/null +++ b/conda/multisheller/whole-body-controllers_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex\\+wbc\\simulink")) +]).else_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex/+wbc/simulink")) +]) diff --git a/conda/multisheller/yarp-matlab-bindings_activate.msh b/conda/multisheller/yarp-matlab-bindings_activate.msh new file mode 100644 index 000000000..32825b3ac --- /dev/null +++ b/conda/multisheller/yarp-matlab-bindings_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_append("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/yarp-matlab-bindings_deactivate.msh b/conda/multisheller/yarp-matlab-bindings_deactivate.msh new file mode 100644 index 000000000..96b2936f2 --- /dev/null +++ b/conda/multisheller/yarp-matlab-bindings_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "Library\\mex")) +]).else_([ + sys.list_remove("MATLABPATH", path.join(env("CONDA_PREFIX"), "mex")) +]) diff --git a/conda/multisheller/yarp_activate.msh b/conda/multisheller/yarp_activate.msh new file mode 100644 index 000000000..057e3b74e --- /dev/null +++ b/conda/multisheller/yarp_activate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\yarp")) +]).else_([ + sys.list_append("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/yarp")) +]) diff --git a/conda/multisheller/yarp_deactivate.msh b/conda/multisheller/yarp_deactivate.msh new file mode 100644 index 000000000..6564064b8 --- /dev/null +++ b/conda/multisheller/yarp_deactivate.msh @@ -0,0 +1,5 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "Library\\share\\yarp")) +]).else_([ + sys.list_remove("YARP_DATA_DIRS", path.join(env("CONDA_PREFIX"), "share/yarp")) +]) diff --git a/conda/python/generate_conda_recipes_from_metametadata.py b/conda/python/generate_conda_recipes_from_metametadata.py new file mode 100644 index 000000000..b173a830e --- /dev/null +++ b/conda/python/generate_conda_recipes_from_metametadata.py @@ -0,0 +1,139 @@ +import argparse +import jinja2 +import os +import string +import yaml +import shutil + +# multisheller includes +import multisheller +from multisheller import cmds +from multisheller.backend import bash, zsh, xonsh, cmdexe, powershell +import argparse, sys +import ast +from multisheller.cmds import * +from multisheller import path, sys +from multisheller.backend.utils import write_script +from pprint import pprint + +def dir_path(string): + if os.path.isdir(string): + return string + else: + raise NotADirectoryError(string) + + +suffixes = { + 'cmdexe': '.bat', + 'bash': '.sh', + 'zsh': '.zsh', + 'xonsh': '.xsh', + 'powershell': '.ps1', +} + +translators = { + 'cmdexe': cmdexe, + 'bash': bash, + 'zsh': zsh, + 'xonsh': xonsh, + 'powershell': powershell, +} + +def write_script(generation_directory, name_without_extension, commands, interpreter): + fname = generation_directory + "/" + name_without_extension + suffixes[interpreter] + s = cmds.Script(commands) + + print(f"Writing file to {fname}") + with open(fname, 'w') as f: + s = translators[interpreter].to_script(s) + f.write(s) + + f.close() + print(f"File wrote to {fname}") + + return + +# Inspired from: +# * https://github.com/wolfv/multisheller/blob/0cc03c68d0c68d2f9cf7b07ddb68afa531419a6d/multisheller/cli/main.py +# * https://github.com/wolfv/multisheller/blob/0cc03c68d0c68d2f9cf7b07ddb68afa531419a6d/multisheller/backend/utils.py#L21 +def generate_scripts_from_multisheller_file(multisheller_file, generation_directory, name_without_extension): + # Parse msh file + with open(multisheller_file) as fi: + contents = fi.read() + contents = contents + tree = ast.parse(contents) + + ls = locals().copy() + cmds = [] + for expr in tree.body: + codeobj = compile(ast.Expression(expr.value), '', mode='eval') + res = eval(codeobj, globals(), ls) + if type(expr) == ast.Assign: + for t in expr.targets: + ls.update({t.id: res}) + else: + cmds.append(res) + + # Generate scripts + write_script(generation_directory, name_without_extension, cmds, "cmdexe") + write_script(generation_directory, name_without_extension, cmds, "bash") + write_script(generation_directory, name_without_extension, cmds, "zsh") + write_script(generation_directory, name_without_extension, cmds, "xonsh") + write_script(generation_directory, name_without_extension, cmds, "powershell") + +def main(): + + # Parse parameters + parser = argparse.ArgumentParser() + parser.add_argument("-i", "--metametadata", type=str, help="metametadata .yaml file") + parser.add_argument("-o", "--recipes_dir", type=dir_path, help="directory of generated recipes directory") + args = parser.parse_args() + + # Get recipe templates + recipe_template_dir = os.path.realpath(os.path.dirname(os.path.abspath(__file__)) + "/../recipe_template"); + recipe_template_files = [f for f in os.listdir(recipe_template_dir) if os.path.isfile(os.path.join(recipe_template_dir, f))] + + # Get multisheller scripts + multisheller_scripts_dir = os.path.realpath(os.path.dirname(os.path.abspath(__file__)) + "/../multisheller"); + multisheller_scripts = [f for f in os.listdir(multisheller_scripts_dir) if os.path.isfile(os.path.join(multisheller_scripts_dir, f))] + + # Prepare Jinja templates + file_loader = jinja2.FileSystemLoader(recipe_template_dir) + env = jinja2.Environment(loader=file_loader) + # Load metametadata + metametadata = yaml.load(open(args.metametadata), Loader=yaml.FullLoader) + + for pkg in metametadata['conda-packages-metametadata']: + print(f"generate_conda_recipes_from_metadatadata: generating recipe for package {pkg}") + + # Check if multisheller file are available for this package, + # if available generate activate scripts + + # Get pkginfo + pkg_info = metametadata['conda-packages-metametadata'][pkg] + recipe_dir = os.path.join(os.path.realpath(args.recipes_dir), pkg_info['name']) + shutil.rmtree(recipe_dir, ignore_errors=True) + os.mkdir(recipe_dir) + print(recipe_dir) + + # Generate activation scripts + activation_script_msh = pkg_info['name'] + "_activate.msh" + deactivation_script_msh = pkg_info['name'] + "_deactivate.msh" + if activation_script_msh in multisheller_scripts and deactivation_script_msh in multisheller_scripts: + print(f"Generating scripts for {pkg_info['name']}") + generate_scripts_from_multisheller_file(multisheller_scripts_dir + "/" + activation_script_msh, recipe_dir, "activate") + generate_scripts_from_multisheller_file(multisheller_scripts_dir + "/" + deactivation_script_msh, recipe_dir, "deactivate") + # To copy the activation scripts in the recipe + pkg_info['copy_activation_scripts'] = True + else: + pkg_info['copy_activation_scripts'] = False + + # Generate recipe + for template_file in recipe_template_files: + template = env.get_template(template_file) + template_output = template.render(pkg_info) + with open(os.path.join(recipe_dir, template_file), 'w') as f: + f.write(template_output) + +if __name__ == '__main__': + main() diff --git a/conda/recipe_template/bld.bat b/conda/recipe_template/bld.bat new file mode 100644 index 000000000..775bedbe0 --- /dev/null +++ b/conda/recipe_template/bld.bat @@ -0,0 +1,46 @@ +mkdir build +cd build + +:: Hardcoding Visual Studio 2019 as GitHub Actions does not have VS2019 +:: -DBUILD_SHARED_LIBS=ON for now disabled as a workaround for https://github.com/robotology/icub-main/issues/717 +cmake ^ + -G"Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% ^ + -DCMAKE_PREFIX_PATH=%LIBRARY_PREFIX% ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_VERBOSE_MAKEFILE=OFF ^ + -DCMAKE_INSTALL_LIBDIR=lib ^ +{% for cmake_arg in cmake_args %} {{ cmake_arg }} ^ +{% endfor %} %SRC_DIR% +if errorlevel 1 exit 1 + +:: Build. +cmake --build . --config Release +if errorlevel 1 exit 1 + +:: Install. +cmake --build . --config Release --target install +if errorlevel 1 exit 1 + +{% if copy_activation_scripts is sameas true %} +setlocal EnableDelayedExpansion +:: Copy the [de]activate scripts to %PREFIX%\etc\conda\[de]activate.d. +:: This will allow them to be run on environment activation. +for %%F in (activate deactivate) DO ( + if not exist %PREFIX%\etc\conda\%%F.d mkdir %PREFIX%\etc\conda\%%F.d + copy %RECIPE_DIR%\%%F.bat %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.bat + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %RECIPE_DIR%\%%F.sh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.sh + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %RECIPE_DIR%\%%F.ps1 %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.ps1 + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %RECIPE_DIR%\%%F.xsh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.xsh + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %RECIPE_DIR%\%%F.zsh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.zsh + if %errorlevel% neq 0 exit /b %errorlevel% +) +{% endif %} diff --git a/conda/recipe_template/build.sh b/conda/recipe_template/build.sh new file mode 100644 index 000000000..1a2f178db --- /dev/null +++ b/conda/recipe_template/build.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +mkdir build +cd build + +cmake .. \ + -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=$PREFIX \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_VERBOSE_MAKEFILE=OFF \ + -DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=True \ +{% for cmake_arg in cmake_args %} {{ cmake_arg }} \ +{% endfor %} + +cmake --build . --config Release +cmake --build . --config Release --target install + +{% if copy_activation_scripts is sameas true %} +# Copy the [de]activate scripts to $PREFIX/etc/conda/[de]activate.d. +# This will allow them to be run on environment activation. +for CHANGE in "activate" "deactivate" +do + mkdir -p "${PREFIX}/etc/conda/${CHANGE}.d" + cp "${RECIPE_DIR}/${CHANGE}.sh" "${PREFIX}/etc/conda/${CHANGE}.d/${PKG_NAME}_${CHANGE}.sh" + cp "${RECIPE_DIR}/${CHANGE}.xsh" "${PREFIX}/etc/conda/${CHANGE}.d/${PKG_NAME}_${CHANGE}.xsh" + cp "${RECIPE_DIR}/${CHANGE}.zsh" "${PREFIX}/etc/conda/${CHANGE}.d/${PKG_NAME}_${CHANGE}.zsh" + cp "${RECIPE_DIR}/${CHANGE}.ps1" "${PREFIX}/etc/conda/${CHANGE}.d/${PKG_NAME}_${CHANGE}.ps1" +done +{% endif %} diff --git a/conda/recipe_template/meta.yaml b/conda/recipe_template/meta.yaml new file mode 100644 index 000000000..27be179e0 --- /dev/null +++ b/conda/recipe_template/meta.yaml @@ -0,0 +1,51 @@ +{{ '{% set name =' }} "{{ name }}" {{ '%}' }} + +package: +{% raw %} name: {{ name }} {% endraw %} + version: "{{ version.replace("v","") }}" + +source: + git_url: https://github.com/{{ github_repo }}.git + git_rev: {{ github_tag }} + +build: + number: {{ conda_build_number }} + run_exports: +{% raw %} # As robotology-superbuild packages tipically do not worry about ABI compatibility, + # we explicitly specify that for every patch version the ABI changes + - {{ pin_subpackage(name, max_pin='x.x.x') }} +{% endraw %} + +requirements: + build: +{# A C/C++ compiler and CMake are required by all packages #} +{% raw %} - {{ compiler('c') }} + - {{ compiler('cxx') }} {% endraw %} + - cmake + - pkg-config + - ninja +{# Handle specific packages required for gl on Linux, see https://conda-forge.org/docs/maintainer/knowledge_base.html?#libgl #} +{# libxcb, libxfixes, libxau and expat are not documented anywhere, but without those blocktest does not build correctly #} +{% if require_opengl_linux %}{% raw %} - {{ cdt('mesa-libgl-devel') }} + - {{ cdt('mesa-dri-drivers') }} + - {{ cdt('libselinux') }} + - {{ cdt('libxdamage') }} + - {{ cdt('libxxf86vm') }} + - {{ cdt('libxext') }} + - {{ cdt('libxcb') }} + - {{ cdt('libxfixes') }} + - {{ cdt('libxau') }} + - {{ cdt('expat') }} {% endraw %}{% endif %} + + host: +{# List all dependencies just a host. Run dependenencies should be correctly set by run_exports #} +{% for dep in dependencies %} - {{ dep }} +{% endfor %} +{# Handle specific packages required for gl on Linux, see https://conda-forge.org/docs/maintainer/knowledge_base.html?#libgl #} +{% if require_opengl_linux %} - xorg-libxfixes {% endif %} +{# Handle the constraint of macos >= 10.13 #} + run: + - __osx >={{ MACOSX_DEPLOYMENT_TARGET|default("10.9") }} # [osx and x86_64] + +about: + home: https://github.com/{{ github_repo }} diff --git a/doc/conda-forge.md b/doc/conda-forge.md index aa06ed877..5459f457f 100644 --- a/doc/conda-forge.md +++ b/doc/conda-forge.md @@ -4,6 +4,11 @@ [`conda-forge`](https://conda-forge.org/) is a community-mantained channel for the `conda` package manager that provides many dependencies useful for scientific software, in particular all the one that are required by the robotology-superbuild . +## Table of Contents +* [conda-forge overview](#conda-forge-overview) +* [Binary installation](#binary-installation) +* [Source installation](#source-installation) + ## conda-forge overview The **advantages** of the use of conda and conda-forge are: @@ -18,24 +23,66 @@ The **advantages** of the use of conda and conda-forge are: The **disadvantages** of conda and conda-forge are: * **Not compatible with dependencies installed by other package managers:** As conda-forge provides all the software it installs without using almost anything from the system, you cannot mix libraries installed by other package managers (such as `apt` or `homebrew`). If you have a dependency that is only provided by `apt` and is not available in `conda-forge`, then you should install all the dependencies that you want to use from `apt`. -* **No Debug version of C++ libraries on Windows:** as other package managers such as `apt` or `homebrew`, a part from some small exceptions conda-forge only ships the version of the libraries compiled as shared library and in `Release` compilation mode. This is not a big problem on Linux or macOS, where executables compiled in `Debug` can link libraries compiled in `Release`, but is more problematic on Windows, where this is not possible. When you are using conda-forge libraries on Windows, you can't compile your executable in `Debug` mode, but only in `Release` or `RelWithDebInfo` mode. If you stricly need to also have the `Debug` version of the libraries, the [`vcpkg`](https://github.com/microsoft/vcpkg) package manager may be more useful for oyu. +* **No Debug version of C++ libraries on Windows:** as other package managers such as `apt` or `homebrew`, a part from some small exceptions conda-forge only ships the version of the libraries compiled as shared library and in `Release` compilation mode. This is not a big problem on Linux or macOS, where executables compiled in `Debug` can link libraries compiled in `Release`, but is more problematic on Windows, where this is not possible. When you are using conda-forge libraries on Windows, you can't compile your executable in `Debug` mode, but only in `Release` or `RelWithDebInfo` mode. If you stricly need to also have the `Debug` version of the libraries, the [`vcpkg`](https://github.com/microsoft/vcpkg) package manager may be more useful for you. -## Source installation +## Binary installation -This section describes how to compile and install the robotology-superbuild with conda-forge provided dependencies on Windows, macOS and Linux. +This section describes how to compile and install the binary packages built from the robotology-superbuild on conda on Windows, macOS and Linux. +The binary packages are hosted in the [`robotology` conda channel](https://anaconda.org/robotology) . Only packages that are built as part of the profiles and options that are supported on Conda (see [documentation on profiles](profiles.md)) are available as conda binary packages in the `robotology` channel. ### Install a conda distribution If you do not have a conda distribution on your system, we suggest to use the minimal [`miniforge3`](https://github.com/conda-forge/miniforge#miniforge3) distribution, that uses `conda-forge` packages by default, following the instructions in our [`install-miniforge`](install-miniforge.md) documentation. -After you installed it, make sure that you can execute the `conda info` package from your terminal, and its output is similar to: +### Create an environment +Differently from `apt` and `homebrew`, the `conda` package manager is an `environment`-oriented package manager, meaning that packages are not +installed in some global location, but rather you install packages in an `environment` (that is just a directory in your filesystem), so that you +can easily have multiple different environments with different packages installed on your system. To read more about this, check https://docs.conda.io/projects/conda/en/4.6.1/user-guide/tasks/manage-environments.html . + +For this reason, to use the robotology conda packages it is suggested to first create a conda environment, and then install in it all the packages you want to use. To create a new environment called `robotologyenv`, execute the following command: +~~~ +conda create -n robotologyenv +~~~ + +Once you created the `robotologyenv` environment, you can "activate" it for the current terminal (i.e. make sure that the installed packages can be found) by the command: +~~~ +conda activate robotologyenv +~~~ + +**IMPORTANT: if you open a new terminal, you need to manually activate the environment also there.** + +### Install robotology packages + +Once you are in an activated environment, you can install robotology packages by just running the command: +~~~ +conda install -c robotology +~~~ + +The list of available packages is available at https://anaconda.org/robotology/repo . + +For example, if you want to install yarp and icub-main, you simple need to install: +~~~ +conda install -c robotology yarp icub-main +~~~ + +In addition, if you want to simulate the iCub in Gazebo, you should also install `icub-models` and `gazebo-yarp-plugins`: +~~~ +conda install -c robotology gazebo-yarp-plugins icub-models ~~~ -$ conda info - active environment : None -[...] +If you want to develop some C++ code on the top of these libraries, it is recommended to also install the necessary compiler and development tools directly in the same environment: +~~~ +conda install compilers cmake pkg-config make ninja ~~~ +## Source installation + +This section describes how to compile and install the robotology-superbuild with conda-forge provided dependencies on Windows, macOS and Linux. + +### Install a conda distribution +If you do not have a conda distribution on your system, we suggest to use the minimal +[`miniforge3`](https://github.com/conda-forge/miniforge#miniforge3) distribution, that uses `conda-forge` packages by default, following the instructions in our [`install-miniforge`](install-miniforge.md) documentation. + Also other conda distributions should be supported, you just will need to manually specify to use the `conda-forge` packages by adding `-c conda-forge` to all `conda install` commands. diff --git a/doc/conda-recipe-generation.md b/doc/conda-recipe-generation.md new file mode 100644 index 000000000..16603a7b6 --- /dev/null +++ b/doc/conda-recipe-generation.md @@ -0,0 +1,59 @@ +Conda Recipe Generation +======================= + +## Rationale + +See the [documentation on conda-forge and the robotology-superbuild](conda-forge.md) for a general discussion on how the robotology-superbuild and conda can work together. + +This document describes how to the internal machinery used to generate the conda recipes and then build conda binaries. If you just want to compile the robotology-superbuild from source using conda-forge dependendencies of you just want to install conda binary packages from the `robotology` conda channel, you do not need to read this document, as the information in the [documentation on conda-forge and the robotology-superbuild](conda-forge.md) should be enough. + +## How to generate recipes + +To generate the conda recipes for a given configuration of the `robotology-superbuild`, configure the `robotology-superbuild` in a conda workspace (TODO: docs on this, for now check the GitHub Action CI). As the conda recipes are intendend to build release version of software, specify an option to get a specific release. + +After that, install the additional dependencies required for the recipe generation: +~~~ +conda install pyyaml jinja2 conda-build ninja anaconda-client +python -m pip install git+https://github.com/wolfv/multisheller.git@0cc03c68d0c68d2f9cf7b07ddb68afa531419a6d +~~~ + +Then, set the `ROBOTOLOGY_GENERATE_CONDA_RECIPES` CMake option to `ON` in the `robotology-superbuild` build. This will **deactivate** the usual logic +for building projects of the `robotology-superbuild`, and instead will generate (at CMake configure time) conda recipes in `/conda/generated_recipes` for all the projects of the superbuild. If the configuration was concluded correctly, i.e. CMake configuration ended with: +~~~ +-- To build the generated conda recipes, navigate to the directory and run conda build . in it. +-- Configuring done +-- Generating done +-- Build files have been written to: C:/src/robotology-superbuild/build-conda +~~~ +you can then build the generated recipes by moving in the `/conda/generated_recipes` directory and running either [`conda build .`](https://github.com/conda/conda-build) or [`boa .`](https://github.com/mamba-org/boa). + +Note that the generated recipes will depend on the specific configuration of the robotology-superbuild used, so enabling additional profiles will generate recipes +for the packages contained in those profiles. For this reason, the generated recipes in general are not cross-platform. For example the recipes generated on `Linux` could contain Linux-specific CMake options passed to the projects, so may not be usable on Windows. +If you want to obtain recipe that can be built on a given operating system, please generate them with the robotology-superbuild on that operating system. + +## Internals + +All the files necessary to generate the conda recipes are contained in the `conda` directory of the root source dir. + +In particular: + +### `conda/cmake/RobotologySuperbuildGenerateCondaRecipes.cmake` +This CMake scripts contain the logic to generate the recipes. The generation is articulated as follows. + +The `cmake/RobotologySuperbuildLogic.cmake` file, that contains the logic of which projects should be built, +is run after redefining the `ycm_ep_helper` and `find_or_build_package` YCM functions, to extract the informations on name, +versions, dependency and cmake options of subpackages. This information are combined with the conda-specific metadata specified +in `conda/cmake/CondaGenerationOptions.cmake` (that contains information such as conda dependencies external to the `robotology-superbuild`) +to generate the `/conda/robotology-superbuild-conda-metametadata.yaml` file. + +After that, the data in `/conda/robotology-superbuild-conda-metametadata.yaml` is used via the `conda/python/generate_conda_recipes_from_metadatadata.py` +python script to generate the conda recipes. + +### `conda/recipe_template` + +This directory contains `Jinja2` templates for the files `meta.yaml`, `bld.bat` and `build.sh` that will be part of each generated recipe. + +### `conda/python/generate_conda_recipes_from_metadatadata.py` + +Python script that takes the `metametadata` file generated by the `generate_metametadata_file` CMake macro, and uses it to configure the +`Jinja2` templates `conda/recipe_template` to generate the recipe for each specific package. diff --git a/doc/developers-faqs.md b/doc/developers-faqs.md index b3cbb1491..de37ca00c 100644 --- a/doc/developers-faqs.md +++ b/doc/developers-faqs.md @@ -57,3 +57,20 @@ you can disable the automatical update of the tags by adding its CMake name in t * Once the release is ready to be made, create a `releases/yyyy.mm` branch from `master` * On the branch `releases/yyyy.mm` modify the default value of the `ROBOTOLOGY_PROJECT_TAGS` CMake option to be `Custom` and of the `ROBOTOLOGY_PROJECT_TAGS_CUSTOM_FILE` to the point to the `yyyy.mm.yaml` file. * Create a new tag and release `vyyyy.mm` on the `releases/yyyy.mm` branch + + +## How to ensure that binary packages are correctly generated for a new package +* If the package is already available in [`conda-forge`](https://conda-forge.org), then no binary should be created and the `conda-forge` version should be used. This is done by setting in the `Build.cmake` file the `_CONDA_PKG_NAME` variable to the name of the package in `conda-forge`, and setting to `ON` the `_CONDA_PKG_CONDA_FORGE_OVERRIDE` variable. For an example of such package, see [Buildosqp.cmake](../cmake/Buildosqp.cmake). +* If instead the package is not part of conda-forge, then it is appropriate to generate a binary package as part of the `robotology` channel, providing the following CMake options in the `Build.cmake` file: + +| Variable | Meaning | Default Value | +|:--------:|:-------:|:--------------:| +| `_CONDA_PKG_NAME` | The name that will be used for the conda package name. The convention is to use lowercase names separated by dashes. | The name of the github repo of the package. | +| `_CONDA_DEPENDENCIES` | The list of conda-forge dependencies required by this package. Note that dependencies managed by the robotology-superbuild should not be listed, as those are handled automatically. | The default value is empty. | + +For any doubt, double check the existing `Build.cmake` files for inspiration. +* If your package needs to set or modify some environment variables to work correctly, it should provide a pair of [multisheller](https://github.com/wolfv/multisheller) scripts named `_activate.msh` and `_deactivate.msh` in the `conda/multisheller` directory to describe how the environment should be modified. Refer to the existing scripts for more details. + + +## How often are conda binary packages generated? +* The conda binaries hosted in the [robotology conda channel](https://anaconda.org/robotology) are re-generated weekly by [`generate-conda-packages`](../.github/workflows/generate-conda-packages.yaml) GitHub Action CI job. At each new re-build, remember to bump the `CONDA_BUILD_NUMBER` in the [`conda/cmake/CondaGenerationOptions.cmake`](../conda/cmake/CondaGenerationOptions.cmake) file. The latest released version of the packages, as specified in the [`releases/latest.releases.yaml`](../releases/latest.releases.yaml) file is used to generate the binaries, that is in turn updated weekly automatically by the [`update-latest-releases`](../.github/workflows/update-latest-releases.yml) GitHub Action CI job. If you need to quickly generate a new binary for a new release, feel free to [open an issue to request that](https://github.com/robotology/robotology-superbuild/issues/new). diff --git a/releases/latest.releases.yaml b/releases/latest.releases.yaml index 1e0d3bf0a..030068ca8 100644 --- a/releases/latest.releases.yaml +++ b/releases/latest.releases.yaml @@ -54,7 +54,7 @@ repositories: yarp-matlab-bindings: type: git url: https://github.com/robotology/yarp-matlab-bindings.git - version: v3.4.1 + version: v3.4.2 RobotTestingFramework: type: git url: https://github.com/robotology/robot-testing-framework.git