Fix optdata restore functionality (#11935)
authorDaniel Podder <dapodd@microsoft.com>
Thu, 1 Jun 2017 23:41:50 +0000 (18:41 -0500)
committerGitHub <noreply@github.com>
Thu, 1 Jun 2017 23:41:50 +0000 (18:41 -0500)
Fix optdata restore functionality (#11935)

Bring back optdata restore functionality following the move to 2.0
BuildTools and csproj-based CLI. Disable a harmless warning that broke
the Linux build when consuming PGO counts due to -Werr.

Fix #11796 for master

build.cmd
build.proj
build.sh
dir.props
extract-from-json.py [deleted file]
pgosupport.cmake
src/.nuget/optdata/nuget.config [new file with mode: 0644]
src/.nuget/optdata/optdata.csproj [new file with mode: 0644]
tests/scripts/optdata/bootstrap.py
tests/scripts/optdata/optdata.csproj [new file with mode: 0644]
tests/scripts/optdata/project.json [deleted file]

index b3706baefa90b80e0f98655ab1df98d045ed5b63..61d5536143d2c75d05f8ab59599879c238af37fc 100644 (file)
--- a/build.cmd
+++ b/build.cmd
@@ -236,21 +236,6 @@ REM === Restore optimization profile data
 REM ===
 REM =========================================================================================
 
-REM Parse the package version out of project.json so that we can pass it on to CMake
-where /q python || (
-    echo %__MsgPrefix%Error: Python not found on PATH, please make sure that it is installed.
-    exit /b 1
-)
-set OptDataProjectJsonPath=%__ProjectDir%\src\.nuget\optdata\project.json
-if EXIST "%OptDataProjectJsonPath%" (
-    for /f "tokens=*" %%s in ('python "%__ProjectDir%\extract-from-json.py" -rf "%OptDataProjectJsonPath%" dependencies optimization.PGO.CoreCLR') do @(
-        set __PgoOptDataVersion=%%s
-    )
-    for /f "tokens=*" %%s in ('python "%__ProjectDir%\extract-from-json.py" -rf "%OptDataProjectJsonPath%" dependencies optimization.IBC.CoreCLR') do @(
-        set __IbcOptDataVersion=%%s
-    )
-)
-
 if %__RestoreOptData% EQU 1 (
     echo %__MsgPrefix%Restoring the OptimizationData Package
     @call %__ProjectDir%\run.cmd sync -optdata
@@ -260,6 +245,20 @@ if %__RestoreOptData% EQU 1 (
     )
 )
 
+REM Parse the optdata package versions out of msbuild so that we can pass them on to CMake
+set DotNetCli=%__ProjectDir%\Tools\dotnetcli\dotnet.exe
+if not exist "%DotNetCli%" (
+    echo Assertion failed: dotnet.exe not found at path "%DotNetCli%"
+    exit /b 1
+)
+set OptDataProjectFilePath=%__ProjectDir%\src\.nuget\optdata\optdata.csproj
+for /f "tokens=*" %%s in ('%DotNetCli% msbuild "%OptDataProjectFilePath%" /t:DumpPgoDataPackageVersion /nologo') do @(
+    set __PgoOptDataVersion=%%s
+)
+for /f "tokens=*" %%s in ('%DotNetCli% msbuild "%OptDataProjectFilePath%" /t:DumpIbcDataPackageVersion /nologo') do @(
+    set __IbcOptDataVersion=%%s
+)
+
 REM =========================================================================================
 REM ===
 REM === Build the CLR VM
index 7325e6ff30492f7e64f75ad420180689c5a9f2ec..8d15cbcd6e2c98ca7142a92de7cb4e67f944fbd6 100644 (file)
     <Delete Files="$(BinDir)System.Private.CoreLib.*" />
   </Target>
 
-  <PropertyGroup>
-    <OptDataProjectJson>$(SourceDir).nuget/optdata/project.json</OptDataProjectJson>
-    <OptDataPackageFeed>https://dotnet.myget.org/F/dotnet-core-optimization-data/api/v3/index.json</OptDataPackageFeed>
-  </PropertyGroup>
   <Target Name="RestoreOptData">
-    <Exec Condition="Exists('$(OptDataProjectJson)')" Command="$(DnuRestoreCommand) &quot;$(OptDataProjectJson)&quot; --source &quot;$(OptDataPackageFeed)&quot;" />
+    <Exec Command="$(DotnetRestoreCommand) $(SourceDir).nuget/optdata/optdata.csproj" />
   </Target>
 
   <!--
index 8e262b7175d015a54c39ecd0b87fce7b32382d09..4e3508de695245ef9154d7b4b180b000cbdd8653 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -141,6 +141,16 @@ restore_optdata()
             echo "Failed to restore the optimization data package."
             exit 1
         fi
+
+        # Parse the optdata package versions out of msbuild so that we can pass them on to CMake
+        local DotNetCli="$__ProjectRoot/Tools/dotnetcli/dotnet"
+        if [ ! -f $DotNetCli ]; then
+            echo "Assertion failed: dotnet CLI not found at '$DotNetCli'"
+            exit 1
+        fi
+        local OptDataProjectFilePath="$__ProjectRoot/src/.nuget/optdata/optdata.csproj"
+        __PgoOptDataVersion=$($DotNetCli msbuild $OptDataProjectFilePath /t:DumpPgoDataPackageVersion /nologo | sed 's/^\s*//')
+        __IbcOptDataVersion=$($DotNetCli msbuild $OptDataProjectFilePath /t:DumpIbcDataPackageVersion /nologo | sed 's/^\s*//')
     fi
 }
 
@@ -897,13 +907,6 @@ if [ $__CrossBuild == 1 ]; then
     fi
 fi
 
-# Parse the optdata package version from its project.json file
-optDataProjectJsonPath="$__ProjectRoot/src/.nuget/optdata/project.json"
-if [ -f $optDataProjectJsonPath ]; then
-    __PgoOptDataVersion=$("$__ProjectRoot/extract-from-json.py" -rf $optDataProjectJsonPath dependencies optimization.PGO.CoreCLR)
-    __IbcOptDataVersion=$("$__ProjectRoot/extract-from-json.py" -rf $optDataProjectJsonPath dependencies optimization.IBC.CoreCLR)
-fi
-
 # init the target distro name
 initTargetDistroRid
 
index 65f3074e6165f6df2b932b43010549d8dda608c3..451e5506732b91f6a303309e85e7e934ea490104 100644 (file)
--- a/dir.props
+++ b/dir.props
     <RoslynPackageName>Microsoft.Net.ToolsetCompilers</RoslynPackageName>
   </PropertyGroup>
 
+  <!-- Profile-based optimization data package versions -->
+  <PropertyGroup>
+    <PgoDataPackageVersion>99.99.99-master-20170531-3000</PgoDataPackageVersion>
+    <!--<IbcDataPackageVersion></IbcDataPackageVersion>-->
+  </PropertyGroup>
+
   <!--
      Switching to the .NET Core version of the BuildTools tasks seems to break numerous scenarios, such as VS intellisense and resource designer
      as well as runnning the build on mono. Until we can get these sorted out we will continue using the .NET 4.5 version of the tasks.
diff --git a/extract-from-json.py b/extract-from-json.py
deleted file mode 100755 (executable)
index e432b2b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python
-
-import argparse
-import json
-import sys
-
-def parse_args():
-    parser = argparse.ArgumentParser(
-        description="""Extracts information from a json file by navigating the JSON object using a
-            sequence of property accessors and returning the JSON subtree, or the raw data, found
-            at that location."""
-    )
-
-    parser.add_argument(
-        '-f', '--file',
-        metavar='<project.json>',
-        help="Path to project.json file to parse",
-        required=True,
-    )
-
-    parser.add_argument(
-        'property',
-        metavar='property_name',
-        help="""Name of property to extract using object notation.
-            Pass multiple values to drill down into nested objects (in order).""",
-        nargs='*',
-    )
-
-    parser.add_argument(
-        '-r', '--raw',
-        help="""Dumps the raw object found at the requested location.
-            If omitted, returns a JSON formatted object instead.""",
-        action='store_true',
-        default=False
-    )
-
-    return parser.parse_args()
-
-def main():
-    args = parse_args()
-
-    with open(args.file) as json_file:
-        selected_property = json.load(json_file)
-
-    for prop in args.property:
-        selected_property = selected_property[prop]
-
-    if args.raw:
-        print(selected_property)
-    else:
-        print(json.dumps(selected_property))
-
-    return 0
-
-if __name__ == "__main__":
-    sys.exit(main())
index dbba415a61851ff5d5a3d7dd2ec77bc477d2a113..90bcbc38767768149100686ad524c8b8b24e405c 100644 (file)
@@ -20,6 +20,8 @@ function(add_pgo TargetName)
         "${CLR_CMAKE_PACKAGES_DIR}/${CLR_CMAKE_OPTDATA_PACKAGEWITHRID}/${CLR_CMAKE_OPTDATA_VERSION}/data/${ProfileFileName}"
         ProfilePath
     )
+    # NuGet packages are restored to lowercase paths
+    string(TOLOWER "${ProfilePath}" ProfilePath)
 
     if(CLR_CMAKE_PGO_INSTRUMENT)
         if(WIN32)
@@ -40,7 +42,7 @@ function(add_pgo TargetName)
             else(WIN32)
                 if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
                     if(HAVE_LTO)
-                        target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-use=${ProfilePath})
+                        target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-use=${ProfilePath} -Wno-profile-instr-out-of-date)
                         set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fuse-ld=gold -fprofile-instr-use=${ProfilePath}")
                     endif(HAVE_LTO)
                 endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
diff --git a/src/.nuget/optdata/nuget.config b/src/.nuget/optdata/nuget.config
new file mode 100644 (file)
index 0000000..e747f7e
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <packageSources>
+    <add key="myget.org dotnet-core-optimization-data" value="https://dotnet.myget.org/F/dotnet-core-optimization-data/api/v3/index.json" />
+ </packageSources>
+</configuration>
diff --git a/src/.nuget/optdata/optdata.csproj b/src/.nuget/optdata/optdata.csproj
new file mode 100644 (file)
index 0000000..20e2a40
--- /dev/null
@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+
+  <PropertyGroup>
+    <TargetFramework>netstandard</TargetFramework>
+    <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
+    <RuntimeIdentifiers>win7-x64;win7-x86;linux-x64</RuntimeIdentifiers>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="optimization.PGO.CoreCLR" Version="$(PgoDataPackageVersion)" Condition="'$(PgoDataPackageVersion)'!=''" />
+    <PackageReference Include="optimization.IBC.CoreCLR" Version="$(IbcDataPackageVersion)" Condition="'$(IbcDataPackageVersion)'!=''" />
+  </ItemGroup>
+
+  <Target Name="DumpPgoDataPackageVersion">
+    <Message Importance="high" Text="$(PgoDataPackageVersion)" />
+  </Target>
+
+  <Target Name="DumpIbcDataPackageVersion">
+    <Message Importance="high" Text="$(IbcDataPackageVersion)" />
+  </Target>
+
+</Project>
index 1cf55fa70cefbc779df29e30de06cc326db32ddd..8dcecca77924321d1c9253c4cd6d3f873165a245 100755 (executable)
@@ -7,12 +7,12 @@
 """
 
 import argparse
-import json
 import os
 from os import path
 import shutil
 import subprocess
 import sys
+import xml.etree.ElementTree as ET
 
 # Display the docstring if the user passes -h|--help
 argparse.ArgumentParser(description=__doc__).parse_args()
@@ -24,8 +24,8 @@ NUGET_SRC_DIR = path.join(REPO_ROOT, 'src', '.nuget')
 assert path.exists(NUGET_SRC_DIR), \
     "Expected %s to exist; please check whether REPO_ROOT is really %s" % (NUGET_SRC_DIR, REPO_ROOT)
 
-ORIGIN_FILE = path.join(SCRIPT_ROOT, 'project.json')
-TARGET_FILE = path.join(NUGET_SRC_DIR, 'optdata', 'project.json')
+ORIGIN_FILE = path.join(SCRIPT_ROOT, 'optdata.csproj')
+TARGET_FILE = path.join(NUGET_SRC_DIR, 'optdata', 'optdata.csproj')
 
 ARCH_LIST = ['x64', 'x86']
 TOOL_LIST = ['IBC', 'PGO']
@@ -40,9 +40,12 @@ def get_buildos():
 
 def get_optdata_version(tool):
     """Returns the version string specified in project.json for the given tool."""
-    package_name = 'optimization.%s.CoreCLR' % (tool)
-    with open(ORIGIN_FILE) as json_file:
-        return json.load(json_file)['dependencies'][package_name]
+    element_name = {
+        'IBC': 'IbcDataPackageVersion',
+        'PGO': 'PgoDataPackageVersion',
+    }[tool]
+    root = ET.parse(ORIGIN_FILE)
+    return root.findtext('./PropertyGroup/{}'.format(element_name))
 
 def get_optdata_dir(tool, arch):
     """Returns an absolute path to the directory that should contain optdata given a tool,arch"""
diff --git a/tests/scripts/optdata/optdata.csproj b/tests/scripts/optdata/optdata.csproj
new file mode 100644 (file)
index 0000000..ac73606
--- /dev/null
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+
+  <PropertyGroup>
+    <TargetFramework>netstandard</TargetFramework>
+    <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
+    <RuntimeIdentifiers>win7-x64;win7-x86;linux-x64</RuntimeIdentifiers>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <PgoDataPackageVersion>99.99.99-test</PgoDataPackageVersion>
+    <IbcDataPackageVersion>99.99.99-test</IbcDataPackageVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="optimization.PGO.CoreCLR" Version="$(PgoDataPackageVersion)" Condition="'$(PgoDataPackageVersion)'!=''" />
+    <PackageReference Include="optimization.IBC.CoreCLR" Version="$(IbcDataPackageVersion)" Condition="'$(IbcDataPackageVersion)'!=''" />
+  </ItemGroup>
+
+  <Target Name="DumpPgoDataPackageVersion">
+    <Message Importance="high" Text="$(PgoDataPackageVersion)" />
+  </Target>
+
+  <Target Name="DumpIbcDataPackageVersion">
+    <Message Importance="high" Text="$(IbcDataPackageVersion)" />
+  </Target>
+
+</Project>
diff --git a/tests/scripts/optdata/project.json b/tests/scripts/optdata/project.json
deleted file mode 100644 (file)
index ae8f946..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": {
-        "optimization.IBC.CoreCLR": "99.99.99-test",
-        "optimization.PGO.CoreCLR": "99.99.99-test"
-    },
-    "frameworks": {
-        "netstandard": {}
-    },
-    "runtimes": {
-        "win7-x64": {}
-    }
-}