diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt new file mode 100644 index 00000000..ab372aa7 --- /dev/null +++ b/THIRD-PARTY-NOTICES.txt @@ -0,0 +1,40 @@ +NOTICES AND INFORMATION +Do Not Translate or Localize + +This software incorporates material from third parties. +Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com, +or you may send a check or money order for US $5.00, including the product name, +the open source component name, platform, and version number, to: + +Source Code Compliance Team +Microsoft Corporation +One Microsoft Way +Redmond, WA 98052 +USA + +Notwithstanding any other terms, you may reverse engineer this software to the extent +required to debug changes to any libraries licensed under the GNU Lesser General Public License. + +libxml2 +======= + +Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. +Copyright (C) The Libxml2 Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/build/yaml/pipelines/build_images.yaml b/build/yaml/pipelines/build_images.yaml new file mode 100644 index 00000000..6f5cd251 --- /dev/null +++ b/build/yaml/pipelines/build_images.yaml @@ -0,0 +1,100 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# Build Pipeline: Linux Build Images +# Manually rebuilds and publishes the Ubuntu and Alpine images used by Linux CI. + +trigger: none +pr: none + +name: $(date:yyyyMMdd)$(rev:rr) + +parameters: +- name: ImageTag + displayName: Container image tag + type: string + default: latest +- name: RegistryServiceConnection + displayName: ACR Docker service connection + type: string + default: 'VS Diagnostics Dev (ProdDiagBuild)' + +variables: +- name: TeamName + value: ClrInstrumentationEngine + readonly: true +- name: ImageTag + value: ${{ parameters.ImageTag }} + readonly: true + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: + name: AzurePipelines-EO + image: 1ESPT-Ubuntu20.04 + os: linux + + stages: + - stage: BuildImages + displayName: Build Linux images + + jobs: + - job: BuildUbuntuImage + displayName: Build and publish Ubuntu image + + templateContext: + authenticatedContainerRegistries: + - serviceConnection: ${{ parameters.RegistryServiceConnection }} + + outputs: + - output: containerImage + image: proddiagbuild.azurecr.io/clrie-build-ubuntu:$(ImageTag) + targetPath: $(Build.ArtifactStagingDirectory) + artifactName: ubuntu-image + + steps: + - checkout: self + clean: true + + - task: 1ES.BuildContainerImage@1 + displayName: Build Ubuntu image + inputs: + image: proddiagbuild.azurecr.io/clrie-build-ubuntu:$(ImageTag) + path: $(Build.SourcesDirectory)/src/unix/docker/context + dockerfile: $(Build.SourcesDirectory)/src/unix/docker/dockerfiles/build/ubuntu/Dockerfile + enableNetwork: true + useBuildKit: true + + - job: BuildAlpineImage + displayName: Build and publish Alpine image + + templateContext: + authenticatedContainerRegistries: + - serviceConnection: ${{ parameters.RegistryServiceConnection }} + + outputs: + - output: containerImage + image: proddiagbuild.azurecr.io/clrie-build-alpine:$(ImageTag) + targetPath: $(Build.ArtifactStagingDirectory) + artifactName: alpine-image + + steps: + - checkout: self + clean: true + + - task: 1ES.BuildContainerImage@1 + displayName: Build Alpine image + inputs: + image: proddiagbuild.azurecr.io/clrie-build-alpine:$(ImageTag) + path: $(Build.SourcesDirectory)/src/unix/docker/context + dockerfile: $(Build.SourcesDirectory)/src/unix/docker/dockerfiles/build/alpine/Dockerfile + enableNetwork: true + useBuildKit: true diff --git a/build/yaml/steps/linux/binaries.yaml b/build/yaml/steps/linux/binaries.yaml index 07c31b80..e3d87421 100644 --- a/build/yaml/steps/linux/binaries.yaml +++ b/build/yaml/steps/linux/binaries.yaml @@ -13,12 +13,23 @@ steps: scriptLocation: inlineScript inlineScript: 'az acr login --name proddiagbuild' +# Restore vcpkg source and binary caches +- task: Cache@2 + displayName: Restore vcpkg cache + inputs: + key: '"vcpkg" | "$(Agent.OS)" | "$(Distro)" | src/vcpkg.json | src/unix/docker/context/components/vcpkg/cgmanifest.json' + restoreKeys: | + "vcpkg" | "$(Agent.OS)" | "$(Distro)" + path: $(Pipeline.Workspace)/vcpkg-cache + # Build binaries - task: Bash@3 displayName: Docker Build inputs: filePath: src/unix/docker/docker-build.sh arguments: $(Distro) $(Configuration) $(Platform) verbose + env: + VCPKG_CACHE_ROOT: $(Pipeline.Workspace)/vcpkg-cache # Cleanup containers - task: Bash@3 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b2baf39..b35f7929 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -365,6 +365,15 @@ add_library_pal(coreclrpal true ${CORECLR_PAL_ROOT}/lib/${CMAKE_BUILD_TYPE}/libc add_library_pal(palrt true ${CORECLR_PAL_ROOT}/lib/${CMAKE_BUILD_TYPE}/libpalrt.a) add_library_pal(corguids false ${CORECLR_PAL_ROOT}/lib/${CMAKE_BUILD_TYPE}/libcorguids.a) +if(CMAKE_SYSTEM_NAME STREQUAL Linux) + find_package(LibXml2 CONFIG REQUIRED) + target_link_options(LibXml2::LibXml2 INTERFACE + "LINKER:--exclude-libs,libxml2.a" + ) +else() + find_package(LibXml2 REQUIRED) +endif() + add_subdirectory(unix/src) add_subdirectory(unix/src/atl) add_subdirectory(Common.Lib) diff --git a/src/Common.Lib/CMakeLists.txt b/src/Common.Lib/CMakeLists.txt index 0ded00b4..81cbef2c 100644 --- a/src/Common.Lib/CMakeLists.txt +++ b/src/Common.Lib/CMakeLists.txt @@ -3,9 +3,8 @@ cmake_minimum_required(VERSION 3.14) project(Common.Lib) -find_package(LibXml2 REQUIRED) -include_directories(. ${LIBXML2_INCLUDE_DIR}) +include_directories(.) build_init(CPP Common.Lib) #note: we purposfully exclude windows-only files, @@ -28,4 +27,9 @@ add_lib(${PROJECT_NAME} ${src_files} ) +target_link_libraries(${PROJECT_NAME} + PUBLIC + LibXml2::LibXml2 +) + #target_compile_options(Common.Lib PUBLIC "-H") \ No newline at end of file diff --git a/src/InstrumentationEngine.Lib/CMakeLists.txt b/src/InstrumentationEngine.Lib/CMakeLists.txt index ad1843e1..6b48c406 100644 --- a/src/InstrumentationEngine.Lib/CMakeLists.txt +++ b/src/InstrumentationEngine.Lib/CMakeLists.txt @@ -3,9 +3,8 @@ cmake_minimum_required(VERSION 3.14) project(InstrumentationEngine.Lib) -find_package(LibXml2 REQUIRED) -include_directories(. ${LIBXML2_INCLUDE_DIR}) +include_directories(.) build_init(CPP InstrumentationEngine.Lib) @@ -30,4 +29,9 @@ add_lib(${PROJECT_NAME} true # use_redefines false # hide_symbols ${src_files} - ) \ No newline at end of file + ) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + LibXml2::LibXml2 +) \ No newline at end of file diff --git a/src/InstrumentationEngine.NuGet/InstrumentationEngine.nuspec b/src/InstrumentationEngine.NuGet/InstrumentationEngine.nuspec index b93b5be8..16e906e4 100644 --- a/src/InstrumentationEngine.NuGet/InstrumentationEngine.nuspec +++ b/src/InstrumentationEngine.NuGet/InstrumentationEngine.nuspec @@ -26,6 +26,7 @@ + diff --git a/src/InstrumentationEngine/CMakeLists.txt b/src/InstrumentationEngine/CMakeLists.txt index 7d4eeed9..6ab5a242 100644 --- a/src/InstrumentationEngine/CMakeLists.txt +++ b/src/InstrumentationEngine/CMakeLists.txt @@ -5,9 +5,7 @@ cmake_minimum_required(VERSION 2.8.12) project(InstrumentationEngine) -find_package(LibXml2 REQUIRED) - -include_directories(. ../InstrumentationEngine.Lib ${LIBXML2_INCLUDE_DIR}) +include_directories(. ../InstrumentationEngine.Lib) build_init(CPP InstrumentationEngine) @@ -90,7 +88,6 @@ endif() target_link_libraries(${PROJECT_NAME} pthread stdc++ - ${LIBXML2_LIBRARIES} ${CORECLRPAL} ${LINUXPAL} ${ATL} diff --git a/src/Tests/CommonLibTests/CMakeLists.txt b/src/Tests/CommonLibTests/CMakeLists.txt index 1e272b92..96287d3e 100644 --- a/src/Tests/CommonLibTests/CMakeLists.txt +++ b/src/Tests/CommonLibTests/CMakeLists.txt @@ -7,10 +7,9 @@ cmake_minimum_required(VERSION 3.14) fetch_google_test() project(Common.LibTests) -find_package(LibXml2 REQUIRED) # the midl directory is needed to replace the rpc headers referenced by midl generated headers. -include_directories(. ${REPOSITORY_ROOT}/src/unix/inc/midl ${REPOSITORY_ROOT}/src ${LIBXML2_INCLUDE_DIR}) +include_directories(. ${REPOSITORY_ROOT}/src/unix/inc/midl ${REPOSITORY_ROOT}/src) build_init(CPP Common.LibTests) @@ -29,7 +28,6 @@ add_executable( target_link_libraries( ${PROJECT_NAME} - ${LIBXML2_LIBRARIES} Common.Lib gtest_main ) diff --git a/src/Tests/InstrEngineTests/NaglerInstrumentationMethod/CMakeLists.txt b/src/Tests/InstrEngineTests/NaglerInstrumentationMethod/CMakeLists.txt index fc94ca72..9d7b4609 100644 --- a/src/Tests/InstrEngineTests/NaglerInstrumentationMethod/CMakeLists.txt +++ b/src/Tests/InstrEngineTests/NaglerInstrumentationMethod/CMakeLists.txt @@ -4,9 +4,8 @@ cmake_minimum_required(VERSION 3.14) project(NaglerInstrumentationEngine) -find_package(LibXml2 REQUIRED) -include_directories(. ${REPOSITORY_ROOT}/src ${LIBXML2_INCLUDE_DIR}) +include_directories(. ${REPOSITORY_ROOT}/src) # don't use the PAL for tests build_init(CPP InstrumentationEngine) @@ -47,7 +46,6 @@ target_link_libraries( ${PROJECT_NAME} pthread stdc++ - ${LIBXML2_LIBRARIES} Common.Lib ) diff --git a/src/Tests/InstrumentationEngineLibTests/CMakeLists.txt b/src/Tests/InstrumentationEngineLibTests/CMakeLists.txt index c08989b6..a85cb400 100644 --- a/src/Tests/InstrumentationEngineLibTests/CMakeLists.txt +++ b/src/Tests/InstrumentationEngineLibTests/CMakeLists.txt @@ -7,9 +7,8 @@ cmake_minimum_required(VERSION 3.14) fetch_google_test() project(InstrumentationEngine.LibTests) -find_package(LibXml2 REQUIRED) -include_directories(. ${REPOSITORY_ROOT}/src ${LIBXML2_INCLUDE_DIR}) +include_directories(. ${REPOSITORY_ROOT}/src) # don't use the PAL for tests build_init(CPP InstrumentationEngine.LibTests) @@ -58,7 +57,6 @@ target_link_libraries( ${PROJECT_NAME} pthread stdc++ - ${LIBXML2_LIBRARIES} ${CORECLRPAL} ${LINUXPAL} ${ATL} diff --git a/src/build.sh b/src/build.sh index 6e695f67..15fcb77b 100755 --- a/src/build.sh +++ b/src/build.sh @@ -134,12 +134,10 @@ get_cmake() echo "found cmake version $cmakeVersion" cmakeMajor=$(echo $cmakeVersion | sed 's/^.*[^0-9]\([0-9]*\)\..*$/\1'/) cmakeMinor=$(echo $cmakeVersion | sed 's/^.*[^0-9]*\.\([0-9]*\)\..*$/\1'/) - if (( $cmakeMajor > 3 )); then - if (( $cmakeMinor >= 14 )); then - # found sufficient cmake, continue. - echo $cmakeLocation - return - fi + if (( $cmakeMajor > 3 || ($cmakeMajor == 3 && $cmakeMinor >= 14) )); then + # found sufficient cmake, continue. + echo $cmakeLocation + return fi echo "Insufficient cmake version. Ensure cmake version 3.14 or later is installed" @@ -190,6 +188,10 @@ locate_build_tools() cmake_extra_defines="$cmake_extra_defines -DCLR_CMAKE_LINUX_ID=$ID" fi + if [[ -n "$__VcpkgInstalledDir" ]]; then + cmake_extra_defines="$cmake_extra_defines -DCMAKE_PREFIX_PATH=$__VcpkgInstalledDir/$__VcpkgTriplet" + fi + locate_google_test $echo "found google version '$__GoogleTestTag' test at '$__GoogleTestUrl'" } @@ -359,6 +361,47 @@ restore_build_dependencies() fi } +restore_vcpkg_dependencies() +{ + if [ -z "$VCPKG_ROOT" ] || [ ! -x "$VCPKG_ROOT/vcpkg" ]; then + echo "ERROR: VCPKG_ROOT must point to a bootstrapped vcpkg installation." + exit 1 + fi + + __VcpkgInstalledDir="$__IntermediatesDir/vcpkg_installed" + __VcpkgTriplet=x64-linux + + "$VCPKG_ROOT/vcpkg" install \ + --x-manifest-root="$EnlistmentRoot/src" \ + --x-install-root="$__VcpkgInstalledDir" \ + --triplet="$__VcpkgTriplet" \ + --clean-after-build + + if [ $? -ne 0 ]; then + echo "ERROR: vcpkg dependency restore failed." + exit 1 + fi +} + +configure_vcpkg_cache() +{ + local cacheRoot="${VCPKG_CACHE_ROOT:-$EnlistmentRoot/out/vcpkg-cache}" + + mkdir -p "$cacheRoot/assets" "$cacheRoot/archives" + if [ $? -ne 0 ]; then + echo "ERROR: Unable to create vcpkg cache at '$cacheRoot'." + exit 1 + fi + + if [ -z "$X_VCPKG_ASSET_SOURCES" ]; then + export X_VCPKG_ASSET_SOURCES="clear;x-azurl,file://$cacheRoot/assets/,,readwrite" + fi + + if [ -z "$VCPKG_BINARY_SOURCES" ]; then + export VCPKG_BINARY_SOURCES="clear;files,$cacheRoot/archives,readwrite" + fi +} + # Set default clang version set_clang_path_and_version() { @@ -570,6 +613,10 @@ setup_dirs check_prereqs restore_build_dependencies +if [ "$OSName" == "Linux" ]; then + configure_vcpkg_cache + restore_vcpkg_dependencies +fi pwd diff --git a/src/unix/docker/context/components/cmake/cgmanifest.json b/src/unix/docker/context/components/cmake/cgmanifest.json index 53febb0a..077ad2c2 100644 --- a/src/unix/docker/context/components/cmake/cgmanifest.json +++ b/src/unix/docker/context/components/cmake/cgmanifest.json @@ -6,9 +6,9 @@ "Type": "other", "other": { "Name": "cmake", - "Version": "3.20.2", - "DownloadUrl": " https://github.com/Kitware/CMake/releases/download/v3.20.2/cmake-3.20.2.tar.gz", - "SHA256CHECK": "aecf6ecb975179eb3bb6a4a50cae192d41e92b9372b02300f9e8f1d5f559544e" + "Version": "3.31.10", + "DownloadUrl": "https://github.com/Kitware/CMake/releases/download/v3.31.10/cmake-3.31.10.tar.gz", + "SHA256CHECK": "cf06fadfd6d41fa8e1ade5099e54976d1d844fd1487ab99942341f91b13d3e29" } }, "DevelopmentDependency": true diff --git a/src/unix/docker/context/components/vcpkg/cgmanifest.json b/src/unix/docker/context/components/vcpkg/cgmanifest.json new file mode 100644 index 00000000..a5f31485 --- /dev/null +++ b/src/unix/docker/context/components/vcpkg/cgmanifest.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/component-detection-manifest.json", + "Registrations": [ + { + "Component": { + "Type": "git", + "git": { + "RepositoryUrl": "https://github.com/microsoft/vcpkg", + "CommitHash": "2d318737bc7daa8a872f4469955a0559686f7580" + } + }, + "DevelopmentDependency": true + } + ] +} diff --git a/src/unix/docker/docker-build.sh b/src/unix/docker/docker-build.sh index 03967a7c..e96e76c4 100644 --- a/src/unix/docker/docker-build.sh +++ b/src/unix/docker/docker-build.sh @@ -104,6 +104,23 @@ invoke_build() fi docker_run_args="$docker_run_args -v $LocalBuildPath:/root/ClrInstrumentationEngine/build:ro" + local VcpkgCachePath="${VCPKG_CACHE_ROOT:-${TMPDIR:-/tmp}/clrie-vcpkg-cache}" + mkdir -p "$VcpkgCachePath" + if [ $? -ne 0 ]; then + echo "ERROR: failed to create vcpkg cache at '$VcpkgCachePath'." + exit 1 + fi + docker_run_args="$docker_run_args -v $VcpkgCachePath:/root/ClrInstrumentationEngine/out/vcpkg-cache" + docker_run_args="$docker_run_args --env VCPKG_CACHE_ROOT=/root/ClrInstrumentationEngine/out/vcpkg-cache" + + if [[ -n "$X_VCPKG_ASSET_SOURCES" ]]; then + docker_run_args="$docker_run_args --env X_VCPKG_ASSET_SOURCES" + fi + + if [[ -n "$VCPKG_BINARY_SOURCES" ]]; then + docker_run_args="$docker_run_args --env VCPKG_BINARY_SOURCES" + fi + build_cmd="bash /root/ClrInstrumentationEngine/src/build.sh $__BuildArch $__BuildType clean $__UnprocessedBuildArgs" docker_run_args="$docker_run_args --net=host $__DockerImage $build_cmd" diff --git a/src/unix/docker/dockerfiles/build/alpine/Dockerfile b/src/unix/docker/dockerfiles/build/alpine/Dockerfile index cdbf73d8..c620f81e 100644 --- a/src/unix/docker/dockerfiles/build/alpine/Dockerfile +++ b/src/unix/docker/dockerfiles/build/alpine/Dockerfile @@ -35,11 +35,14 @@ RUN wget -O dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DOTNET && dotnet help # CLR Instrumentation Engine Build Prerequisites -RUN apk update \ - && apk add --no-cache libxml2-dev - -# Add jq to make it easer to read json in shell scripts -RUN apk add --no-cache jq +RUN apk add --no-cache \ + git \ + jq \ + ninja \ + patchelf \ + pkgconf \ + unzip \ + zip # Install newer version of cmake. We need to run make commands inside the directory # that it is extracted to, so WORKDIR is the easiest context to use. @@ -62,4 +65,18 @@ RUN cmakeurl=$(cat cgmanifest.json | jq '.Registrations[0].Component.other.Downl # Delete the cmake installer it is no longer needed. WORKDIR / -RUN rm -rf /usr/share/cmakeinst \ No newline at end of file +RUN rm -rf /usr/share/cmakeinst + +ENV VCPKG_ROOT=/opt/vcpkg +ENV VCPKG_FORCE_SYSTEM_BINARIES=1 +ENV PATH="$VCPKG_ROOT:$PATH" + +COPY "components/vcpkg/cgmanifest.json" /tmp/vcpkg-cgmanifest.json +RUN vcpkg_repo=$(jq -r '.Registrations[0].Component.git.RepositoryUrl' /tmp/vcpkg-cgmanifest.json) \ + && vcpkg_commit=$(jq -r '.Registrations[0].Component.git.CommitHash' /tmp/vcpkg-cgmanifest.json) \ + && git init "$VCPKG_ROOT" \ + && git -C "$VCPKG_ROOT" remote add origin "$vcpkg_repo" \ + && git -C "$VCPKG_ROOT" fetch --depth 1 origin "$vcpkg_commit" \ + && git -C "$VCPKG_ROOT" checkout --detach FETCH_HEAD \ + && "$VCPKG_ROOT/bootstrap-vcpkg.sh" -disableMetrics \ + && rm /tmp/vcpkg-cgmanifest.json \ No newline at end of file diff --git a/src/unix/docker/dockerfiles/build/ubuntu/Dockerfile b/src/unix/docker/dockerfiles/build/ubuntu/Dockerfile index ddf5f670..6c62322b 100644 --- a/src/unix/docker/dockerfiles/build/ubuntu/Dockerfile +++ b/src/unix/docker/dockerfiles/build/ubuntu/Dockerfile @@ -68,9 +68,25 @@ RUN apt-get update \ clang-3.9 \ cmake \ git \ - libxml2-dev \ make \ - jq + jq \ + ninja-build \ + pkg-config \ + unzip \ + zip + +ENV VCPKG_ROOT=/opt/vcpkg +ENV PATH="$VCPKG_ROOT:$PATH" + +COPY "components/vcpkg/cgmanifest.json" /tmp/vcpkg-cgmanifest.json +RUN vcpkg_repo=$(jq -r '.Registrations[0].Component.git.RepositoryUrl' /tmp/vcpkg-cgmanifest.json) \ + && vcpkg_commit=$(jq -r '.Registrations[0].Component.git.CommitHash' /tmp/vcpkg-cgmanifest.json) \ + && git init "$VCPKG_ROOT" \ + && git -C "$VCPKG_ROOT" remote add origin "$vcpkg_repo" \ + && git -C "$VCPKG_ROOT" fetch --depth 1 origin "$vcpkg_commit" \ + && git -C "$VCPKG_ROOT" checkout --detach FETCH_HEAD \ + && "$VCPKG_ROOT/bootstrap-vcpkg.sh" -disableMetrics \ + && rm /tmp/vcpkg-cgmanifest.json # Git now checks for repository ownership RUN git config --global --add safe.directory /root/ClrInstrumentationEngine/out/Linux/Intermediate/x64.Debug/_deps/googletest-src diff --git a/src/vcpkg.json b/src/vcpkg.json new file mode 100644 index 00000000..6f1fd513 --- /dev/null +++ b/src/vcpkg.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "name": "clr-instrumentation-engine-native-dependencies", + "version-string": "1.0", + "builtin-baseline": "2d318737bc7daa8a872f4469955a0559686f7580", + "dependencies": [ + { + "name": "libxml2", + "default-features": false, + "features": [ + "iconv" + ] + } + ] +}