Ask Mode: Xplat symbol stripping (dotnet/core-setup#2476)
authorchcosta <chcosta@microsoft.com>
Mon, 22 May 2017 22:29:52 +0000 (15:29 -0700)
committerGitHub <noreply@github.com>
Mon, 22 May 2017 22:29:52 +0000 (15:29 -0700)
* Strip xplat symbols and repackage (dotnet/core-setup#2430)

* Staging xplay sym stripping

* Symbols are being stripped, need to package them

* Package xplat symbols

* Add _.pdb placeholder

* Strip symbols for apphost and dotnet

* Use tools version of pdb placeholder

* Strip xplat symbols and repackage

* Update official builds

* Add EOF newlines

* Remove debug message

* Move cmakeoutput path properties

* Add symbol stripping to ci release x64 unix builds (dotnet/core-setup#2436)

* Add symbol stripping to ci release unix builds

* Exclude armel from symstrip

* Only strip symbols on x64

* switch back to enabling arm builds, they should be strippable

* Enable symstrip for arm

Commit migrated from https://github.com/dotnet/core-setup/commit/58e8d097e513ba1e303d59828d1701f99dd6bf4c

16 files changed:
src/installer/buildpipeline/pipeline.json
src/installer/config.json
src/installer/corehost/CMakeLists.txt
src/installer/corehost/build.proj
src/installer/corehost/build.sh
src/installer/corehost/cli/dll/CMakeLists.txt
src/installer/corehost/cli/exe/apphost/CMakeLists.txt
src/installer/corehost/cli/exe/dotnet/CMakeLists.txt
src/installer/corehost/cli/fxr/CMakeLists.txt
src/installer/dir.props
src/installer/netci.groovy
src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props
src/installer/pkg/projects/Microsoft.NETCore.DotNetHost/runtime.Windows_NT.Microsoft.NETCore.DotNetHost.props
src/installer/pkg/projects/Microsoft.NETCore.DotNetHostPolicy/runtime.Windows_NT.Microsoft.NETCore.DotNetHostPolicy.props
src/installer/pkg/projects/Microsoft.NETCore.DotNetHostResolver/runtime.Windows_NT.Microsoft.NETCore.DotNetHostResolver.props
src/installer/pkg/projects/dir.targets

index 5b40fe3..21bca77 100644 (file)
@@ -20,7 +20,7 @@
           "Parameters": {
             "PB_DistroRid": "rhel.7.2-x64",
             "PB_DockerTag": "rhel7_prereqs_2",
-            "PB_AdditionalBuildArguments":"-PortableBuild=true",
+            "PB_AdditionalBuildArguments":"-PortableBuild=true -strip-symbols",
             "PB_PortableBuild": "true"
           },
           "ReportingParameters": {
@@ -36,7 +36,7 @@
             "PB_DistroRid": "ubuntu.14.04-arm", 
             "PB_DockerTag": "ubuntu-14.04-cross-0cd4667-20172211042239", 
             "PB_TargetArchitecture": "arm", 
-            "PB_AdditionalBuildArguments":"-TargetArchitecture=arm -DistroRid=linux-arm -DisableCrossgen=true -PortableBuild=true -SkipTests=true -CrossBuild=true",
+            "PB_AdditionalBuildArguments":"-TargetArchitecture=arm -DistroRid=linux-arm -DisableCrossgen=true -PortableBuild=true -SkipTests=true -CrossBuild=true -strip-symbols",
             "PB_CrossBuildArgs": "-e ROOTFS_DIR ",
             "PB_PortableBuild": "true" 
           }, 
@@ -50,7 +50,7 @@
         {
           "Name": "Core-Setup-OSX-BT",
           "Parameters": {
-            "PB_PortableBuildArg": "-PortableBuild=true",
+            "PB_PortableBuildArg": "-PortableBuild=true -strip-symbols",
             "PB_PortableBuild": "true"
           },
           "ReportingParameters": {
index 28ea6a0..a77c8f1 100644 (file)
       "values": [],
       "defaultValue": "/flp:v=normal"
     },
+    "StripSymbols": {
+      "description": "Pass additional argument to native build to configure symbol stripping.",
+      "valueType": "property",
+      "values": ["true", "false"],
+      "defaultValue": false
+    },    
     "Project": {
       "description": "Project where the commands are going to be applied.",
       "valueType": "passThrough",
           "settings": {
             "DisableCrossgen": "true"
           }
+        },
+        "strip-symbols": {
+          "description": "Strip native symbols.",
+          "settings": {
+            "StripSymbols": true
+          }
         }
       },
       "defaultValues":{
index 0a76ce4..456aa04 100644 (file)
@@ -1,2 +1,126 @@
 cmake_minimum_required (VERSION 2.6)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    message("System name Linux")
+endif(CMAKE_SYSTEM_NAME STREQUAL Linux)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    message("System name Darwin")
+endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    add_definitions(-D_BSD_SOURCE) # required for getline
+    message("System name FreeBSD")
+endif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    message("System name OpenBSD")
+endif(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    message("System name NetBSD")
+endif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL SunOS)
+    set(CLR_CMAKE_PLATFORM_UNIX 1)
+    message("System name SunOS")
+endif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
+
+if (NOT WIN32)
+    if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+        # Ensure that dsymutil and strip are present
+        find_program(DSYMUTIL dsymutil)
+        if (DSYMUTIL STREQUAL "DSYMUTIL-NOTFOUND")
+            message(FATAL_ERROR "dsymutil not found")
+        endif()
+
+        find_program(STRIP strip)
+        if (STRIP STREQUAL "STRIP-NOTFOUND")
+            message(FATAL_ERROR "strip not found")
+        endif()
+    else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+        # Ensure that objcopy is present
+        if(DEFINED ENV{ROOTFS_DIR})
+            if(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+                find_program(OBJCOPY ${TOOLCHAIN}-objcopy)
+            else()
+                message(FATAL_ERROR "Only AMD64, X86, ARM64 and ARM are supported")
+            endif()
+        else()
+            find_program(OBJCOPY objcopy)
+        endif()
+        if (OBJCOPY STREQUAL "OBJCOPY-NOTFOUND" AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+            message(FATAL_ERROR "objcopy not found")
+        endif()
+    endif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+endif ()
+
+function(strip_symbols targetName outputFilename)
+    if(CLR_CMAKE_PLATFORM_UNIX)
+        if(STRIP_SYMBOLS)
+
+            # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
+            # generator expression doesn't work correctly returning the wrong path and on
+            # the newer cmake versions the LOCATION property isn't supported anymore.
+            if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
+                set(strip_source_file $<TARGET_FILE:${targetName}>)
+            else()
+                get_property(strip_source_file TARGET ${targetName} PROPERTY LOCATION)
+            endif()
+
+            if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+                set(strip_destination_file ${strip_source_file}.dwarf)
+
+                add_custom_command(
+                    TARGET ${targetName}
+                    POST_BUILD
+                    VERBATIM 
+                    COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
+                    COMMAND ${STRIP} -u -r ${strip_source_file}
+                    COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
+                )
+            else(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+                set(strip_destination_file ${strip_source_file}.dbg)
+
+                add_custom_command(
+                    TARGET ${targetName}
+                    POST_BUILD
+                    VERBATIM 
+                    COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
+                    COMMAND ${OBJCOPY} --strip-unneeded ${strip_source_file}
+                    COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
+                    COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
+                )
+            endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+            set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
+        endif(STRIP_SYMBOLS)
+    endif(CLR_CMAKE_PLATFORM_UNIX)
+endfunction()
+
+function(install_library_and_symbols targetName)
+    strip_symbols(${targetName} strip_destination_file)
+
+    # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
+    # generator expression doesn't work correctly returning the wrong path and on
+    # the newer cmake versions the LOCATION property isn't supported anymore.
+    if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
+        set(install_source_file $<TARGET_FILE:${targetName}>)
+    else()
+        get_property(install_source_file TARGET ${targetName} PROPERTY LOCATION)
+    endif()
+
+    install(PROGRAMS ${install_source_file} DESTINATION .)
+    if(WIN32)
+        install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION PDB)
+    else()
+        install(FILES ${strip_destination_file} DESTINATION .)
+    endif()
+endfunction()
+
 add_subdirectory(cli)
index bd20b95..3d480e0 100644 (file)
           Condition="'$(OSGroup)' != 'Windows_NT'"
           DependsOnTargets="GetLatestCommitHash">
     <PropertyGroup>
+      <CMakeBuildDir>$(IntermediateOutputRootPath)corehost\cmake\</CMakeBuildDir>
+      <DotNetHostFxrPath>$(CMakeBuildDir)cli\fxr\$(DotnetHostFxrBaseName)</DotNetHostFxrPath>
+      <HostPolicyPath>$(CMakeBuildDir)cli\dll\$(HostPolicyBaseName)</HostPolicyPath>
+    
       <BuildArgs>--arch $(TargetArchitecture) --apphostver $(AppHostVersion) --hostver $(HostVersion) --fxrver $(HostResolverVersion) --policyver $(HostPolicyVersion) --commithash $(LatestCommit)</BuildArgs>
       <BuildArgs Condition="'$(PortableBuild)' == 'true'">$(BuildArgs) -portable</BuildArgs>     
-      <CMakeBuildDir>$(IntermediateOutputRootPath)corehost\cmake\</CMakeBuildDir>
-      <BuildArgs Condition="'$(CrossBuild)' == 'true'">$(BuildArgs) --cross</BuildArgs>     
+      <BuildArgs Condition="'$(CrossBuild)' == 'true'">$(BuildArgs) --cross</BuildArgs>  
+      <BuildArgs Condition="'$(StripSymbols)' == 'true'">$(BuildArgs) --stripsymbols</BuildArgs>   
     </PropertyGroup>
 
     <RemoveDir Directories="$(CMakeBuildDir)" Condition="Exists('$(CMakeBuildDir)')" />
     <ItemGroup>
       <CMakeOutput Include="$(CMakeBuildDir)cli\exe\dotnet\dotnet" />
       <CMakeOutput Include="$(CMakeBuildDir)cli\exe\apphost\apphost" />
-      <CMakeOutput Include="$(CMakeBuildDir)cli\dll\$(HostPolicyBaseName)" />
-      <CMakeOutput Include="$(CMakeBuildDir)cli\fxr\$(DotnetHostFxrBaseName)" />
+      <CMakeOutput Include="$(HostPolicyPath)" />
+      <CMakeOutput Include="$(DotnetHostFxrPath)" />
+    </ItemGroup>
+    <ItemGroup Condition="'$(StripSymbols)' == 'true'">
+      <CMakeOutput Include="@(CmakeOutput -> '%(Identity)$(SymbolFileExtension)')" />
     </ItemGroup>
 
     <Copy SourceFiles="@(CMakeOutput)"
index 647d610..da6c3d0 100755 (executable)
@@ -61,6 +61,7 @@ usage()
     echo "  -portable                         Optional argument to build portable platform packages."
     echo "  --cross                           Optional argument to signify cross compilation,"
     echo "                                    and use ROOTFS_DIR environment variable to find rootfs."
+    echo "  --stripsymbols                    Optional argument to strip native symbols during the build"
 
     exit 1
 }
@@ -86,6 +87,7 @@ __commit_hash=
 __portableBuildArgs=
 __configuration=Debug
 __linkPortable=0
+__cmake_defines="-DCMAKE_BUILD_TYPE=${__configuration} ${__portableBuildArgs}"
 
 while [ "$1" != "" ]; do
         lowerI="$(echo $1 | awk '{print tolower($0)}')"
@@ -129,14 +131,15 @@ while [ "$1" != "" ]; do
         --cross)
             __CrossBuild=1
             ;;
+        --stripsymbols)
+            __cmake_defines="${__cmake_defines} -DSTRIP_SYMBOLS=true"
+            ;;
         *)
         echo "Unknown argument to build.sh $1"; usage; exit 1
     esac
     shift
 done
 
-__cmake_defines="-DCMAKE_BUILD_TYPE=${__configuration} ${__portableBuildArgs}"
-
 case $__build_arch in
     amd64|x64)
         __arch_define=-DCLI_CMAKE_PLATFORM_ARCH_AMD64=1
index 81d0ec6..aeb4e4c 100644 (file)
@@ -67,3 +67,4 @@ if (WIN32 AND CLI_CMAKE_PLATFORM_ARCH_ARM)
     target_link_libraries(hostpolicy shell32.lib)
 endif()
 
+install_library_and_symbols (hostpolicy)
index 196ac38..0dd8585 100644 (file)
@@ -2,6 +2,7 @@
 # Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
 cmake_minimum_required (VERSION 2.6)
+project(apphost)
 set(DOTNET_HOST_EXE_NAME "apphost")
 
 # Add RPATH to the apphost binary that allows using local copies of shared libraries
@@ -19,3 +20,4 @@ include(../exe.cmake)
 set(SOURCES)
 add_definitions(-DFEATURE_APPHOST=1)
 
+install_library_and_symbols (apphost)
index 3ef6863..b8b0763 100644 (file)
@@ -2,8 +2,10 @@
 # Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
 cmake_minimum_required (VERSION 2.6)
+project(dotnet)
 set(DOTNET_HOST_EXE_NAME "dotnet")
 set(SOURCES 
     ../../fxr/fx_ver.cpp)
 include(../exe.cmake)
 
+install_library_and_symbols (dotnet)
index 235bd4b..bb87c6a 100644 (file)
@@ -64,4 +64,4 @@ if (WIN32 AND CLI_CMAKE_PLATFORM_ARCH_ARM)
     target_link_libraries(hostfxr shell32.lib)
 endif()
 
-
+install_library_and_symbols (hostfxr)
index 31c597a..783789f 100644 (file)
@@ -9,9 +9,13 @@
 
   <PropertyGroup>
     <LibPrefix Condition="'$(OSGroup)' != 'Windows_NT'">lib</LibPrefix>
+    <LibSuffix>.so</LibSuffix> 
     <LibSuffix Condition="'$(OSGroup)' == 'Windows_NT'">.dll</LibSuffix>
     <LibSuffix Condition="'$(OSGroup)' == 'OSX'">.dylib</LibSuffix>
-    <LibSuffix Condition="'$(OSGroup)' != 'Windows_NT' and '$(OSGroup)' != 'OSX'">.so</LibSuffix>  
+    <SymbolFileExtension>.dbg</SymbolFileExtension>
+    <SymbolFileExtension Condition="'$(OSGroup)' == 'OSX'">.dwarf</SymbolFileExtension>
+    <SymbolFileExtension Condition="'$(OSGroup)' == 'Windows_NT'">.pdb</SymbolFileExtension> 
+
     <DotnetHostFxrBaseName>$(LibPrefix)hostfxr$(LibSuffix)</DotnetHostFxrBaseName>
     <HostPolicyBaseName>$(LibPrefix)hostpolicy$(LibSuffix)</HostPolicyBaseName>      
   </PropertyGroup>
index 2f63125..0e0e103 100644 (file)
@@ -30,10 +30,15 @@ platformList.each { platform ->
     def dockerWorkingDirectory = "/src/core-setup"
     def dockerCommand = ''
     def crossbuildargs = ''
+    def buildArgs = "-ConfigurationGroup=${configuration} -TargetArchitecture=${architecture}"
+
+    if (os != 'Windows_NT' && configuration == 'Release') {
+        buildArgs += " -strip-symbols"
+    }
 
     // Calculate build command
     if (os == 'Windows_NT') {
-        buildCommand = ".\\build.cmd -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture}"
+        buildCommand = ".\\build.cmd ${buildArgs}"
         if ((architecture == 'arm' || architecture == 'arm64')) {
             buildCommand += " -PortableBuild=true -SkipTests=true"
         }
@@ -43,7 +48,8 @@ platformList.each { platform ->
         dockerContainer = "ubuntu1404_cross_prereqs_v4-tizen_rootfs"
 
         dockerCommand = "docker run -e ROOTFS_DIR=/crossrootfs/${architecture}.tizen.build --name ${dockerContainer} --rm -v \${WORKSPACE}:${dockerWorkingDirectory} -w=${dockerWorkingDirectory} ${dockerRepository}:${dockerContainer}"
-        buildCommand = "${dockerCommand} ./build.sh -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture} -DistroRid=tizen.4.0.0-${architecture} -SkipTests=true -DisableCrossgen=true -CrossBuild=true -- /p:OverridePackageSource=https:%2F%2Ftizen.myget.org/F/dotnet-core/api/v3/index.json"
+        buildArgs += " -DistroRid=tizen.4.0.0-${architecture} -SkipTests=true -DisableCrossgen=true -CrossBuild=true -- /p:OverridePackageSource=https:%2F%2Ftizen.myget.org/F/dotnet-core/api/v3/index.json"
+        buildCommand = "${dockerCommand} ./build.sh ${buildArgs}"
     }
     else if ((os.startsWith("Ubuntu")) && 
              (architecture == 'arm' || architecture == 'armel')) {
@@ -56,16 +62,18 @@ platformList.each { platform ->
             dockerContainer = "ubuntu-16.04-cross-ef0ac75-20175511035548"
         }
         dockerCommand = "docker run -e ROOTFS_DIR=/crossrootfs/${architecture} --name ${dockerContainer} --rm -v \${WORKSPACE}:${dockerWorkingDirectory} -w=${dockerWorkingDirectory} ${dockerRepository}:${dockerContainer}"
-        buildCommand = "${dockerCommand} ./build.sh -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture} -PortableBuild=true -DistroRid=linux-${architecture} -SkipTests=true -DisableCrossgen=true${crossbuildargs}"
+        buildArgs += " -PortableBuild=true -DistroRid=linux-${architecture} -SkipTests=true -DisableCrossgen=true${crossbuildargs}"
+        buildCommand = "${dockerCommand} ./build.sh ${buildArgs}"
     }
     else if (os == "Ubuntu") {
         dockerContainer = "ubuntu-14.04-debpkg-e5cf912-20175003025046"
         dockerCommand = "docker run --name ${dockerContainer} --rm -v \${WORKSPACE}:${dockerWorkingDirectory} -w=${dockerWorkingDirectory} ${dockerRepository}:${dockerContainer}"
-        buildCommand = "${dockerCommand} ./build.sh -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture}"
+        buildCommand = "${dockerCommand} ./build.sh ${buildArgs}"
     }
     else if (os == "PortableLinux") {
         // Jenkins non-Ubuntu CI machines don't have docker
-        buildCommand = "./build.sh -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture} -PortableBuild=true"
+        buildArgs += " -PortableBuild=true"
+        buildCommand = "./build.sh ${buildArgs}"
         
         // Trigger a portable Linux build that runs on RHEL7.2
         osForGHTrigger = "PortableLinux"
@@ -73,7 +81,7 @@ platformList.each { platform ->
     }
     else {
         // Jenkins non-Ubuntu CI machines don't have docker
-        buildCommand = "./build.sh -ConfigurationGroup=${configuration} -TargetArchitecture=${architecture}"
+        buildCommand = "./build.sh ${buildArgs}"
     }
 
     def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {
index 0e598ce..29eb5db 100644 (file)
@@ -2,9 +2,6 @@
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/apphost.exe" />
-    <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/apphost.pdb">
-      <IsSymbolFile>true</IsSymbolFile>
-    </ArchitectureSpecificNativeFile>
 
     <File Include="@(ArchitectureSpecificNativeFile)">
       <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
index 3f97b80..87ff19b 100644 (file)
@@ -2,9 +2,6 @@
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/dotnet.exe" />
-    <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/dotnet.pdb">
-      <IsSymbolFile>true</IsSymbolFile>
-    </ArchitectureSpecificNativeFile>
 
     <File Include="@(ArchitectureSpecificNativeFile)">
       <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
index 8f9e9b8..107a7fd 100644 (file)
@@ -2,9 +2,6 @@
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/hostpolicy.dll"/>
-    <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/hostpolicy.pdb">
-      <IsSymbolFile>true</IsSymbolFile>
-    </ArchitectureSpecificNativeFile>
 
     <File Include="@(ArchitectureSpecificNativeFile)">
       <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
index 580df8f..10268f6 100644 (file)
@@ -2,9 +2,6 @@
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/hostfxr.dll"/>
-    <ArchitectureSpecificNativeFile Include="$(DotNetHostBinDir)/hostfxr.pdb">
-      <IsSymbolFile>true</IsSymbolFile>
-    </ArchitectureSpecificNativeFile>
 
     <File Include="@(ArchitectureSpecificNativeFile)">
       <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
index 6055b03..868e4b5 100644 (file)
@@ -6,6 +6,43 @@
     <PrereleaseResolveNuGetPackages>true</PrereleaseResolveNuGetPackages>
   </PropertyGroup>
 
+  <!--
+    Finds symbol files and injects them into the package build.
+  -->
+  <Target Name="GetSymbolPackageFiles" BeforeTargets="GetPackageFiles">
+    <ItemGroup Condition="'$(SymbolFileExtension)' != ''">
+      <AdditionalLibPackageExcludes Include="%2A%2A\%2a$(SymbolFileExtension)" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <WindowsNativeFile Include="@(File)"
+                         Condition="'%(File.Extension)' == '.dll' OR '%(File.Extension)' == '.exe'" />
+      <WindowsSymbolFile Include="@(File -> '%(RootDir)%(Directory)%(Filename).pdb')" />
+      <ExistingWindowsSymbolFile Include="@(WindowsSymbolFile)" Condition="Exists('%(Identity)')" />
+
+      <NonWindowsNativeFile Include="@(File)"
+                            Exclude="@(WindowsNativeFile)" />
+      <NonWindowsSymbolFile Include="@(NonWindowsNativeFile -> '%(Identity)$(SymbolFileExtension)')" />
+      <ExistingNonWindowsSymbolFile Include="@(NonWindowsSymbolFile)" Condition="Exists('%(Identity)')" />
+
+      <File Include="@(ExistingWindowsSymbolFile);@(ExistingNonWindowsSymbolFile)">
+        <IsSymbolFile>true</IsSymbolFile>
+      </File>
+    </ItemGroup>
+
+    <PropertyGroup>
+      <NeedsPlaceholderPdb Condition="'@(ExistingNonWindowsSymbolFile)' != '' and '@(ExistingWindowsSymbolFile)' == ''">true</NeedsPlaceholderPdb>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <File Include="$(ToolsDir)\_.pdb"
+            Condition="'$(NeedsPlaceholderPdb)' == 'true' AND '$(PackageTargetRuntime)' != ''">
+        <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+        <IsSymbolFile>true</IsSymbolFile>
+      </File>
+    </ItemGroup>
+  </Target>
+
   <Target Name="PreserveSymbols"
           AfterTargets="CreatePackage">
     <PropertyGroup>