diff --git a/.azure-pipelines/azure-pipelines-linux.yml b/.azure-pipelines/azure-pipelines-linux.yml index 41a7922..effe0c7 100755 --- a/.azure-pipelines/azure-pipelines-linux.yml +++ b/.azure-pipelines/azure-pipelines-linux.yml @@ -12,10 +12,12 @@ jobs: CONFIG: linux_64_ UPLOAD_PACKAGES: 'True' DOCKER_IMAGE: quay.io/condaforge/linux-anvil-cos7-x86_64 + SHORT_CONFIG: linux_64_ linux_aarch64_: CONFIG: linux_aarch64_ UPLOAD_PACKAGES: 'True' DOCKER_IMAGE: quay.io/condaforge/linux-anvil-cos7-x86_64 + SHORT_CONFIG: linux_aarch64_ timeoutInMinutes: 360 steps: @@ -46,4 +48,33 @@ jobs: env: BINSTAR_TOKEN: $(BINSTAR_TOKEN) FEEDSTOCK_TOKEN: $(FEEDSTOCK_TOKEN) - STAGING_BINSTAR_TOKEN: $(STAGING_BINSTAR_TOKEN) \ No newline at end of file + STAGING_BINSTAR_TOKEN: $(STAGING_BINSTAR_TOKEN) + - script: | + export CI=azure + export CI_RUN_ID=$(build.BuildNumber).$(system.JobAttempt) + export FEEDSTOCK_NAME=$(basename ${BUILD_REPOSITORY_NAME}) + export CONDA_BLD_DIR=build_artifacts + export ARTIFACT_STAGING_DIR="$(Build.ArtifactStagingDirectory)" + # Archive everything in CONDA_BLD_DIR except environments + export BLD_ARTIFACT_PREFIX=conda_artifacts + if [[ "$AGENT_JOBSTATUS" == "Failed" ]]; then + # Archive the CONDA_BLD_DIR environments only when the job fails + export ENV_ARTIFACT_PREFIX=conda_envs + fi + ./.scripts/create_conda_build_artifacts.sh + displayName: Prepare conda build artifacts + condition: succeededOrFailed() + + - task: PublishPipelineArtifact@1 + displayName: Store conda build artifacts + condition: not(eq(variables.BLD_ARTIFACT_PATH, '')) + inputs: + targetPath: $(BLD_ARTIFACT_PATH) + artifactName: $(BLD_ARTIFACT_NAME) + + - task: PublishPipelineArtifact@1 + displayName: Store conda build environment artifacts + condition: not(eq(variables.ENV_ARTIFACT_PATH, '')) + inputs: + targetPath: $(ENV_ARTIFACT_PATH) + artifactName: $(ENV_ARTIFACT_NAME) \ No newline at end of file diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml index 8032e96..a550455 100755 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -11,9 +11,11 @@ jobs: osx_64_: CONFIG: osx_64_ UPLOAD_PACKAGES: 'True' + SHORT_CONFIG: osx_64_ osx_arm64_: CONFIG: osx_arm64_ UPLOAD_PACKAGES: 'True' + SHORT_CONFIG: osx_arm64_ timeoutInMinutes: 360 steps: @@ -33,4 +35,33 @@ jobs: env: BINSTAR_TOKEN: $(BINSTAR_TOKEN) FEEDSTOCK_TOKEN: $(FEEDSTOCK_TOKEN) - STAGING_BINSTAR_TOKEN: $(STAGING_BINSTAR_TOKEN) \ No newline at end of file + STAGING_BINSTAR_TOKEN: $(STAGING_BINSTAR_TOKEN) + - script: | + export CI=azure + export CI_RUN_ID=$(build.BuildNumber).$(system.JobAttempt) + export FEEDSTOCK_NAME=$(basename ${BUILD_REPOSITORY_NAME}) + export CONDA_BLD_DIR=/Users/runner/miniforge3/conda-bld + export ARTIFACT_STAGING_DIR="$(Build.ArtifactStagingDirectory)" + # Archive everything in CONDA_BLD_DIR except environments + export BLD_ARTIFACT_PREFIX=conda_artifacts + if [[ "$AGENT_JOBSTATUS" == "Failed" ]]; then + # Archive the CONDA_BLD_DIR environments only when the job fails + export ENV_ARTIFACT_PREFIX=conda_envs + fi + ./.scripts/create_conda_build_artifacts.sh + displayName: Prepare conda build artifacts + condition: succeededOrFailed() + + - task: PublishPipelineArtifact@1 + displayName: Store conda build artifacts + condition: not(eq(variables.BLD_ARTIFACT_PATH, '')) + inputs: + targetPath: $(BLD_ARTIFACT_PATH) + artifactName: $(BLD_ARTIFACT_NAME) + + - task: PublishPipelineArtifact@1 + displayName: Store conda build environment artifacts + condition: not(eq(variables.ENV_ARTIFACT_PATH, '')) + inputs: + targetPath: $(ENV_ARTIFACT_PATH) + artifactName: $(ENV_ARTIFACT_NAME) \ No newline at end of file diff --git a/.azure-pipelines/azure-pipelines-win.yml b/.azure-pipelines/azure-pipelines-win.yml index 8a0bcae..f7fc29f 100755 --- a/.azure-pipelines/azure-pipelines-win.yml +++ b/.azure-pipelines/azure-pipelines-win.yml @@ -11,6 +11,7 @@ jobs: win_64_: CONFIG: win_64_ UPLOAD_PACKAGES: 'True' + SHORT_CONFIG: win_64_ timeoutInMinutes: 360 variables: CONDA_BLD_PATH: D:\\bld\\ @@ -63,6 +64,33 @@ jobs: displayName: Build recipe env: PYTHONUNBUFFERED: 1 + - script: | + set CI=azure + set CI_RUN_ID=$(build.BuildNumber).$(system.JobAttempt) + set FEEDSTOCK_NAME=$(build.Repository.Name) + set ARTIFACT_STAGING_DIR=$(Build.ArtifactStagingDirectory) + set CONDA_BLD_DIR=$(CONDA_BLD_PATH) + set BLD_ARTIFACT_PREFIX=conda_artifacts + if "%AGENT_JOBSTATUS%" == "Failed" ( + set ENV_ARTIFACT_PREFIX=conda_envs + ) + call ".scripts\create_conda_build_artifacts.bat" + displayName: Prepare conda build artifacts + condition: succeededOrFailed() + + - task: PublishPipelineArtifact@1 + displayName: Store conda build artifacts + condition: not(eq(variables.BLD_ARTIFACT_PATH, '')) + inputs: + targetPath: $(BLD_ARTIFACT_PATH) + artifactName: $(BLD_ARTIFACT_NAME) + + - task: PublishPipelineArtifact@1 + displayName: Store conda build environment artifacts + condition: not(eq(variables.ENV_ARTIFACT_PATH, '')) + inputs: + targetPath: $(ENV_ARTIFACT_PATH) + artifactName: $(ENV_ARTIFACT_NAME) - script: | set "FEEDSTOCK_NAME=%BUILD_REPOSITORY_NAME:*/=%" call activate base diff --git a/.scripts/create_conda_build_artifacts.bat b/.scripts/create_conda_build_artifacts.bat new file mode 100755 index 0000000..79ce625 --- /dev/null +++ b/.scripts/create_conda_build_artifacts.bat @@ -0,0 +1,80 @@ +setlocal enableextensions enabledelayedexpansion + +rem INPUTS (environment variables that need to be set before calling this script): +rem +rem CI (azure/github_actions/UNSET) +rem CI_RUN_ID (unique identifier for the CI job run) +rem FEEDSTOCK_NAME +rem CONFIG (build matrix configuration string) +rem SHORT_CONFIG (uniquely-shortened configuration string) +rem CONDA_BLD_DIR (path to the conda-bld directory) +rem ARTIFACT_STAGING_DIR (use working directory if unset) +rem BLD_ARTIFACT_PREFIX (prefix for the conda build artifact name, skip if unset) +rem ENV_ARTIFACT_PREFIX (prefix for the conda build environments artifact name, skip if unset) + +rem OUTPUTS +rem +rem BLD_ARTIFACT_NAME +rem BLD_ARTIFACT_PATH +rem ENV_ARTIFACT_NAME +rem ENV_ARTIFACT_PATH + +rem Check that the conda-build directory exists +if not exist %CONDA_BLD_DIR% ( + echo conda-build directory does not exist + exit 1 +) + +if not defined ARTIFACT_STAGING_DIR ( + rem Set staging dir to the working dir + set ARTIFACT_STAGING_DIR=%cd% +) + +rem Set a unique ID for the artifact(s), specialized for this particular job run +set ARTIFACT_UNIQUE_ID=%CI_RUN_ID%_%CONFIG% +if not "%ARTIFACT_UNIQUE_ID%" == "%ARTIFACT_UNIQUE_ID:~0,80%" ( + set ARTIFACT_UNIQUE_ID=%CI_RUN_ID%_%SHORT_CONFIG% +) + +rem Set a descriptive ID for the archive(s), specialized for this particular job run +set ARCHIVE_UNIQUE_ID=%CI_RUN_ID%_%CONFIG% + +rem Make the build artifact zip +if defined BLD_ARTIFACT_PREFIX ( + set BLD_ARTIFACT_NAME=%BLD_ARTIFACT_PREFIX%_%ARTIFACT_UNIQUE_ID% + echo BLD_ARTIFACT_NAME: !BLD_ARTIFACT_NAME! + + set "BLD_ARTIFACT_PATH=%ARTIFACT_STAGING_DIR%\%FEEDSTOCK_NAME%_%BLD_ARTIFACT_PREFIX%_%ARCHIVE_UNIQUE_ID%.zip" + 7z a "!BLD_ARTIFACT_PATH!" "%CONDA_BLD_DIR%" -xr^^!.git/ -xr^^!_*_env*/ -xr^^!*_cache/ -bb + if errorlevel 1 exit 1 + echo BLD_ARTIFACT_PATH: !BLD_ARTIFACT_PATH! + + if "%CI%" == "azure" ( + echo ##vso[task.setVariable variable=BLD_ARTIFACT_NAME]!BLD_ARTIFACT_NAME! + echo ##vso[task.setVariable variable=BLD_ARTIFACT_PATH]!BLD_ARTIFACT_PATH! + ) + if "%CI%" == "github_actions" ( + echo ::set-output name=BLD_ARTIFACT_NAME::!BLD_ARTIFACT_NAME! + echo ::set-output name=BLD_ARTIFACT_PATH::!BLD_ARTIFACT_PATH! + ) +) + +rem Make the environments artifact zip +if defined ENV_ARTIFACT_PREFIX ( + set ENV_ARTIFACT_NAME=!ENV_ARTIFACT_PREFIX!_%ARTIFACT_UNIQUE_ID% + echo ENV_ARTIFACT_NAME: !ENV_ARTIFACT_NAME! + + set "ENV_ARTIFACT_PATH=%ARTIFACT_STAGING_DIR%\%FEEDSTOCK_NAME%_%ENV_ARTIFACT_PREFIX%_%ARCHIVE_UNIQUE_ID%.zip" + 7z a "!ENV_ARTIFACT_PATH!" -r "%CONDA_BLD_DIR%"/_*_env*/ -bb + if errorlevel 1 exit 1 + echo ENV_ARTIFACT_PATH: !ENV_ARTIFACT_PATH! + + if "%CI%" == "azure" ( + echo ##vso[task.setVariable variable=ENV_ARTIFACT_NAME]!ENV_ARTIFACT_NAME! + echo ##vso[task.setVariable variable=ENV_ARTIFACT_PATH]!ENV_ARTIFACT_PATH! + ) + if "%CI%" == "github_actions" ( + echo ::set-output name=ENV_ARTIFACT_NAME::!ENV_ARTIFACT_NAME! + echo ::set-output name=ENV_ARTIFACT_PATH::!ENV_ARTIFACT_PATH! + ) +) \ No newline at end of file diff --git a/.scripts/create_conda_build_artifacts.sh b/.scripts/create_conda_build_artifacts.sh new file mode 100755 index 0000000..cba0fae --- /dev/null +++ b/.scripts/create_conda_build_artifacts.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +# INPUTS (environment variables that need to be set before calling this script): +# +# CI (azure/github_actions/UNSET) +# CI_RUN_ID (unique identifier for the CI job run) +# FEEDSTOCK_NAME +# CONFIG (build matrix configuration string) +# SHORT_CONFIG (uniquely-shortened configuration string) +# CONDA_BLD_DIR (path to the conda-bld directory) +# ARTIFACT_STAGING_DIR (use working directory if unset) +# BLD_ARTIFACT_PREFIX (prefix for the conda build artifact name, skip if unset) +# ENV_ARTIFACT_PREFIX (prefix for the conda build environments artifact name, skip if unset) + +# OUTPUTS +# +# BLD_ARTIFACT_NAME +# BLD_ARTIFACT_PATH +# ENV_ARTIFACT_NAME +# ENV_ARTIFACT_PATH + +source .scripts/logging_utils.sh + +# DON'T do set -x, because it results in double echo-ing pipeline commands +# and that might end up inserting extraneous quotation marks in output variables +set -e + +# Check that the conda-build directory exists +if [ ! -d "$CONDA_BLD_DIR" ]; then + echo "conda-build directory does not exist" + exit 1 +fi + +# Set staging dir to the working dir, in Windows style if applicable +if [[ -z "${ARTIFACT_STAGING_DIR}" ]]; then + if pwd -W; then + ARTIFACT_STAGING_DIR=$(pwd -W) + else + ARTIFACT_STAGING_DIR=$PWD + fi +fi +echo "ARTIFACT_STAGING_DIR: $ARTIFACT_STAGING_DIR" + +FEEDSTOCK_ROOT=$(cd "$(dirname "$0")/.."; pwd;) +if [ -z ${FEEDSTOCK_NAME} ]; then + export FEEDSTOCK_NAME=$(basename ${FEEDSTOCK_ROOT}) +fi + +# Set a unique ID for the artifact(s), specialized for this particular job run +ARTIFACT_UNIQUE_ID="${CI_RUN_ID}_${CONFIG}" +if [[ ${#ARTIFACT_UNIQUE_ID} -gt 80 ]]; then + ARTIFACT_UNIQUE_ID="${CI_RUN_ID}_${SHORT_CONFIG}" +fi +echo "ARTIFACT_UNIQUE_ID: $ARTIFACT_UNIQUE_ID" + +# Set a descriptive ID for the archive(s), specialized for this particular job run +ARCHIVE_UNIQUE_ID="${CI_RUN_ID}_${CONFIG}" + +# Make the build artifact zip +if [[ ! -z "$BLD_ARTIFACT_PREFIX" ]]; then + export BLD_ARTIFACT_NAME="${BLD_ARTIFACT_PREFIX}_${ARTIFACT_UNIQUE_ID}" + export BLD_ARTIFACT_PATH="${ARTIFACT_STAGING_DIR}/${FEEDSTOCK_NAME}_${BLD_ARTIFACT_PREFIX}_${ARCHIVE_UNIQUE_ID}.zip" + + ( startgroup "Archive conda build directory" ) 2> /dev/null + + # Try 7z and fall back to zip if it fails (for cross-platform use) + if ! 7z a "$BLD_ARTIFACT_PATH" "$CONDA_BLD_DIR" '-xr!.git/' '-xr!_*_env*/' '-xr!*_cache/' -bb; then + pushd "$CONDA_BLD_DIR" + zip -r -y -T "$BLD_ARTIFACT_PATH" . -x '*.git/*' '*_*_env*/*' '*_cache/*' + popd + fi + + ( endgroup "Archive conda build directory" ) 2> /dev/null + + echo "BLD_ARTIFACT_NAME: $BLD_ARTIFACT_NAME" + echo "BLD_ARTIFACT_PATH: $BLD_ARTIFACT_PATH" + + if [[ "$CI" == "azure" ]]; then + echo "##vso[task.setVariable variable=BLD_ARTIFACT_NAME]$BLD_ARTIFACT_NAME" + echo "##vso[task.setVariable variable=BLD_ARTIFACT_PATH]$BLD_ARTIFACT_PATH" + elif [[ "$CI" == "github_actions" ]]; then + echo "::set-output name=BLD_ARTIFACT_NAME::$BLD_ARTIFACT_NAME" + echo "::set-output name=BLD_ARTIFACT_PATH::$BLD_ARTIFACT_PATH" + fi +fi + +# Make the environments artifact zip +if [[ ! -z "$ENV_ARTIFACT_PREFIX" ]]; then + export ENV_ARTIFACT_NAME="${ENV_ARTIFACT_PREFIX}_${ARTIFACT_UNIQUE_ID}" + export ENV_ARTIFACT_PATH="${ARTIFACT_STAGING_DIR}/${FEEDSTOCK_NAME}_${ENV_ARTIFACT_PREFIX}_${ARCHIVE_UNIQUE_ID}.zip" + + ( startgroup "Archive conda build environments" ) 2> /dev/null + + # Try 7z and fall back to zip if it fails (for cross-platform use) + if ! 7z a "$ENV_ARTIFACT_PATH" -r "$CONDA_BLD_DIR"/'_*_env*/' -bb; then + pushd "$CONDA_BLD_DIR" + zip -r -y -T "$ENV_ARTIFACT_PATH" . -i '*_*_env*/*' + popd + fi + + ( endgroup "Archive conda build environments" ) 2> /dev/null + + echo "ENV_ARTIFACT_NAME: $ENV_ARTIFACT_NAME" + echo "ENV_ARTIFACT_PATH: $ENV_ARTIFACT_PATH" + + if [[ "$CI" == "azure" ]]; then + echo "##vso[task.setVariable variable=ENV_ARTIFACT_NAME]$ENV_ARTIFACT_NAME" + echo "##vso[task.setVariable variable=ENV_ARTIFACT_PATH]$ENV_ARTIFACT_PATH" + elif [[ "$CI" == "github_actions" ]]; then + echo "::set-output name=ENV_ARTIFACT_NAME::$ENV_ARTIFACT_NAME" + echo "::set-output name=ENV_ARTIFACT_PATH::$ENV_ARTIFACT_PATH" + fi +fi \ No newline at end of file diff --git a/conda-forge.yml b/conda-forge.yml index 06f629b..d54cacb 100644 --- a/conda-forge.yml +++ b/conda-forge.yml @@ -10,3 +10,5 @@ github: branch_name: main tooling_branch_name: main test: native_and_emulated +azure: + store_build_artifacts: true diff --git a/recipe/activate.msh b/recipe/activate.msh new file mode 100644 index 0000000..b28ceb1 --- /dev/null +++ b/recipe/activate.msh @@ -0,0 +1,11 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_append("IGN_GAZEBO_SYSTEM_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-gazebo-6\\plugins")), + sys.list_append("IGN_GUI_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-gazebo-6\\plugins\\gui")), + sys.list_append("IGN_GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\ignition\\ignition-gazebo6\\worlds")), + sys.list_append("IGN_GAZEBO_PHYSICS_ENGINE_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-physics-5\\engine-plugins")), +]).else_([ + sys.list_append("IGN_GAZEBO_SYSTEM_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-gazebo-6/plugins")), + sys.list_append("IGN_GUI_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-gazebo-6/plugins/gui")), + sys.list_append("IGN_GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "share/ignition/ignition-gazebo6/worlds")), + sys.list_append("IGN_GAZEBO_PHYSICS_ENGINE_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-physics-5/engine-plugins")), +]) diff --git a/recipe/bld.bat b/recipe/bld.bat index 0e2bcff..da91676 100644 --- a/recipe/bld.bat +++ b/recipe/bld.bat @@ -18,3 +18,31 @@ if errorlevel 1 exit 1 :: Install. cmake --build . --config Release --target install if errorlevel 1 exit 1 + +setlocal EnableDelayedExpansion +:: Just on Windows, binary relocation is not working properly so we use environment variables +:: to specify the location of resources installed by ign-gazebo +:: Generate and 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 ( + multisheller %RECIPE_DIR%\%%F.msh --output .\%%F + + if not exist %PREFIX%\etc\conda\%%F.d mkdir %PREFIX%\etc\conda\%%F.d + copy %%F.bat %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.bat + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %%F.sh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.sh + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %%F.bash %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.bash + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %%F.ps1 %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.ps1 + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %%F.xsh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.xsh + if %errorlevel% neq 0 exit /b %errorlevel% + + copy %%F.zsh %PREFIX%\etc\conda\%%F.d\%PKG_NAME%_%%F.zsh + if %errorlevel% neq 0 exit /b %errorlevel% +) diff --git a/recipe/deactivate.msh b/recipe/deactivate.msh new file mode 100644 index 0000000..c312229 --- /dev/null +++ b/recipe/deactivate.msh @@ -0,0 +1,11 @@ +if_(is_set("COMSPEC")).then_([ + sys.list_remove("IGN_GAZEBO_SYSTEM_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-gazebo-6\\plugins")), + sys.list_remove("IGN_GUI_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-gazebo-6\\plugins\\gui")), + sys.list_remove("IGN_GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "Library\\share\\ignition\\ignition-gazebo6\\worlds")), + sys.list_remove("IGN_GAZEBO_PHYSICS_ENGINE_PATH", path.join(env("CONDA_PREFIX"), "Library\\lib\\ign-physics-5\\engine-plugins")), +]).else_([ + sys.list_remove("IGN_GAZEBO_SYSTEM_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-gazebo-6/plugins")), + sys.list_remove("IGN_GUI_PLUGIN_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-gazebo-6/plugins/gui")), + sys.list_remove("IGN_GAZEBO_RESOURCE_PATH", path.join(env("CONDA_PREFIX"), "share/ignition/ignition-gazebo6/worlds")), + sys.list_remove("IGN_GAZEBO_PHYSICS_ENGINE_PATH", path.join(env("CONDA_PREFIX"), "lib/ign-physics-5/engine-plugins")), +]) diff --git a/recipe/enable_win_ign.patch b/recipe/enable_win_ign.patch index fe7a7b1..dd94fc0 100644 --- a/recipe/enable_win_ign.patch +++ b/recipe/enable_win_ign.patch @@ -1,23 +1,467 @@ -From bfbff0e0163c37fe825d73c4cd0dd470bce1cdb4 Mon Sep 17 00:00:00 2001 -From: Silvio Traversaro -Date: Sun, 3 Jul 2022 19:43:31 +0200 -Subject: [PATCH] Install ignition-tools files also on Windows +From 7dc7dd4773f595ccc27f9eba5f21dc674065a49c Mon Sep 17 00:00:00 2001 +From: Silvio +Date: Tue, 5 Jul 2022 21:10:16 +0200 +Subject: [PATCH] Enable use of ign gazebo -s on Windows Signed-off-by: Silvio --- - src/CMakeLists.txt | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) + src/CMakeLists.txt | 32 ++++++++-- + src/cmd/CMakeLists.txt | 121 +++++++++++++++++++++---------------- + src/cmd/ModelCommandAPI.hh | 6 +- + src/cmd/cmdgazebo.rb.in | 16 ++++- + src/cmd/cmdmodel.rb.in | 4 +- + src/ign.hh | 16 ++--- + src/ign_TEST.cc | 13 ++-- + src/systems/CMakeLists.txt | 7 +-- + 8 files changed, 136 insertions(+), 79 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index ff178007c..fd606033a 100644 +index ff178007c3..7acb368963 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt -@@ -224,7 +224,4 @@ foreach(CMD_TEST +@@ -92,7 +92,6 @@ set (gtest_sources + TestFixture_TEST.cc + Util_TEST.cc + World_TEST.cc +- ign_TEST.cc + comms/Broker_TEST.cc + comms/MsgManager_TEST.cc + network/NetworkConfig_TEST.cc +@@ -100,11 +99,22 @@ set (gtest_sources + network/NetworkManager_TEST.cc + ) - endforeach() ++# ign_TEST and ModelCommandAPI_TEST are not supported with multi config ++# CMake generators, see also cmd/CMakeLists.txt ++get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) ++if(NOT GENERATOR_IS_MULTI_CONFIG) ++ list(APPEND gtest_sources ign_TEST.cc) ++endif() ++ ++ + # Tests that require a valid display + set(tests_needing_display +- ModelCommandAPI_TEST.cc + ) + ++if(NOT GENERATOR_IS_MULTI_CONFIG) ++ list(APPEND tests_needing_display ModelCommandAPI_TEST.cc) ++endif() ++ + # Add systems that need a valid display here. + # \todo(anyone) Find a way to run these tests with a virtual display such Xvfb + # or Xdummy instead of skipping them +@@ -222,9 +232,19 @@ foreach(CMD_TEST + set_tests_properties(${CMD_TEST} PROPERTIES + ENVIRONMENT "${_env_vars}") + +-endforeach() ++ # On Windows there is no RPATH, so an alternative way for tests for finding .dll libraries ++ # in build directory in necessary. For regular tests, the trick is to place all libraries ++ # and executables in a common CMAKE_RUNTIME_OUTPUT_DIRECTORY, so that the .dll are found ++ # as they are in the same directory where the executable is loaded. For tests that are ++ # launched via ruby, this does not work, so we need to manually add CMAKE_RUNTIME_OUTPUT_DIRECTORY ++ # to the PATH. This is done via the ENVIRONMENT_MODIFICATION that is only available ++ # since CMake 3.22 . However, if an older CMake is used another trick to install the libraries ++ # beforehand ++ if (WIN32 AND CMAKE_VERSION STRGREATER "3.22") ++ set_tests_properties(${CMD_TEST} PROPERTIES ++ ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") ++ endif() -if(NOT WIN32) - add_subdirectory(cmd) -endif() -- ++endforeach() + +add_subdirectory(cmd) +diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt +index 11e7ef7e00..e81a98be44 100644 +--- a/src/cmd/CMakeLists.txt ++++ b/src/cmd/CMakeLists.txt +@@ -2,12 +2,19 @@ + # Generate the ruby script. + # Note that the major version of the library is included in the name. + # Ex: cmdgazebo0.rb +-set(cmd_script_generated "${CMAKE_CURRENT_BINARY_DIR}/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.rb") +-set(cmd_script_configured "${cmd_script_generated}.configured") ++set(cmd_script_name "cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.rb") ++set(cmd_script_generated "${CMAKE_CURRENT_BINARY_DIR}/$_${cmd_script_name}") ++set(cmd_script_configured "${CMAKE_CURRENT_BINARY_DIR}/${cmd_script_name}.configured") + + # Set the library_location variable to the relative path to the library file + # within the install directory structure. +-set(library_location "../../../${CMAKE_INSTALL_LIBDIR}/$") ++if(WIN32) ++ set(plugin_location ${CMAKE_INSTALL_BINDIR}) ++else() ++ set(plugin_location ${CMAKE_INSTALL_LIBDIR}) ++endif() ++ ++set(library_location "../../../${plugin_location}/$") + + configure_file( + "cmd${IGN_DESIGNATION}.rb.in" +@@ -19,7 +26,7 @@ file(GENERATE + INPUT "${cmd_script_configured}") + + # Install the ruby command line library in an unversioned location. +-install(FILES ${cmd_script_generated} DESTINATION lib/ruby/ignition) ++install(FILES ${cmd_script_generated} DESTINATION lib/ruby/ignition RENAME ${cmd_script_name}) + + set(ign_library_path "${CMAKE_INSTALL_PREFIX}/lib/ruby/ignition/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}") + +@@ -40,8 +47,9 @@ install( FILES + # Used for the installed model command version. + # Generate the ruby script that gets installed. + # Note that the major version of the library is included in the name. +-set(cmd_model_script_generated "${CMAKE_CURRENT_BINARY_DIR}/cmdmodel${PROJECT_VERSION_MAJOR}.rb") +-set(cmd_model_script_configured "${cmd_model_script_generated}.configured") ++set(cmd_model_script_name "cmdmodel${PROJECT_VERSION_MAJOR}.rb") ++set(cmd_model_script_generated "${CMAKE_CURRENT_BINARY_DIR}/$_${cmd_model_script_name}") ++set(cmd_model_script_configured "${CMAKE_CURRENT_BINARY_DIR}/${cmd_model_script_name}.configured") + + configure_file( + "cmdmodel.rb.in" +@@ -51,7 +59,7 @@ file(GENERATE + OUTPUT "${cmd_model_script_generated}" + INPUT "${cmd_model_script_configured}") + +-install(FILES ${cmd_model_script_generated} DESTINATION lib/ruby/ignition) ++install(FILES ${cmd_model_script_generated} DESTINATION lib/ruby/ignition RENAME ${cmd_model_script_name}) + + # Used for the installed version. + set(ign_model_ruby_path "${CMAKE_INSTALL_PREFIX}/lib/ruby/ignition/cmdmodel${PROJECT_VERSION_MAJOR}") +@@ -68,55 +76,64 @@ install(FILES ${model_configured} DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_IN + # Generate the ruby script for internal testing. + # Note that the major version of the library is included in the name. + # Ex: cmdgazebo0.rb +-set(cmd_script_generated_test "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.rb") +-set(cmd_script_configured_test "${cmd_script_generated_test}.configured") +- +-# Set the library_location variable to the relative path to the library file +-# within the install directory structure. +-set(library_location "$") +- +-configure_file( +- "cmd${IGN_DESIGNATION}.rb.in" +- "${cmd_script_configured_test}" +- @ONLY) +- +-file(GENERATE +- OUTPUT "${cmd_script_generated_test}" +- INPUT "${cmd_script_configured_test}") +- +-# Used only for internal testing. +-set(ign_library_path +- "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}") +- +-# Generate a configuration file for internal testing. +-# Note that the major version of the library is included in the name. +-# Ex: gazebo0.yaml +-configure_file( +- "${IGN_DESIGNATION}.yaml.in" +- "${CMAKE_BINARY_DIR}/test/conf/${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.yaml" @ONLY) ++# The logic is valid only for single-config CMake generators, so no script is ++# generated if a multiple-config CMake geneator is used ++get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) ++if(NOT GENERATOR_IS_MULTI_CONFIG) ++ set(cmd_script_generated_test "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.rb") ++ set(cmd_script_configured_test "${cmd_script_generated_test}.configured") ++ ++ # Set the library_location variable to the relative path to the library file ++ # within the install directory structure. ++ set(library_location "$") ++ ++ configure_file( ++ "cmd${IGN_DESIGNATION}.rb.in" ++ "${cmd_script_configured_test}" ++ @ONLY) ++ ++ file(GENERATE ++ OUTPUT "${cmd_script_generated_test}" ++ INPUT "${cmd_script_configured_test}") ++ ++ # Used only for internal testing. ++ set(ign_library_path ++ "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition/cmd${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}") ++ ++ # Generate a configuration file for internal testing. ++ # Note that the major version of the library is included in the name. ++ # Ex: gazebo0.yaml ++ configure_file( ++ "${IGN_DESIGNATION}.yaml.in" ++ "${CMAKE_BINARY_DIR}/test/conf/${IGN_DESIGNATION}${PROJECT_VERSION_MAJOR}.yaml" @ONLY) ++endif() + + #=============================================================================== + # Generate the ruby script for internal testing. + # Note that the major version of the library is included in the name. +-set(cmd_model_ruby_test_dir "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition") +-set(cmd_model_script_generated_test "${cmd_model_ruby_test_dir}/cmdmodel${PROJECT_VERSION_MAJOR}.rb") +-set(cmd_model_script_configured_test "${cmd_model_script_generated_test}.configured") +- +-configure_file( +- "cmdmodel.rb.in" +- "${cmd_model_script_configured_test}" +- @ONLY) +- +-file(GENERATE +- OUTPUT "${cmd_model_script_generated_test}" +- INPUT "${cmd_model_script_configured_test}") +- +-# Used for internal testing. +-set(ign_model_ruby_path "${cmd_model_script_generated_test}") +- +-configure_file( +- "model.yaml.in" +- "${CMAKE_BINARY_DIR}/test/conf/model${PROJECT_VERSION_MAJOR}.yaml" @ONLY) ++# The logic is valid only for single-config CMake generators, so no script is ++# generated if a multiple-config CMake geneator is used ++if(NOT GENERATOR_IS_MULTI_CONFIG) ++ set(cmd_model_ruby_test_dir "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition") ++ set(cmd_model_script_generated_test "${cmd_model_ruby_test_dir}/cmdmodel${PROJECT_VERSION_MAJOR}.rb") ++ set(cmd_model_script_configured_test "${cmd_model_script_generated_test}.configured") ++ ++ configure_file( ++ "cmdmodel.rb.in" ++ "${cmd_model_script_configured_test}" ++ @ONLY) ++ ++ file(GENERATE ++ OUTPUT "${cmd_model_script_generated_test}" ++ INPUT "${cmd_model_script_configured_test}") ++ ++ # Used for internal testing. ++ set(ign_model_ruby_path "${cmd_model_script_generated_test}") ++ ++ configure_file( ++ "model.yaml.in" ++ "${CMAKE_BINARY_DIR}/test/conf/model${PROJECT_VERSION_MAJOR}.yaml" @ONLY) ++endif() + + #=============================================================================== + # Bash completion +diff --git a/src/cmd/ModelCommandAPI.hh b/src/cmd/ModelCommandAPI.hh +index 2ca7248c60..c941936471 100644 +--- a/src/cmd/ModelCommandAPI.hh ++++ b/src/cmd/ModelCommandAPI.hh +@@ -15,8 +15,10 @@ + * + */ + ++#include "ignition/gazebo/Export.hh" ++ + /// \brief External hook to get a list of available models. +-extern "C" void cmdModelList(); ++extern "C" IGNITION_GAZEBO_VISIBLE void cmdModelList(); + + /// \brief External hook to dump model information. + /// \param[in] _modelName Model name. +@@ -24,7 +26,7 @@ extern "C" void cmdModelList(); + /// \param[in] _linkName Link name. + /// \param[in] _jointName Joint name. + /// \param[in] _sensorName Sensor name. +-extern "C" void cmdModelInfo( ++extern "C" IGNITION_GAZEBO_VISIBLE void cmdModelInfo( + const char *_modelName, int _pose, const char *_linkName, + const char *_jointName, + const char *_sensorName); +diff --git a/src/cmd/cmdgazebo.rb.in b/src/cmd/cmdgazebo.rb.in +index 16ee5e1cac..023843ce1d 100755 +--- a/src/cmd/cmdgazebo.rb.in ++++ b/src/cmd/cmdgazebo.rb.in +@@ -27,6 +27,7 @@ end + + require 'optparse' + require 'erb' ++require 'pathname' + + # Constants. + LIBRARY_NAME = '@library_location@' +@@ -337,7 +338,8 @@ class Cmd + def execute(args) + options = parse(args) + +- if LIBRARY_NAME[0] == '/' ++ library_name_path = Pathname.new(LIBRARY_NAME) ++ if library_name_path.absolute? + # If the first character is a slash, we'll assume that we've been given an + # absolute path to the library. This is only used during test mode. + plugin = LIBRARY_NAME +@@ -467,6 +469,12 @@ See https://github.com/ignitionrobotics/ign-gazebo/issues/44 for more info." + exit(-1) + end + ++ if plugin.end_with? ".dll" ++ puts "`ign gazebo` currently only works with the -s argument on Windows. ++See https://github.com/gazebosim/gz-sim/issues/168 for more info." ++ exit(-1) ++ end ++ + serverPid = Process.fork do + ENV['RMT_PORT'] = '1500' + Process.setpgid(0, 0) +@@ -526,6 +534,12 @@ See https://github.com/ignitionrobotics/ign-gazebo/issues/44 for more info." + exit(-1) + end + ++ if plugin.end_with? ".dll" ++ puts "`ign gazebo` currently only works with the -s argument on Windows. ++See https://github.com/gazebosim/gz-sim/issues/168 for more info." ++ exit(-1) ++ end ++ + ENV['RMT_PORT'] = '1501' + Importer.runGui(options['gui_config'], options['file'], + options['wait_gui'], options['render_engine_gui']) +diff --git a/src/cmd/cmdmodel.rb.in b/src/cmd/cmdmodel.rb.in +index 88e65a50f3..e49eb30749 100644 +--- a/src/cmd/cmdmodel.rb.in ++++ b/src/cmd/cmdmodel.rb.in +@@ -26,6 +26,7 @@ else + end + + require 'optparse' ++require 'pathname' + + # Constants. + LIBRARY_NAME = '@library_location@' +@@ -157,7 +158,8 @@ class Cmd + options = parse(args) + + # Read the plugin that handles the command. +- if LIBRARY_NAME[0] == '/' ++ library_name_path = Pathname.new(LIBRARY_NAME) ++ if library_name_path.absolute? + # If the first character is a slash, we'll assume that we've been given an + # absolute path to the library. This is only used during test mode. + plugin = LIBRARY_NAME +diff --git a/src/ign.hh b/src/ign.hh +index 38de2a88e6..18eac3cfc5 100644 +--- a/src/ign.hh ++++ b/src/ign.hh +@@ -21,18 +21,18 @@ + + /// \brief External hook to read the library version. + /// \return C-string representing the version. Ex.: 0.1.2 +-extern "C" char *ignitionGazeboVersion(); ++extern "C" IGNITION_GAZEBO_VISIBLE char *ignitionGazeboVersion(); + + /// \brief Get the Gazebo version header. + /// \return C-string containing the Gazebo version information. +-extern "C" char *gazeboVersionHeader(); ++extern "C" IGNITION_GAZEBO_VISIBLE char *gazeboVersionHeader(); + + /// \brief Set verbosity level + /// \param[in] _verbosity 0 to 4 +-extern "C" void cmdVerbosity( ++extern "C" IGNITION_GAZEBO_VISIBLE void cmdVerbosity( + const char *_verbosity); + +-extern "C" const char *worldInstallDir(); ++extern "C" IGNITION_GAZEBO_VISIBLE const char *worldInstallDir(); + + /// \brief External hook to run simulation server. + /// \param[in] _sdfString SDF file to run, as a string. +@@ -59,7 +59,7 @@ extern "C" const char *worldInstallDir(); + /// \param[in] _headless True if server rendering should run headless + /// \param[in] _recordPeriod --record-period option + /// \return 0 if successful, 1 if not. +-extern "C" int runServer(const char *_sdfString, ++extern "C" IGNITION_GAZEBO_VISIBLE int runServer(const char *_sdfString, + int _iterations, int _run, float _hz, int _levels, + const char *_networkRole, int _networkSecondaries, int _record, + const char *_recordPath, int _recordResources, int _logOverwrite, +@@ -77,14 +77,14 @@ extern "C" int runServer(const char *_sdfString, + /// it receives a world path from GUI. + /// \param[in] _renderEngine --render-engine-gui option + /// \return 0 if successful, 1 if not. +-extern "C" int runGui(const char *_guiConfig, const char *_file, int _waitGui, +- const char *_renderEngine); ++extern "C" IGNITION_GAZEBO_VISIBLE int runGui(const char *_guiConfig, ++ const char *_file, int _waitGui, const char *_renderEngine); + + /// \brief External hook to find or download a fuel world provided a URL. + /// \param[in] _pathToResource Path to the fuel world resource, ie, + /// https://staging-fuel.ignitionrobotics.org/1.0/gmas/worlds/ShapesClone + /// \return C-string containing the path to the local world sdf file +-extern "C" const char *findFuelResource( ++extern "C" IGNITION_GAZEBO_VISIBLE const char *findFuelResource( + char *_pathToResource); + + #endif +diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc +index fbf01162bf..397441bed4 100644 +--- a/src/ign_TEST.cc ++++ b/src/ign_TEST.cc +@@ -59,8 +59,7 @@ std::string customExecStr(std::string _cmd) + } + + ///////////////////////////////////////////////// +-// See https://github.com/ignitionrobotics/ign-gazebo/issues/1175 +-TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(Server)) ++TEST(CmdLine, Server) + { + std::string cmd = kIgnCommand + " -r -v 4 --iterations 5 " + + std::string(PROJECT_SOURCE_PATH) + "/test/worlds/plugins.sdf"; +@@ -75,6 +74,9 @@ TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(Server)) + << output; + } + ++// Disable on WIN32 as on Windows it is not support to prepend ++// a command with the env variable to set ++#ifndef _WIN32 + // Use IGN_GAZEBO_RESOURCE_PATH instead of specifying the complete path + cmd = std::string("IGN_GAZEBO_RESOURCE_PATH=") + + PROJECT_SOURCE_PATH + "/test/worlds " + kIgnCommand + +@@ -89,10 +91,11 @@ TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(Server)) + EXPECT_NE(output.find("iteration " + std::to_string(i)), std::string::npos) + << output; + } ++#endif + } + + ///////////////////////////////////////////////// +-TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(CachedFuelWorld)) ++TEST(CmdLine, CachedFuelWorld) + { + std::string projectPath = std::string(PROJECT_SOURCE_PATH) + "/test/worlds"; + ignition::common::setenv("IGN_FUEL_CACHE_PATH", projectPath.c_str()); +@@ -106,7 +109,7 @@ TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(CachedFuelWorld)) + } + + ///////////////////////////////////////////////// +-TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(GazeboServer)) ++TEST(CmdLine, GazeboServer) + { + std::string cmd = kIgnCommand + " -r -v 4 --iterations 5 " + + std::string(PROJECT_SOURCE_PATH) + "/test/worlds/plugins.sdf"; +@@ -123,7 +126,7 @@ TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(GazeboServer)) + } + + ///////////////////////////////////////////////// +-TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(Gazebo)) ++TEST(CmdLine, Gazebo) + { + std::string cmd = kIgnCommand + " -r -v 4 --iterations 5 " + + std::string(PROJECT_SOURCE_PATH) + "/test/worlds/plugins.sdf"; +diff --git a/src/systems/CMakeLists.txt b/src/systems/CMakeLists.txt +index 303c6fc7d9..330b267f25 100644 +--- a/src/systems/CMakeLists.txt ++++ b/src/systems/CMakeLists.txt +@@ -82,10 +82,9 @@ function(gz_add_system system_name) + set(unversioned ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME_NO_VERSION_LOWER}-${system_name}${CMAKE_SHARED_LIBRARY_SUFFIX}) + if(WIN32) + # symlinks on Windows require admin priviledges, fallback to copy +- ADD_CUSTOM_COMMAND(TARGET ${system_target} POST_BUILD +- COMMAND "${CMAKE_COMMAND}" -E copy +- "$" +- "$/${unversioned}") ++ INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy ++ ${IGNITION_GAZEBO_PLUGIN_INSTALL_DIR}\/${versioned} ++ ${IGNITION_GAZEBO_PLUGIN_INSTALL_DIR}\/${unversioned})") + else() + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E create_symlink ${versioned} ${unversioned} WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 71bd2ab..184bfed 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -12,11 +12,11 @@ package: source: - url: https://github.com/ignitionrobotics/ign-{{ component_name }}/archive/ignition-{{ component_name }}{{ version }}.tar.gz sha256: 0c5036976b4811f18f3ea657ea3a738784e948449504f0a52b32bd7da9d7fe79 - patches: - - enable_win_ign.patch + patches: # [win] + - enable_win_ign.patch # [win] build: - number: 0 + number: 1 run_exports: - {{ pin_subpackage(name, max_pin='x') }} @@ -28,6 +28,7 @@ requirements: - cmake - pkg-config - ninja # [win] + - multisheller # [win] - {{ cdt('mesa-libgl-devel') }} # [linux] - {{ cdt('mesa-dri-drivers') }} # [linux] - {{ cdt('libselinux') }} # [linux]