Add support for SourceLink for msquic (#591)

This commit is contained in:
Thad House 2020-07-17 15:20:22 -07:00 коммит произвёл GitHub
Родитель e9bba6d8a7
Коммит 3d0bfc60cf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 283 добавлений и 10 удалений

Просмотреть файл

@ -19,6 +19,8 @@ jobs:
steps:
- checkout: self
submodules: recursive
${{ if eq(parameters.platform, 'windows') }}:
path: msquic
- task: ShellScript@2
displayName: Install Powershell
@ -39,7 +41,7 @@ jobs:
inputs:
pwsh: true
filePath: scripts/build.ps1
arguments: -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} -Platform ${{ parameters.platform }} ${{ parameters.extraBuildArgs }}
arguments: -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} -Platform ${{ parameters.platform }} ${{ parameters.extraBuildArgs }} -CI
- task: PowerShell@2
displayName: Build Source Code (Release)
@ -47,6 +49,6 @@ jobs:
inputs:
pwsh: true
filePath: scripts/build.ps1
arguments: -Config Release -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} -Platform ${{ parameters.platform }} ${{ parameters.extraBuildArgs }}
arguments: -Config Release -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} -Platform ${{ parameters.platform }} ${{ parameters.extraBuildArgs }} -CI
- template: ./upload-artifacts.yml

Просмотреть файл

@ -11,6 +11,12 @@ jobs:
steps:
- checkout: self
submodules: recursive
path: msquic
- task: NuGetCommand@2
displayName: Nuget Restore
inputs:
restoreSolution: msquic.kernel.sln
- task: VSBuild@1
inputs:

Просмотреть файл

@ -9,6 +9,8 @@ FATAL: In-source builds are not allowed.
")
endif()
message(STATUS "CMAKE Version: ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@ -49,22 +51,26 @@ else()
# Setup for Install. We set this up in here rather then in the main library folder for future use.
# i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH FALSE)
#set(CMAKE_SKIP_BUILD_RPATH FALSE)
# When building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
#set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/msquic/lib")
# Azure is not liking this argument. I think its a bug in their configuration
# Once this is fixed, also fix the shim in build-config-user.yml
#set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
#set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/msquic/lib")
# Add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# The RPATH to be used when installing, but only if it's not a system directory
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/msquic/lib" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/msquic/lib")
#set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/msquic/lib")
endif("${isSystemDir}" STREQUAL "-1")
set(msquic_dest msquic)
@ -91,6 +97,8 @@ option(QUIC_SANITIZE_ADDRESS "Enables address sanitizer" OFF)
option(QUIC_STATIC_LINK_CRT "Statically links the C runtime" ON)
option(QUIC_UWP_BUILD "Build for UWP" OFF)
option(QUIC_PGO "Enables profile guided optimizations" OFF)
option(QUIC_SOURCE_LINK "Enables source linking on MSVC" ON)
option(QUIC_CI "Enable CI specific flags" OFF)
# FindLTTngUST does not exist before CMake 3.6, so disable logging for older cmake versions
if (${CMAKE_VERSION} VERSION_LESS "3.6.0")
@ -106,6 +114,27 @@ elseif ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Darwin")
set(QUIC_PLATFORM "darwin")
endif()
if (QUIC_CI)
if (MSVC)
file(READ ${CMAKE_CURRENT_LIST_DIR}/cmake/PdbAltPath.txt PDBALTPATH)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PDBALTPATH}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PDBALTPATH}")
message(STATUS ${CMAKE_EXE_LINKER_FLAGS})
endif()
if (QUIC_SOURCE_LINK AND MSVC)
if ("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL "19.20")
include(${PROJECT_SOURCE_DIR}/cmake/SourceLink.cmake)
file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/source_link.json" SOURCE_LINK_JSON)
source_link(${PROJECT_SOURCE_DIR} ${SOURCE_LINK_JSON})
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SOURCELINK:${SOURCE_LINK_JSON}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /SOURCELINK:${SOURCE_LINK_JSON}")
else()
message(WARNING "Disabling SourceLink due to old version of MSVC. Please update to VS2019!")
endif()
endif()
endif()
set(QUIC_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(QUIC_OUTPUT_DIR ${QUIC_BUILD_DIR}/bin/$<IF:$<CONFIG:Debug>,Debug,Release> CACHE STRING "Output directory for build artifacts")

87
cmake/GitCommands.cmake Normal file
Просмотреть файл

@ -0,0 +1,87 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
find_package(Git REQUIRED QUIET)
if (NOT Git_FOUND)
message(FATAL_ERROR "Unable to find git, which is needed for versioning")
endif()
function(get_git_dir DIRECTORY OUTPUT_VAR)
execute_process(
COMMAND
${GIT_EXECUTABLE} rev-parse --git-dir
WORKING_DIRECTORY
${DIRECTORY}
RESULT_VARIABLE
GIT_DIR_RESULT
OUTPUT_VARIABLE
GIT_DIR_OUTPUT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Allow to fail
set(${OUTPUT_VAR} ${GIT_DIR_OUTPUT} PARENT_SCOPE)
endfunction()
function(get_git_current_hash DIRECTORY OUTPUT_VAR)
execute_process(
COMMAND
${GIT_EXECUTABLE} rev-parse --verify HEAD
WORKING_DIRECTORY
${DIRECTORY}
RESULT_VARIABLE
GIT_CURRENT_HASH_RESULT
OUTPUT_VARIABLE
GIT_CURRENT_HASH_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (NOT ("${GIT_CURRENT_HASH_RESULT}" STREQUAL "0"))
message(${GIT_CURRENT_HASH_OUTPUT})
message(FATAL_ERROR "Failed to get ${DIRECTORY} git hash")
endif()
set(${OUTPUT_VAR} ${GIT_CURRENT_HASH_OUTPUT} PARENT_SCOPE)
endfunction()
function(get_git_remote_url DIRECTORY OUTPUT_VAR)
execute_process(
COMMAND
${GIT_EXECUTABLE} config --get remote.origin.url
RESULT_VARIABLE
GIT_REMOTE_URL_RESULT
OUTPUT_VARIABLE
GIT_REMOTE_URL_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY
${DIRECTORY}
)
if (NOT ("${GIT_REMOTE_URL_RESULT}" STREQUAL "0"))
message(${GIT_REMOTE_URL_OUTPUT})
message(FATAL_ERROR "Failed to get ${DIRECTORY} git remote")
endif()
set(${OUTPUT_VAR} ${GIT_REMOTE_URL_OUTPUT} PARENT_SCOPE)
endfunction()
function(run_git_submodule_foreach CMD DIRECTORY OUTPUT_VALUE)
execute_process(
COMMAND
${GIT_EXECUTABLE} submodule foreach --quiet --recursive "${CMD}"
RESULT_VARIABLE
GIT_SUBMODULE_CMD_RESULT
OUTPUT_VARIABLE
GIT_SUBMODULE_CMD_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY
${DIRECTORY}
)
if (NOT ("${GIT_SUBMODULE_CMD_RESULT}" STREQUAL "0"))
message(${GIT_SUBMODULE_CMD_OUTPUT})
message(FATAL_ERROR "Failed to run git submodule foreach command: ${CMD} in ${DIRECTORY}")
endif()
set(${OUTPUT_VALUE} ${GIT_SUBMODULE_CMD_OUTPUT} PARENT_SCOPE)
endfunction()

1
cmake/PdbAltPath.txt Normal file
Просмотреть файл

@ -0,0 +1 @@
/PDBALTPATH:%_PDB%

106
cmake/SourceLink.cmake Normal file
Просмотреть файл

@ -0,0 +1,106 @@
# CMake Module to generate Source Link JSON for the MSVC compiler
#
# Microsoft defines Source Link as the following:
#
# > Source Link is a developer productivity feature that allows unique
# > information about an assembly's original source code to be embedded in its
# > PDB during compilation.
# https://github.com/dotnet/designs/blob/master/accepted/diagnostics/source-link.md
#
# Specifically, this script will embedded information into the PDB of where to
# download the source code from. This will allow developers to use the PDB without
# the source located on disk.
#
# This script currently only works with GitHub but could be extended to support
# other source control servers. Any server which hosts their code as raw source
# over HTTP should work.
#
include(${CMAKE_CURRENT_LIST_DIR}/GitCommands.cmake)
# Warn if this is included and the compilier doesn't support source link
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if ("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL "19.20")
# Good to go!
elseif("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL "19.14")
message(STATUS "SourceLink enabled but case insensative")
else()
message(WARNING "SourceLink will not work on version of MSVC less than 19.14")
endif()
else()
message(WARNING "SourceLink will not work on the ${CMAKE_C_COMPILER_ID} compiler")
endif()
# REPO_ROOT is the path to the repository where code it stored.
#
# SOURCE_LINK_JSON_PATH is the file to output the json
function(source_link REPO_ROOT SOURCE_LINK_JSON_PATH)
if (NOT (IS_DIRECTORY ${REPO_ROOT}))
message(FATAL_ERROR "\"${REPO_ROOT}\" is not a directory")
endif()
get_git_remote_url(${REPO_ROOT} GIT_REMOTE)
get_git_current_hash(${REPO_ROOT} GIT_CURRENT_HASH)
build_source_link_rule(${REPO_ROOT} ${GIT_REMOTE} ${GIT_CURRENT_HASH} ROOT_RULE)
set(SOURCE_LINK_RULES)
list(APPEND SOURCE_LINK_RULES ${ROOT_RULE})
# Also build rules for submodules
run_git_submodule_foreach("echo $displaypath,$sha1,`git config --get remote.origin.url`" ${REPO_ROOT} SUBMODULE_INFO)
if (NOT ("${SUBMODULE_INFO}" STREQUAL ""))
# Turn output of new lines into a CMake list
string(REPLACE "\r\n" ";" SUBMODULE_INFO ${SUBMODULE_INFO})
string(REPLACE "\n" ";" SUBMODULE_INFO ${SUBMODULE_INFO})
foreach(ITEM ${SUBMODULE_INFO})
# Turn each line into a list of path;hash;url
string(REPLACE "," ";" SUBMODULE ${ITEM})
list(GET SUBMODULE 0 LOCAL_PATH)
list(GET SUBMODULE 1 CURRENT_HASH)
list(GET SUBMODULE 2 REMOTE)
string(CONCAT LOCAL_PATH "${REPO_ROOT}/" ${LOCAL_PATH})
build_source_link_rule(${LOCAL_PATH} ${REMOTE} ${CURRENT_HASH} RULE)
list(APPEND SOURCE_LINK_RULES ${RULE})
endforeach()
endif()
set(OUTPUT)
string(APPEND OUTPUT "{\n")
string(APPEND OUTPUT "\"documents\": {\n")
string(JOIN ",\n" EXPANDED_RULES ${SOURCE_LINK_RULES})
string(APPEND OUTPUT "${EXPANDED_RULES}\n")
string(APPEND OUTPUT "}\n")
string(APPEND OUTPUT "}\n")
file(WRITE ${SOURCE_LINK_JSON_PATH} ${OUTPUT})
endfunction()
function(build_source_link_rule LOCAL_PATH GIT_REMOTE GIT_CURRENT_HASH OUTPUT)
# Verify local path exists
if (NOT (IS_DIRECTORY ${LOCAL_PATH}))
message(FATAL_ERROR "${LOCAL_PATH} is not a directory")
endif()
# Change local path to native path
file(TO_NATIVE_PATH "${LOCAL_PATH}/*" LOCAL_PATH)
# Escape any backslashes for JSON
string(REPLACE "\\" "\\\\" LOCAL_PATH ${LOCAL_PATH})
# Verify this is a GitHub URL
# In the future we could support other source servers but currently they
# are not supported
if (NOT ("${GIT_REMOTE}" MATCHES "https://github\\.com"))
message(STATUS "Unable to sourcelink remote: \"${GIT_REMOTE}\". Unknown host")
return()
endif()
string(REPLACE ".git" "" RAW_GIT_URL ${GIT_REMOTE})
string(REPLACE "github.com" "raw.githubusercontent.com" RAW_GIT_URL ${RAW_GIT_URL})
string(CONCAT RAW_GIT_URL ${RAW_GIT_URL} "/${GIT_CURRENT_HASH}/*")
set(${OUTPUT} "\"${LOCAL_PATH}\" : \"${RAW_GIT_URL}\"" PARENT_SCOPE)
endfunction(build_source_link_rule)

0
cmake/rpath.txt Normal file
Просмотреть файл

Просмотреть файл

@ -48,6 +48,9 @@ This script provides helpers for building msquic.
.PARAMETER Generator
Specifies a specific cmake generator (Only supported on unix)
.PARAMETER CI
Specifies that this is a CI build. This enables certain flags in the build, currently PDBALTPATH
.EXAMPLE
build.ps1
@ -101,7 +104,10 @@ param (
[switch]$PGO = $false,
[Parameter(Mandatory = $false)]
[string]$Generator = ""
[string]$Generator = "",
[Parameter(Mandatory = $false)]
[switch]$CI = $false
)
Set-StrictMode -Version 'Latest'
@ -111,7 +117,7 @@ if ($Generator -eq "") {
if ($IsWindows) {
$Generator = "Visual Studio 16 2019"
} elseif ($IsLinux) {
$Generator = "Linux Makefiles"
$Generator = "Ninja"
} else {
$Generator = "Unix Makefiles"
}
@ -223,6 +229,9 @@ function CMake-Generate {
if ($ToolchainFile -ne "") {
$Arguments += " ""-DCMAKE_TOOLCHAIN_FILE=" + $ToolchainFile + """"
}
if ($CI) {
$Arguments += " -DQUIC_CI=ON"
}
$Arguments += " ../../.."
CMake-Execute $Arguments
@ -246,6 +255,8 @@ function CMake-Build {
}
if ($IsWindows) {
$Arguments += " --config " + $Config
} else {
$Arguments += " -- VERBOSE=1"
}
CMake-Execute $Arguments

Просмотреть файл

@ -38,7 +38,7 @@ target_include_directories(msquic PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../inc>
$<INSTALL_INTERFACE:${include_dest}>)
set(PUBLIC_HEADERS
set(PUBLIC_HEADERS
../inc/msquic.h
../inc/msquic_winuser.h
../inc/msquic_linux.h

Просмотреть файл

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.props')" />
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props')" />
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props')" />
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -116,11 +120,31 @@
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<PropertyGroup>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.targets')" />
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.targets')" />
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets')" />
<Import Project="..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.AzureRepos.Git.1.0.0\build\Microsoft.SourceLink.AzureRepos.Git.targets'))" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Build.Tasks.Git" version="1.0.0" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.SourceLink.AzureRepos.Git" version="1.0.0" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.SourceLink.Common" version="1.0.0" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.SourceLink.GitHub" version="1.0.0" targetFramework="native" developmentDependency="true" />
</packages>