ICU-20712 Add support for building Windows UWP ARM/ARM64 data DLLs.

This also changes the pkgdata tool command line options to decouple the
ARM/ARM64 flags from the UWP flag, and adds a generic architecture
option (-a) for passing in the value of the linker "/MACHINE:" argument
on the command line. (Ex: -a ARM64).

Additionally this change also adds another option to pkgdata (-b) to 
set /DYNAMICBASE on the data DLL, which is required for the ARM64 builds.

Both of these changes also work towards future work in order to enable
full ARM64 desktop builds without UWP.

This change also removes a number of ifdefs/forks in the ICU code based
on U_PLATFORM_HAS_WINUWP_API, and changes them to use ICU_DATA_DIR_WINDOWS
instead. This is needed to unblock the usage of the data DLL in the
UWP scenario, but also helps to further reduce the divergence of the UWP
projects from regular Windows builds.

Related tickets:
  ICU4C: Remove fixed DLL base addresses when building Windows DLLs
  https://unicode-org.atlassian.net/browse/ICU-20768

  Add support to generate ICU data DLL for Windows arm64
  https://unicode-org.atlassian.net/browse/ICU-20670

diff --git a/.gitignore b/.gitignore
index b84c0a9..3ef3453 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,17 +6,23 @@
 /.git
 .vscode
 icu4c/bin
+icu4c/binARM
 icu4c/bin32uwp
 icu4c/bin64
+icu4c/binARM64
 icu4c/bin64uwp
 icu4c/binARMUWP
+icu4c/binARM64UWP
 icu4c/commondata
 icu4c/include
 icu4c/lib
+icu4c/libARM
 icu4c/lib32uwp
 icu4c/lib64
+icu4c/libARM64
 icu4c/lib64uwp
 icu4c/libARMuwp
+icu4c/libARM64uwp
 icu4c/source/Doxyfile
 icu4c/source/Makefile
 icu4c/source/README
@@ -43,6 +49,7 @@
 icu4c/source/common/Makefile.local
 icu4c/source/common/Release
 icu4c/source/common/arm
+icu4c/source/common/arm64
 icu4c/source/common/common.res
 icu4c/source/common/common.vcproj.*.*.user
 icu4c/source/common/debug
@@ -85,6 +92,8 @@
 icu4c/source/data/uni-core-data
 icu4c/source/data/x64
 icu4c/source/data/x86
+icu4c/source/data/arm
+icu4c/source/data/arm64
 icu4c/source/dist
 icu4c/source/doc
 icu4c/source/extra/Makefile
@@ -123,6 +132,7 @@
 icu4c/source/i18n/Makefile.local
 icu4c/source/i18n/Release
 icu4c/source/i18n/arm
+icu4c/source/i18n/arm64
 icu4c/source/i18n/debug
 icu4c/source/i18n/i18n.res
 icu4c/source/i18n/i18n.vcproj.*.*.user
@@ -409,6 +419,8 @@
 icu4c/source/stubdata/stubdatabuilt.txt
 icu4c/source/stubdata/x64
 icu4c/source/stubdata/x86
+icu4c/source/stubdata/ARM
+icu4c/source/stubdata/ARM64
 icu4c/source/test-*.xml
 icu4c/source/test/Makefile
 icu4c/source/test/cintltst/*.d
diff --git a/icu4c/source/allinone/allinone.sln b/icu4c/source/allinone/allinone.sln
index 11bd320..2b18941 100644
--- a/icu4c/source/allinone/allinone.sln
+++ b/icu4c/source/allinone/allinone.sln
@@ -410,14 +410,18 @@
 		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|Win32.Build.0 = Release|Win32
 		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|x64.ActiveCfg = Release|x64
 		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|x64.Build.0 = Release|x64
-		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM.ActiveCfg = Debug|Win32
-		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM.ActiveCfg = Debug|ARM
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM.Build.0 = Debug|ARM
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|ARM64.Build.0 = Debug|ARM64
 		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.ActiveCfg = Debug|Win32
 		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.Build.0 = Debug|Win32
 		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.ActiveCfg = Debug|x64
 		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.Build.0 = Debug|x64
-		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM.ActiveCfg = Release|Win32
-		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM64.ActiveCfg = Release|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM.ActiveCfg = Release|ARM
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM.Build.0 = Release|ARM
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM64.ActiveCfg = Release|ARM64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|ARM64.Build.0 = Release|ARM64
 		{203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.ActiveCfg = Release|Win32
 		{203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.Build.0 = Release|Win32
 		{203EC78A-0531-43F0-A636-285439BDE025}.Release|x64.ActiveCfg = Release|x64
diff --git a/icu4c/source/common/common.vcxproj b/icu4c/source/common/common.vcxproj
index 02c88e24..3bfc646 100644
--- a/icu4c/source/common/common.vcxproj
+++ b/icu4c/source/common/common.vcxproj
@@ -56,6 +56,7 @@
       <WarningLevel>Level3</WarningLevel>
     </ClCompile>
     <Link>
+      <!-- The icudt.lib is for U_ICUDATA_ENTRY_POINT -->
       <AdditionalDependencies>icudt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <BaseAddress>0x4a800000</BaseAddress>
     </Link>
diff --git a/icu4c/source/common/common_uwp.vcxproj b/icu4c/source/common/common_uwp.vcxproj
index 1c0e940..bff752c 100644
--- a/icu4c/source/common/common_uwp.vcxproj
+++ b/icu4c/source/common/common_uwp.vcxproj
@@ -114,7 +114,8 @@
       </DataExecutionPrevention>
       <TurnOffAssemblyGeneration>true</TurnOffAssemblyGeneration>
       <IgnoreSpecificDefaultLibraries>vccorlib.lib;msvcrt.lib</IgnoreSpecificDefaultLibraries>
-      <AdditionalDependencies>onecore.lib</AdditionalDependencies>
+      <!-- The icudt.lib is for U_ICUDATA_ENTRY_POINT -->
+      <AdditionalDependencies>icudt.lib;onecore.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
@@ -131,7 +132,7 @@
     </ResourceCompile>
     <Link>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <AdditionalDependencies>vccorlib.lib;WindowsApp.lib;msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>vccorlib.lib;msvcrt.lib;vcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
@@ -152,7 +153,7 @@
     </ResourceCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>vccorlibd.lib;WindowsApp.lib;msvcrtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>vccorlibd.lib;msvcrtd.lib;vcruntimed.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
@@ -163,6 +164,10 @@
     <ClCompile>
       <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <Link>
+      <!-- This is so that we can use the existing stubdata icudt.lib and not need a UWP version. -->
+      <AdditionalLibraryDirectories>.\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
     <!-- Options that are common to all 64-bit configurations -->
@@ -174,6 +179,8 @@
     </ClCompile>
     <Link>
       <TargetMachine>MachineX64</TargetMachine>
+      <!-- This is so that we can use the existing stubdata icudt.lib and not need a UWP version. -->
+      <AdditionalLibraryDirectories>.\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Platform)'=='ARM'">
@@ -186,6 +193,8 @@
     </ClCompile>
     <Link>
       <TargetMachine>MachineARM</TargetMachine>
+      <!-- This is so that we can use the existing stubdata icudt.lib and not need a UWP version. -->
+      <AdditionalLibraryDirectories>.\..\..\libARM;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Platform)'=='ARM64'">
@@ -198,6 +207,8 @@
     </ClCompile>
     <Link>
       <TargetMachine>MachineARM64</TargetMachine>
+      <!-- This is so that we can use the existing stubdata icudt.lib and not need a UWP version. -->
+      <AdditionalLibraryDirectories>.\..\..\libARM64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <!-- Options that are specific to a particular configuration -->
@@ -373,9 +384,7 @@
     <ClCompile Include="errorcode.cpp" />
     <ClCompile Include="icudataver.cpp" />
     <ClCompile Include="locmap.cpp" />
-    <ClCompile Include="putil.cpp">
-      <CompileAsWinRT>true</CompileAsWinRT>
-    </ClCompile>
+    <ClCompile Include="putil.cpp" />
     <ClCompile Include="umath.cpp" />
     <ClCompile Include="umutex.cpp" />
     <ClCompile Include="utrace.cpp" />
@@ -643,4 +652,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" Condition="'$(SkipUWP)'!='true'" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp
index aa36f95..acb9022 100644
--- a/icu4c/source/common/putil.cpp
+++ b/icu4c/source/common/putil.cpp
@@ -1315,11 +1315,10 @@
 # endif
 #endif
 
-#if U_PLATFORM_HAS_WINUWP_API != 0
+#if defined(ICU_DATA_DIR_WINDOWS)
 // Helper function to get the ICU Data Directory under the Windows directory location.
 static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
 {
-#if defined(ICU_DATA_DIR_WINDOWS)
     wchar_t windowsPath[MAX_PATH];
     char windowsPathUtf8[MAX_PATH];
 
@@ -1346,7 +1345,6 @@
             }
         }
     }
-#endif
 
     return FALSE;
 }
@@ -1380,9 +1378,9 @@
     */
 #   if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
     /* First try to get the environment variable */
-#       if U_PLATFORM_HAS_WINUWP_API == 0  // Windows UWP does not support getenv
+#     if U_PLATFORM_HAS_WINUWP_API == 0  // Windows UWP does not support getenv
         path=getenv("ICU_DATA");
-#       endif
+#     endif
 #   endif
 
     /* ICU_DATA_DIR may be set as a compile option.
@@ -1411,7 +1409,7 @@
     }
 #endif
 
-#if U_PLATFORM_HAS_WINUWP_API != 0  && defined(ICU_DATA_DIR_WINDOWS)
+#if defined(ICU_DATA_DIR_WINDOWS)
     char datadir_path_buffer[MAX_PATH];
     if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
         path = datadir_path_buffer;
@@ -1461,12 +1459,17 @@
 
     const char *dir = "";
 
-#if U_PLATFORM_HAS_WINUWP_API != 0
-    // The UWP version does not support the environment variable setting, but can possibly pick them up from the Windows directory.
+#if U_PLATFORM_HAS_WINUWP_API == 1
+// The UWP version does not support the environment variable setting.
+
+# if defined(ICU_DATA_DIR_WINDOWS)
+    // When using the Windows system data, we can possibly pick up time zone data from the Windows directory.
     char datadir_path_buffer[MAX_PATH];
     if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
         dir = datadir_path_buffer;
     }
+# endif
+
 #else
     dir = getenv("ICU_TIMEZONE_FILES_DIR");
 #endif // U_PLATFORM_HAS_WINUWP_API
@@ -2064,7 +2067,7 @@
     static char codepage[64];
     DWORD codepageNumber = 0;
 
-#if U_PLATFORM_HAS_WINUWP_API > 0
+#if U_PLATFORM_HAS_WINUWP_API == 1
     // UWP doesn't have a direct API to get the default ACP as Microsoft would rather
     // have folks use Unicode than a "system" code page, however this is the same
     // codepage as the system default locale codepage.  (FWIW, the system locale is
diff --git a/icu4c/source/common/udata.cpp b/icu4c/source/common/udata.cpp
index 6ea6c12..ec9c999 100644
--- a/icu4c/source/common/udata.cpp
+++ b/icu4c/source/common/udata.cpp
@@ -111,11 +111,12 @@
 static UHashtable  *gCommonDataCache = NULL;  /* Global hash table of opened ICU data files.  */
 static icu::UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
 
-#if U_PLATFORM_HAS_WINUWP_API == 0 
+#if !defined(ICU_DATA_DIR_WINDOWS)
 static UDataFileAccess  gDataFileAccess = UDATA_DEFAULT_ACCESS;  // Access not synchronized.
                                                                  // Modifying is documented as thread-unsafe.
 #else
-static UDataFileAccess  gDataFileAccess = UDATA_NO_FILES;        // Windows UWP looks in one spot explicitly
+// If we are using the Windows data directory, then look in one spot only.
+static UDataFileAccess  gDataFileAccess = UDATA_NO_FILES;
 #endif
 
 static UBool U_CALLCONV
@@ -207,7 +208,7 @@
     return didUpdate;
 }
 
-#if U_PLATFORM_HAS_WINUWP_API == 0 
+#if !defined(ICU_DATA_DIR_WINDOWS)
 
 static UBool
 setCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCode) {
@@ -640,7 +641,8 @@
  *      our common data.                                                *
  *                                                                      *
  *----------------------------------------------------------------------*/
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
 extern "C" const DataHeader U_DATA_API U_ICUDATA_ENTRY_POINT;
 #endif
 
@@ -690,7 +692,8 @@
             if(gCommonICUDataArray[commonDataIndex] != NULL) {
                 return gCommonICUDataArray[commonDataIndex];
             }
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
             int32_t i;
             for(i = 0; i < commonDataIndex; ++i) {
                 if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT) {
@@ -714,7 +717,8 @@
             setCommonICUDataPointer(uprv_getICUData_conversion(), FALSE, pErrorCode);
         }
         */
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
         setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT, FALSE, pErrorCode);
         {
             Mutex lock;
@@ -1279,12 +1283,12 @@
     fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.data());
 #endif
 
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
     if(path == NULL) {
         path = COMMON_DATA_NAME; /* "icudt26e" */
     }
 #else
-    // Windows UWP expects only a single data file.
+    // When using the Windows system data, we expects only a single data file.
     path = COMMON_DATA_NAME; /* "icudt26e" */
 #endif
 
diff --git a/icu4c/source/data/makedata.mak b/icu4c/source/data/makedata.mak
index b0b813c..752bddc 100644
--- a/icu4c/source/data/makedata.mak
+++ b/icu4c/source/data/makedata.mak
@@ -106,6 +106,8 @@
 #
 !IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
 DLL_OUTPUT=$(ICUP)\binARM$(UWP)
+!ELSE IF "$(CFG)" == "ARM64\Release" || "$(CFG)" == "ARM64\Debug"
+DLL_OUTPUT=$(ICUP)\binARM64$(UWP)
 !ELSE IF "$(CFG)" == "x64\Release" || "$(CFG)" == "x64\Debug"
 DLL_OUTPUT=$(ICUP)\bin64$(UWP)
 !ELSE IF "$(UWP)" == "UWP"
@@ -140,18 +142,19 @@
 
 #
 #  TOOLS CFG PATH
-#      ARM needs to use one of the other tools, so make sure to get an usable cfg path
+#      Generally the tools want to run on the same architechure as is being built.
+#      Thus ARM and ARM64 need to use another build of the other tools, so make sure to get an usable cfg path.
 #      Since tools, particularly pkggen, have architecture built-in, we made x64 on
 #      Windows be machine-independent and use those tools.
 #
 CFGTOOLS=$(CFG)
-!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
+!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug" || "$(CFG)" == "ARM64\Release"  || "$(CFG)" == "ARM64\Debug"
 CFGTOOLS=x64\Release
 !ENDIF
 !MESSAGE ICU tools CFG subpath is $(CFGTOOLS)
 
 # The current ICU tools need to be in the path first.
-# x86 uses x86, x64 and arm use x64
+# x86 uses x86; x64, arm, and arm64 use x64
 !IF "$(CFG)" == "x86\Release" || "$(CFG)" == "x86\Debug"
 PATH = $(ICUP)\bin;$(PATH)
 ICUPBIN=$(ICUP)\bin
@@ -190,9 +193,12 @@
 COMMON_ICUDATA_ARGUMENTS=-f -e $(U_ICUDATA_NAME) -v $(ICU_PACKAGE_MODE) -c -p $(ICUPKG) -T "$(ICUTMP)" -L $(U_ICUDATA_NAME) -d "$(ICUBLD_PKG)" -s .
 !IF "$(UWP)" == "UWP"
 COMMON_ICUDATA_ARGUMENTS=$(COMMON_ICUDATA_ARGUMENTS) -u
-!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
-COMMON_ICUDATA_ARGUMENTS=$(COMMON_ICUDATA_ARGUMENTS) -a
 !ENDIF
+!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
+COMMON_ICUDATA_ARGUMENTS=$(COMMON_ICUDATA_ARGUMENTS) -a ARM
+!ENDIF
+!IF "$(CFG)" == "ARM64\Release" || "$(CFG)" == "ARM64\Debug"
+COMMON_ICUDATA_ARGUMENTS=$(COMMON_ICUDATA_ARGUMENTS) -a ARM64
 !ENDIF
 
 #############################################################################
diff --git a/icu4c/source/data/makedata_uwp.vcxproj b/icu4c/source/data/makedata_uwp.vcxproj
index 1385da4..f835ab5 100644
--- a/icu4c/source/data/makedata_uwp.vcxproj
+++ b/icu4c/source/data/makedata_uwp.vcxproj
@@ -84,6 +84,12 @@
     <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM\Debug UWP=UWP</NMakeBuildCommandLine>
     <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM\Debug UWP=UWP clean all</NMakeReBuildCommandLine>
     <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM\Debug UWP=UWP clean</NMakeCleanCommandLine>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Release UWP=UWP</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Release UWP=UWP clean all</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Release UWP=UWP clean</NMakeCleanCommandLine>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Debug UWP=UWP</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Debug UWP=UWP clean all</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NMAKE /f makedata.mak ICUMAKE="$(ProjectDir)\" CFG=ARM64\Debug UWP=UWP clean</NMakeCleanCommandLine>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <BuildLog>
@@ -115,6 +121,16 @@
       <Path>.\out\tmp\arm\DebugUWPBuildLog.html</Path>
     </BuildLog>
   </ItemDefinitionGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <BuildLog>
+      <Path>.\out\tmp\arm64\ReleaseUWPBuildLog.html</Path>
+    </BuildLog>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <BuildLog>
+      <Path>.\out\tmp\arm64\DebugUWPBuildLog.html</Path>
+    </BuildLog>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <None Include="brkitr\brkfiles.mk" />
     <None Include="coll\colfiles.mk" />
diff --git a/icu4c/source/stubdata/stubdata.vcxproj b/icu4c/source/stubdata/stubdata.vcxproj
index 43a1f0f..dbc605c 100644
--- a/icu4c/source/stubdata/stubdata.vcxproj
+++ b/icu4c/source/stubdata/stubdata.vcxproj
@@ -13,6 +13,24 @@
   <Import Project="..\allinone\Build.Windows.ProjectConfiguration.props" />
   <!-- The following import will include the library configuration options for VS projects. -->
   <Import Project="..\allinone\Build.Windows.Library.ProjectConfiguration.props" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|ARM64">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM64">
+      <Configuration>Release</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
@@ -35,20 +53,32 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
-    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
-    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
-    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
-    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\ARM\Release\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\ARM\Release\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\ARM\Debug\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\ARM\Debug\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\ARM64\Release\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\ARM64\Release\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\ARM64\Debug\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\ARM64\Debug\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Platform)'=='ARM'">
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+    <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Platform)'=='ARM64'">
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
   </PropertyGroup>
   <!-- Options that are common to *all* project configurations -->
   <ItemDefinitionGroup>
@@ -69,7 +99,7 @@
       <BaseAddress>0x4ad00000</BaseAddress>
       <NoEntryPoint>true</NoEntryPoint>
       <SetChecksum>true</SetChecksum>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
       <TurnOffAssemblyGeneration>true</TurnOffAssemblyGeneration>
     </Link>
   </ItemDefinitionGroup>
@@ -159,6 +189,102 @@
       <ImportLibrary>..\..\lib64\icudt.lib</ImportLibrary>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='ARM'">
+    <!-- Options that are common to all ARM configurations -->
+    <Midl>
+      <TargetEnvironment>ARM</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <PreprocessorDefinitions>ARM;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <OutputFile>..\..\binARM\icudt64.dll</OutputFile>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+      <TargetMachine>MachineARM</TargetMachine>
+      <ImportLibrary>..\..\libARM\icudt.lib</ImportLibrary>
+      <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <BaseAddress></BaseAddress>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <Midl>
+      <TypeLibraryName>.\ARM\Release\icudt.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <PrecompiledHeaderOutputFile>.\ARM\Release\stubdata.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\ARM\Release/</AssemblerListingLocation>
+      <ObjectFileName>.\ARM\Release/</ObjectFileName>
+      <ProgramDataBaseFileName>.\ARM\Release/</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <ProgramDatabaseFile>.\ARM\Release\icudt.pdb</ProgramDatabaseFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <Midl>
+      <TypeLibraryName>.\ARM\Debug/icudt.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <PrecompiledHeaderOutputFile>.\ARM\Debug/stubdata.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\ARM\Debug/</AssemblerListingLocation>
+      <ObjectFileName>.\ARM\Debug/</ObjectFileName>
+      <ProgramDataBaseFileName>.\ARM\Debug/</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <ProgramDatabaseFile>.\ARM\Debug/icudt.pdb</ProgramDatabaseFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='ARM64'">
+    <!-- Options that are common to all ARM64 configurations -->
+    <Midl>
+      <TargetEnvironment>ARM64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <PreprocessorDefinitions>ARM64;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <OutputFile>..\..\binARM64\icudt64.dll</OutputFile>
+      <TargetMachine>MachineARM64</TargetMachine>
+      <ImportLibrary>..\..\libARM64\icudt.lib</ImportLibrary>
+      <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64</AdditionalLibraryDirectories>
+      <BaseAddress></BaseAddress>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <Midl>
+      <TypeLibraryName>.\ARM64\Release\icudt.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <PrecompiledHeaderOutputFile>.\ARM64\Release\stubdata.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\ARM64\Release/</AssemblerListingLocation>
+      <ObjectFileName>.\ARM64\Release/</ObjectFileName>
+      <ProgramDataBaseFileName>.\ARM64\Release/</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <ProgramDatabaseFile>.\ARM64\Release\icudt.pdb</ProgramDatabaseFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <Midl>
+      <TypeLibraryName>.\ARM64\Debug/icudt.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <PrecompiledHeaderOutputFile>.\ARM64\Debug/stubdata.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\ARM64\Debug/</AssemblerListingLocation>
+      <ObjectFileName>.\ARM64\Debug/</ObjectFileName>
+      <ProgramDataBaseFileName>.\ARM64\Debug/</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <ProgramDatabaseFile>.\ARM64\Debug/icudt.pdb</ProgramDatabaseFile>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="stubdata.cpp" />
   </ItemGroup>
@@ -170,4 +296,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/icu4c/source/tools/pkgdata/pkgdata.cpp b/icu4c/source/tools/pkgdata/pkgdata.cpp
index 429e4b4..5e73079 100644
--- a/icu4c/source/tools/pkgdata/pkgdata.cpp
+++ b/icu4c/source/tools/pkgdata/pkgdata.cpp
@@ -122,8 +122,9 @@
     QUIET,
     WITHOUT_ASSEMBLY,
     PDS_BUILD,
-    UWP_BUILD,
-    UWP_ARM_BUILD
+    WIN_UWP_BUILD,
+    WIN_DLL_ARCH,
+    WIN_DYNAMICBASE
 };
 
 /* This sets the modes that are available */
@@ -167,7 +168,8 @@
     /*20*/    UOPTION_DEF( "without-assembly", 'w', UOPT_NO_ARG),
     /*21*/    UOPTION_DEF("zos-pds-build", 'z', UOPT_NO_ARG),
     /*22*/    UOPTION_DEF("windows-uwp-build", 'u', UOPT_NO_ARG),
-    /*23*/    UOPTION_DEF("windows-uwp-arm-build", 'a', UOPT_NO_ARG)
+    /*23*/    UOPTION_DEF("windows-DLL-arch", 'a', UOPT_REQUIRES_ARG),
+    /*24*/    UOPTION_DEF("windows-dynamicbase", 'b', UOPT_NO_ARG),
 };
 
 /* This enum and the following char array should be kept in sync. */
@@ -258,7 +260,8 @@
     "Build the data without assembly code",
     "Build PDS dataset (zOS build only)",
     "Build for Universal Windows Platform (Windows build only)",
-    "Set DLL machine type for UWP to target windows ARM (Windows UWP build only)"
+    "Specify the DLL machine architecture for LINK.exe (Windows build only)",
+    "Set DYNAMICBASE on for the DLL (Windows build only)",
 };
 
 const char  *progname = "PKGDATA";
@@ -1778,13 +1781,14 @@
 #ifdef WINDOWS_WITH_MSVC
 #define LINK_CMD "link.exe /nologo /release /out:"
 #define LINK_FLAGS "/DLL /NOENTRY /MANIFEST:NO /implib:"
-#ifdef _WIN64
+
 #define LINK_EXTRA_UWP_FLAGS "/NXCOMPAT /DYNAMICBASE /APPCONTAINER "
-#else
-#define LINK_EXTRA_UWP_FLAGS "/NXCOMPAT /SAFESEH /DYNAMICBASE /APPCONTAINER /MACHINE:X86"
-#endif
-#define LINK_EXTRA_UWP_FLAGS_ARM "/NXCOMPAT /DYNAMICBASE /APPCONTAINER /MACHINE:ARM"
-#define LINK_EXTRA_NO_UWP_FLAGS "/base:0x4ad00000 "
+#define LINK_EXTRA_UWP_FLAGS_X86_ONLY "/SAFESEH "
+
+#define LINK_EXTRA_NO_DYNAMICBASE "/base:0x4ad00000 "
+#define LINK_EXTRA_DYNAMICBASE "/DYNAMICBASE "
+#define LINK_EXTRA_FLAGS_MACHINE "/MACHINE:"
+
 #define LIB_CMD "LIB.exe /nologo /out:"
 #define LIB_FILE "icudt.lib"
 #define LIB_EXT UDATA_LIB_SUFFIX
@@ -1864,23 +1868,29 @@
           return 0;
         }
 
-        char *extraFlags = "";
+        char extraFlags[SMALL_BUFFER_MAX_SIZE] = "";
 #ifdef WINDOWS_WITH_MSVC
-        if (options[UWP_BUILD].doesOccur)
-        {
-            if (options[UWP_ARM_BUILD].doesOccur)
-            {
-                extraFlags = LINK_EXTRA_UWP_FLAGS_ARM;
+        if (options[WIN_UWP_BUILD].doesOccur) {
+            uprv_strcat(extraFlags, LINK_EXTRA_UWP_FLAGS);
+
+            if (options[WIN_DLL_ARCH].doesOccur) {
+                if (uprv_strcmp(options[WIN_DLL_ARCH].value, "X86") == 0) {
+                    uprv_strcat(extraFlags, LINK_EXTRA_UWP_FLAGS_X86_ONLY);
+                }
             }
-            else
-            {
-                extraFlags = LINK_EXTRA_UWP_FLAGS;
+        } else {
+            if (options[WIN_DYNAMICBASE].doesOccur) {
+                uprv_strcat(extraFlags, LINK_EXTRA_DYNAMICBASE);
+            } else {
+                uprv_strcat(extraFlags, LINK_EXTRA_NO_DYNAMICBASE);
             }
         }
-        else
-        {
-            extraFlags = LINK_EXTRA_NO_UWP_FLAGS;
+
+        if (options[WIN_DLL_ARCH].doesOccur) {
+            uprv_strcat(extraFlags, LINK_EXTRA_FLAGS_MACHINE);
+            uprv_strcat(extraFlags, options[WIN_DLL_ARCH].value);
         }
+
 #endif
         sprintf(cmd, "%s\"%s\" %s %s\"%s\" \"%s\" %s",
             LINK_CMD,