Răsfoiți Sursa

Update Windows and xplat build systems to support local ICU

Jack Horton 8 ani în urmă
părinte
comite
7f2888eb2c

+ 4 - 1
.gitignore

@@ -76,6 +76,10 @@ install_manifest.txt
 *.xcodeproj
 *.xcworkspace
 
+# ICU
+deps/Chakra.ICU/Chakra.ICU.props
+deps/Chakra.ICU/icu
+
 # VIM
 .*.swo
 .*.swp
@@ -98,7 +102,6 @@ lib/wabt/built/config.h
 # Generated by other tools
 *.lldb.cmd
 *.orig
-deps/
 
 .DS_Store
 android-toolchain-arm/

+ 0 - 7
Build/Chakra.Build.Paths.props

@@ -9,11 +9,4 @@
 
     <ChakraBuildPathImported>true</ChakraBuildPathImported>
   </PropertyGroup>
-  <PropertyGroup Label="ICU">
-    <!-- IcuLibDir can be set in environment or with "/p:IcuLibDir=..." -->
-    <IcuLibDir Condition="'$(IcuLibDir)'=='' AND '$(Configuration)'=='Debug'">$(ChakraCoreRootDirectory)\deps\static\icu-small\debug</IcuLibDir>
-    <IcuLibDir Condition="'$(IcuLibDir)'=='' AND ('$(Configuration)'=='Test' or '$(Configuration)'=='Release')">$(ChakraCoreRootDirectory)\deps\static\icu-small\release</IcuLibDir>
-    <!-- IcuIncludeDir can be set in environment or with "/p:IcuIncludeDir=..." -->
-    <IcuIncludeDir Condition="'$(IcuIncludeDir)'==''">$(ChakraCoreRootDirectory)\deps\icu-small\source</IcuIncludeDir>
-  </PropertyGroup>
 </Project>

+ 13 - 6
Build/Chakra.Build.props

@@ -17,6 +17,18 @@
   <PropertyGroup Condition="'$(RunCodeAnalysis)'=='' AND '$(Configuration)'=='Release'">
     <RunCodeAnalysis>$(BuildWithCodeAnalysis)</RunCodeAnalysis>
   </PropertyGroup>
+  <PropertyGroup>
+    <EnableIntl Condition="'$(EnableIntl)'==''">true</EnableIntl>
+    <EnableIntl Condition="'$(BuildLite)'=='true'">false</EnableIntl>
+
+    <ChakraICU Condition="'$(ChakraICU)'==''">false</ChakraICU>
+    <!-- ARM does not support ICU until we figure out how to link icudtXXl.dat without genccode.exe -->
+    <ChakraICU Condition="'$(Platform)'=='ARM'">false</ChakraICU>
+
+    <UseICU Condition="'$(UseICU)'==''">false</UseICU>
+    <UseICU Condition="'$(BuildLite)'=='true'">false</UseICU>
+    <UseICU Condition="'$(ChakraICU)'!='false'">true</UseICU>
+  </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
       <PreprocessorDefinitions>
@@ -38,7 +50,7 @@
         %(PreprocessorDefinitions);
         CHAKRACORE_LITE
       </PreprocessorDefinitions>
-      <PreprocessorDefinitions Condition="'$(IntlICU)'=='true'">
+      <PreprocessorDefinitions Condition="'$(EnableIntl)'=='true' AND '$(UseICU)'=='true'">
         %(PreprocessorDefinitions);
         INTL_ICU=1
       </PreprocessorDefinitions>
@@ -62,11 +74,6 @@
         $(IntDir)..\CoreManifests;
         %(AdditionalIncludeDirectories)
       </AdditionalIncludeDirectories>
-      <AdditionalIncludeDirectories Condition="'$(IntlICU)'=='true'">
-        $(IcuIncludeDir)\common;
-        $(IcuIncludeDir)\i18n;
-        %(AdditionalIncludeDirectories)
-      </AdditionalIncludeDirectories>
     </ClCompile>
 
     <ResourceCompile>

+ 129 - 0
Build/Chakra.Core.sln

@@ -156,6 +156,20 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pal", "..\pal\pal.vcxproj",
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wabt", "..\lib\wabt\wabt.vcxproj", "{F48B3491-81DF-4F49-B35F-3308CBE6A379}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.Common", "..\deps\Chakra.ICU\Chakra.ICU.Common.vcxproj", "{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Deps", "Deps", "{6C6BC844-3D86-42B4-B3C4-7478487D2C38}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.Data", "..\deps\Chakra.ICU\Chakra.ICU.Data.vcxproj", "{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.i18n", "..\deps\Chakra.ICU\Chakra.ICU.i18n.vcxproj", "{0494C753-5BB9-45AA-874E-E61B9922E88F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.GenCCode", "..\deps\Chakra.ICU\Chakra.ICU.GenCCode.vcxproj", "{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.Stubdata", "..\deps\Chakra.ICU\Chakra.ICU.Stubdata.vcxproj", "{E14F373D-05A0-4259-A5E9-AFE8405FB847}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.ICU.Toolutil", "..\deps\Chakra.ICU\Chakra.ICU.Toolutil.vcxproj", "{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ARM = Debug|ARM
@@ -713,6 +727,114 @@ Global
 		{F48B3491-81DF-4F49-B35F-3308CBE6A379}.Test|x64.Build.0 = Test|x64
 		{F48B3491-81DF-4F49-B35F-3308CBE6A379}.Test|x86.ActiveCfg = Test|Win32
 		{F48B3491-81DF-4F49-B35F-3308CBE6A379}.Test|x86.Build.0 = Test|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|ARM.ActiveCfg = Debug|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|ARM.Build.0 = Debug|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|x64.ActiveCfg = Debug|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|x64.Build.0 = Debug|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|x86.ActiveCfg = Debug|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Debug|x86.Build.0 = Debug|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|ARM.ActiveCfg = Release|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|ARM.Build.0 = Release|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|x64.ActiveCfg = Release|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|x64.Build.0 = Release|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|x86.ActiveCfg = Release|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Release|x86.Build.0 = Release|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|ARM.ActiveCfg = Test|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|ARM.Build.0 = Test|ARM
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|x64.ActiveCfg = Test|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|x64.Build.0 = Test|x64
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|x86.ActiveCfg = Test|Win32
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}.Test|x86.Build.0 = Test|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|ARM.ActiveCfg = Debug|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|ARM.Build.0 = Debug|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|x64.ActiveCfg = Debug|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|x64.Build.0 = Debug|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|x86.ActiveCfg = Debug|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Debug|x86.Build.0 = Debug|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|ARM.ActiveCfg = Release|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|ARM.Build.0 = Release|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|x64.ActiveCfg = Release|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|x64.Build.0 = Release|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|x86.ActiveCfg = Release|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Release|x86.Build.0 = Release|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|ARM.ActiveCfg = Test|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|ARM.Build.0 = Test|ARM
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|x64.ActiveCfg = Test|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|x64.Build.0 = Test|x64
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|x86.ActiveCfg = Test|Win32
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}.Test|x86.Build.0 = Test|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|ARM.ActiveCfg = Debug|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|ARM.Build.0 = Debug|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|x64.ActiveCfg = Debug|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|x64.Build.0 = Debug|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|x86.ActiveCfg = Debug|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Debug|x86.Build.0 = Debug|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|ARM.ActiveCfg = Release|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|ARM.Build.0 = Release|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|x64.ActiveCfg = Release|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|x64.Build.0 = Release|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|x86.ActiveCfg = Release|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Release|x86.Build.0 = Release|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|ARM.ActiveCfg = Test|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|ARM.Build.0 = Test|ARM
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|x64.ActiveCfg = Test|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|x64.Build.0 = Test|x64
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|x86.ActiveCfg = Test|Win32
+		{0494C753-5BB9-45AA-874E-E61B9922E88F}.Test|x86.Build.0 = Test|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|ARM.ActiveCfg = Debug|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|ARM.Build.0 = Debug|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|x64.ActiveCfg = Debug|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|x64.Build.0 = Debug|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|x86.ActiveCfg = Debug|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Debug|x86.Build.0 = Debug|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|ARM.ActiveCfg = Release|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|ARM.Build.0 = Release|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|x64.ActiveCfg = Release|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|x64.Build.0 = Release|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|x86.ActiveCfg = Release|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Release|x86.Build.0 = Release|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|ARM.ActiveCfg = Test|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|ARM.Build.0 = Test|ARM
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|x64.ActiveCfg = Test|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|x64.Build.0 = Test|x64
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|x86.ActiveCfg = Test|Win32
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}.Test|x86.Build.0 = Test|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|ARM.ActiveCfg = Debug|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|ARM.Build.0 = Debug|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|x64.ActiveCfg = Debug|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|x64.Build.0 = Debug|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|x86.ActiveCfg = Debug|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Debug|x86.Build.0 = Debug|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|ARM.ActiveCfg = Release|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|ARM.Build.0 = Release|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|x64.ActiveCfg = Release|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|x64.Build.0 = Release|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|x86.ActiveCfg = Release|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Release|x86.Build.0 = Release|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|ARM.ActiveCfg = Test|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|ARM.Build.0 = Test|ARM
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|x64.ActiveCfg = Test|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|x64.Build.0 = Test|x64
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|x86.ActiveCfg = Test|Win32
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847}.Test|x86.Build.0 = Test|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|ARM.ActiveCfg = Debug|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|ARM.Build.0 = Debug|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|x64.ActiveCfg = Debug|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|x64.Build.0 = Debug|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|x86.ActiveCfg = Debug|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Debug|x86.Build.0 = Debug|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|ARM.ActiveCfg = Release|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|ARM.Build.0 = Release|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|x64.ActiveCfg = Release|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|x64.Build.0 = Release|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|x86.ActiveCfg = Release|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Release|x86.Build.0 = Release|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|ARM.ActiveCfg = Test|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|ARM.Build.0 = Test|ARM
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|x64.ActiveCfg = Test|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|x64.Build.0 = Test|x64
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|x86.ActiveCfg = Test|Win32
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}.Test|x86.Build.0 = Test|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -755,6 +877,13 @@ Global
 		{2F6A1847-BFAF-4B8A-9463-AC39FB46B96A} = {984BE359-87F7-4BD7-A823-AD8A59739801}
 		{02D4FD92-AD34-40CA-85DF-4D6C7E3A1F22} = {546172B2-F084-4363-BE35-06010663D319}
 		{F48B3491-81DF-4F49-B35F-3308CBE6A379} = {D8216B93-BD6E-4293-8D98-79CEF7CF66BC}
+		{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
+		{6C6BC844-3D86-42B4-B3C4-7478487D2C38} = {158C8616-750C-4E0E-BD3D-5721D3C555E6}
+		{347824B1-7100-4EE6-8A6B-4FF64E66B0C0} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
+		{0494C753-5BB9-45AA-874E-E61B9922E88F} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
+		{FA9E9590-0E6C-40F9-9527-E608F2DFA76D} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
+		{E14F373D-05A0-4259-A5E9-AFE8405FB847} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
+		{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01} = {6C6BC844-3D86-42B4-B3C4-7478487D2C38}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {1F6CA1BC-6C01-4C82-8505-6A7690EBD556}

+ 45 - 53
CMakeLists.txt

@@ -62,11 +62,9 @@ endif()
 
 if(ICU_SETTINGS_RESET)
     unset(ICU_SETTINGS_RESET CACHE)
-    unset(ICU_INCLUDE_PATH CACHE)
     unset(ICU_INCLUDE_PATH_SH CACHE)
-    unset(NO_ICU_PATH_GIVEN_SH CACHE)
-    unset(NO_ICU_PATH_GIVEN CACHE)
-    unset(CC_EMBED_ICU_SH CACHE)
+    unset(NO_ICU_SH CACHE)
+    unset(LOCAL_ICU_SH CACHE)
 endif()
 
 if(CC_TARGET_OS_ANDROID_SH)
@@ -102,58 +100,55 @@ if (ENABLE_CC_XPLAT_TRACE_SH)
     endif()
 endif()
 
-if(CC_EMBED_ICU_SH)
-    unset(CC_EMBED_ICU_SH CACHE)
-    set(CC_EMBED_ICU 1)
-    set(ICU_INCLUDE_PATH "deps/icu/source/output/include/")
-endif()
-
 if(ICU_INCLUDE_PATH_SH)
     set(ICU_INCLUDE_PATH ${ICU_INCLUDE_PATH_SH})
-    unset(NO_ICU_PATH_GIVEN_SH CACHE)
-    unset(NO_ICU_PATH_GIVEN CACHE)
     unset(ICU_INCLUDE_PATH_SH CACHE)
 endif()
 
-if(NO_ICU_PATH_GIVEN_SH)
-    set(NO_ICU_PATH_GIVEN ${NO_ICU_PATH_GIVEN_SH})
-    unset(NO_ICU_PATH_GIVEN_SH CACHE)
-    unset(ICU_INCLUDE_PATH_SH CACHE)
-    unset(ICU_INCLUDE_PATH CACHE)
+if(NO_ICU_SH)
+    set(NO_ICU 1)
+    unset(NO_ICU_SH CACHE)
 endif()
 
 function(clr_unknown_arch)
     message(FATAL_ERROR "Only AMD64, ARM and I386 are supported")
 endfunction()
 
-if(NOINTL_ICU_SH)
-    unset(NOINTL_ICU_SH CACHE)    # don't cache
-    set(ICU_INTL_DISABLED 1)
+if(INTL_ICU_SH)
+    unset(INTL_ICU_SH CACHE)
+    set(INTL_ICU 1)
+else()
+    unset(INTL_ICU_SH CACHE)
+    set(INTL_ICU 0)
 endif()
 
 if(ICU_INCLUDE_PATH)
     add_definitions(-DHAS_REAL_ICU=1)
-    set(ICU_CC_PATH "${ICU_INCLUDE_PATH}/../lib/")
-    find_library(ICUUC icuuc PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-    if(NOT ICU_INTL_DISABLED)
+    set(ICU_LIBRARY_PATH "${ICU_INCLUDE_PATH}/../lib/")
+    find_library(ICUUC icuuc PATHS ${ICU_LIBRARY_PATH} NO_DEFAULT_PATH)
+
+    if(INTL_ICU)
         add_definitions(-DINTL_ICU=1)
-        find_library(ICU18 icui18n PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-        # icu header files are either located under the same folder or i18n is under a relative path
-        # TODO (unlikely): shall we add `--icu-intl` to build.sh ?
+        find_library(ICUIN icui18n PATHS ${ICU_LIBRARY_PATH} NO_DEFAULT_PATH)
+        # In a default install, ICU header files are all in ICU_ROOT/include
+        # However, for Node, the include/ folder is never generated, so we have to look
+        # in NODE/deps/icu/source/{common|i18n} for headers
         set(ICU_INCLUDE_PATH
-          "${ICU_INCLUDE_PATH}"
-          "${ICU_INCLUDE_PATH}/../i18n/")
+            "${ICU_INCLUDE_PATH}"
+            "${ICU_INCLUDE_PATH}/../i18n/"
+        )
     endif()
+
     if(ICUUC)
-      message("-- found ICU libs: ${ICU_CC_PATH}")
-      find_library(ICUDATA icudata PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-      if (NOT ICUDATA)
-          set(ICUDATA "")
-      endif()
-      set(ICULIB
-        ${ICUUC}
-        ${ICU18}
-        ${ICUDATA}
+        message("-- found ICU libs: ${ICU_LIBRARY_PATH}")
+        find_library(ICUDATA icudata PATHS ${ICU_LIBRARY_PATH} NO_DEFAULT_PATH)
+        if (NOT ICUDATA)
+            set(ICUDATA "")
+        endif()
+        set(ICU_LIBRARIES
+            ${ICUUC}
+            ${ICUIN}
+            ${ICUDATA}
         )
     endif()
 endif()
@@ -194,19 +189,16 @@ if(CAN_BUILD_WABT)
 endif()
 
 if(CC_TARGET_OS_LINUX OR CC_TARGET_OS_ANDROID)
-    if(NOT ICULIB)
-        if(NOT NO_ICU_PATH_GIVEN)
-            if(NOT CC_EMBED_ICU)
-                set(ICULIB "icuuc")
-                if(NOT ICU_INTL_DISABLED)
-                    add_definitions(-DINTL_ICU=1)
-                    set(ICULIB
-                      "${ICULIB}"
-                      "icui18n")
-                endif()
-            endif()
-            add_definitions(-DHAS_REAL_ICU=1)
+    if(SYSTEM_ICU_SH)
+        set(ICU_LIBRARIES "icuuc")
+        if(INTL_ICU)
+            add_definitions(-DINTL_ICU=1)
+            set(ICU_LIBRARIES
+                ${ICU_LIBRARIES}
+                icui18n
+            )
         endif()
+        add_definitions(-DHAS_REAL_ICU=1)
     endif()
 
     set(CLR_CMAKE_PLATFORM_LINUX 1)
@@ -227,8 +219,8 @@ elseif(CC_TARGET_OS_OSX)
     # in case ICU path was given but it doesn't exist, build script will fail.
     # so, fallback only if ICU path wasn't given
     if(NOT ICU_INCLUDE_PATH)
-      set(NO_ICU_PATH_GIVEN 1)
-      message("-- Couldn't find ICU. Falling back to --no-icu build")
+        set(NO_ICU 1)
+        message("-- Couldn't find ICU. Falling back to --no-icu build")
     endif()
 
     if(NOT CC_XCODE_PROJECT)
@@ -360,7 +352,7 @@ if(CLR_CMAKE_PLATFORM_XPLAT)
     # Also disable RTTI when building a shared library
     # TODO: why does the shared library break with rtti disabled?
     if(CMAKE_BUILD_TYPE STREQUAL Release)
-        if(STATIC_LIBRARY OR ICU_INTL_DISABLED)
+        if(STATIC_LIBRARY)
             add_compile_options(-fno-rtti)
         endif()
     endif()
@@ -484,7 +476,7 @@ include_directories(
 
 if(ICU_INCLUDE_PATH)
     if(NOT HAVE_LIBICU_UCHAR_H)
-        set(HAVE_LIBICU_UCHAR_H "1")
+        set(HAVE_LIBICU_UCHAR_H 1)
     endif()
 endif()
 

+ 1 - 1
bin/ChakraCore/CMakeLists.txt

@@ -46,10 +46,10 @@ set(lib_target "${lib_target}"
   -Wl,-undefined,error
   ${LINKER_START_GROUP}
   ChakraCoreStatic
+  ${ICU_LIBRARIES}
   ${LINKER_END_GROUP}
   pthread
   dl
-  ${ICULIB}
   )
 
 if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)

+ 12 - 7
bin/ChakraCore/ChakraCore.vcxproj

@@ -52,13 +52,9 @@
         Rpcrt4.lib;
         $(ChakraCommonLinkDependencies)
       </AdditionalDependencies>
-      <AdditionalDependencies Condition="'$(IntlICU)'=='true'">
-        %(AdditionalDependencies);
-        <!-- TODO cleanup: we do need to link to ICU libraries in ChakraCore, but we probably will not need all of them -->
-        $(IcuLibDir)\icutools.lib;
-        $(IcuLibDir)\icui18n.lib;
-        <!--$(IcuLibDir)\icudata.lib;-->
-        <!--$(IcuLibDir)\icuucx.lib;-->
+      <AdditionalDependencies Condition="'$(UseICU)'=='true' AND '$(ChakraICU)'!='false'">
+        $(IcuLibraryDependencies)
+        %(AdditionalDependencies)
       </AdditionalDependencies>
       <DelayLoadDLLs>%(DelayLoadDLLs);oleaut32.dll</DelayLoadDLLs>
     </Link>
@@ -176,6 +172,15 @@
     <ProjectReference Include="..\..\lib\Runtime\Types\Chakra.Runtime.Types.vcxproj">
       <Project>{706083f7-6aa4-4558-a153-6352ef9110f6}</Project>
     </ProjectReference>
+    <ProjectReference Condition="'$(ChakraICU)'!='false'" Include="..\..\deps\Chakra.ICU\Chakra.ICU.Common.vcxproj">
+      <Project>{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}</Project>
+    </ProjectReference>
+    <ProjectReference Condition="'$(ChakraICU)'!='false'" Include="..\..\deps\Chakra.ICU\Chakra.ICU.i18n.vcxproj">
+      <Project>{0494C753-5BB9-45AA-874E-E61B9922E88F}</Project>
+    </ProjectReference>
+    <ProjectReference Condition="'$(ChakraICU)'!='false'" Include="..\..\deps\Chakra.ICU\Chakra.ICU.Data.vcxproj">
+      <Project>{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}</Project>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="TestHooks.h" />

+ 80 - 80
build.sh

@@ -40,14 +40,17 @@ PRINT_USAGE() {
     echo "     --cxx=PATH        Path to Clang++ (see example below)"
     echo "     --create-deb[=V]  Create .deb package with given V version."
     echo " -d, --debug           Debug build. Default: Release"
-    echo "     --embed-icu       Download and embed ICU-57 statically."
     echo "     --extra-defines=DEF=VAR,DEFINE,..."
     echo "                       Compile with additional defines"
     echo " -h, --help            Show help"
-    echo "     --icu=PATH        Path to ICU include folder (see example below)"
+    echo "     --custom-icu=PATH The path to ICUUC headers"
+    echo "                       If --libs-only --static is not specified,"
+    echo "                       PATH/../lib must be the location of ICU libraries"
+    echo "                       Example: /usr/local/opt/icu4c/include when using ICU from homebrew"
+    echo "     --system-icu      Use the ICU that you installed globally on your machine"
+    echo "     --no-icu          Compile without ICU (disables Unicode and Intl features)"
     echo " -j[=N], --jobs[=N]    Multicore build, allow N jobs at once."
     echo " -n, --ninja           Build with ninja instead of make."
-    echo "     --no-icu          Compile without unicode/icu/intl support."
     echo "     --no-jit          Disable JIT"
     echo "     --libs-only       Do not build CH and GCStress"
     echo "     --lto             Enables LLVM Full LTO"
@@ -61,7 +64,7 @@ PRINT_USAGE() {
     echo "     --target-path[=S] Output path for compiled binaries. Default: out/"
     echo "     --trace           Enables experimental built-in trace."
     echo "     --xcode           Generate XCode project."
-    echo "     --without-intl    --icu arg also enables Intl by default. Disable it."
+    echo "     --without-intl    Disable Intl (ECMA 402) support"
     echo "     --without=FEATURE,FEATURE,..."
     echo "                       Disable FEATUREs from JSRT experimental features."
     echo "     --valgrind        Enable Valgrind support"
@@ -79,7 +82,7 @@ script (at your own risk)"
     echo "example:"
     echo "  ./build.sh --cxx=/path/to/clang++ --cc=/path/to/clang -j"
     echo "with icu:"
-    echo "  ./build.sh --icu=/usr/local/opt/icu4c/include"
+    echo "  ./build.sh --custom-icu=/usr/local/opt/icu4c"
     echo ""
 }
 
@@ -88,14 +91,16 @@ CHAKRACORE_DIR=`pwd -P`
 popd > /dev/null
 _CXX=""
 _CC=""
-_VERBOSE=""
+VERBOSE="0"
 BUILD_TYPE="Release"
 CMAKE_GEN=
 EXTRA_DEFINES=""
 MAKE=make
 MULTICORE_BUILD=""
 NO_JIT=
-ICU_PATH="-DICU_SETTINGS_RESET=1"
+CMAKE_ICU="-DICU_SETTINGS_RESET=1"
+CMAKE_INTL="-DINTL_ICU_SH=1" # default to enabling intl
+USE_LOCAL_ICU=1 # default to using $CHAKRACORE_DIR/deps/Chakra.ICU/icu
 STATIC_LIBRARY="-DSHARED_LIBRARY_SH=1"
 SANITIZE=
 WITHOUT_FEATURES=""
@@ -116,8 +121,7 @@ VALGRIND=0
 # -DCMAKE_EXPORT_COMPILE_COMMANDS=ON useful for clang-query tool
 CMAKE_EXPORT_COMPILE_COMMANDS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
 LIBS_ONLY_BUILD=
-SHOULD_EMBED_ICU=0
-ALWAYS_YES=0
+ALWAYS_YES=
 
 UNAME_S=`uname -s`
 if [[ $UNAME_S =~ 'Linux' ]]; then
@@ -155,17 +159,13 @@ while [[ $# -gt 0 ]]; do
         ;;
 
     -v | --verbose)
-        _VERBOSE="VERBOSE=1"
+        VERBOSE="1"
         ;;
 
     -d | --debug)
         BUILD_TYPE="Debug"
         ;;
 
-    --embed-icu)
-        SHOULD_EMBED_ICU=1
-        ;;
-
     --extra-defines=*)
         DEFINES=$1
         DEFINES=${DEFINES:16}    # value after --extra-defines=
@@ -202,20 +202,27 @@ while [[ $# -gt 0 ]]; do
         fi
         ;;
 
-    --icu=*)
+    --custom-icu=*)
         ICU_PATH=$1
-        # resolve tilde on path
-        eval ICU_PATH="${ICU_PATH:6}"
-        if [[ ! -d ${ICU_PATH} ]]; then
-            if [[ -d "${CHAKRACORE_DIR}/${ICU_PATH}" ]]; then
-                ICU_PATH="${CHAKRACORE_DIR}/${ICU_PATH}"
-            else
-                # if ICU_PATH is given, do not fallback to no-icu
-                echo "!!! couldn't find ICU at $ICU_PATH"
-                exit 1
-            fi
+        # `eval` used to resolve tilde in the path
+        eval ICU_PATH="${ICU_PATH:13}"
+        if [[ ! -d $ICU_PATH || ! -d $ICU_PATH/unicode ]]; then
+            # if --custom-icu is given, do not fallback to no-icu
+            echo "!!! couldn't find ICU at $ICU_PATH"
+            exit 1
         fi
-        ICU_PATH="-DICU_INCLUDE_PATH_SH=${ICU_PATH}"
+        CMAKE_ICU="-DICU_INCLUDE_PATH_SH=$ICU_PATH"
+        USE_LOCAL_ICU=0
+        ;;
+
+    --system-icu)
+        CMAKE_ICU="-DSYSTEM_ICU_SH=1"
+        USE_LOCAL_ICU=0
+        ;;
+
+    --no-icu)
+        CMAKE_ICU="-DNO_ICU_SH=1"
+        USE_LOCAL_ICU=0
         ;;
 
     --libs-only)
@@ -242,16 +249,12 @@ while [[ $# -gt 0 ]]; do
         MAKE=ninja
         ;;
 
-    --no-icu)
-        ICU_PATH="-DNO_ICU_PATH_GIVEN_SH=1"
-        ;;
-
     --no-jit)
         NO_JIT="-DNO_JIT_SH=1"
         ;;
 
     --without-intl)
-        INTL_ICU="-DNOINTL_ICU_SH=1"
+        CMAKE_INTL="-DINTL_ICU_SH=0"
         ;;
 
     --xcode)
@@ -351,7 +354,7 @@ while [[ $# -gt 0 ]]; do
         ;;
 
     -y | -Y)
-        ALWAYS_YES=1
+        ALWAYS_YES=-y
         ;;
 
     *)
@@ -364,64 +367,61 @@ while [[ $# -gt 0 ]]; do
     shift
 done
 
-if [[ $SHOULD_EMBED_ICU == 1 ]]; then
-    if [ ! -d "${CHAKRACORE_DIR}/deps/icu/source/output" ]; then
-        ICU_URL="http://source.icu-project.org/repos/icu/icu/tags/release-57-1"
-        echo -e "\n----------------------------------------------------------------"
-        echo -e "\nThis script will download ICU-LIB from\n${ICU_URL}\n"
-        echo "It is licensed to you by its publisher, not Microsoft."
-        echo "Microsoft is not responsible for the software."
-        echo "Your installation and use of ICU-LIB is subject to the publisher's terms available here:"
-        echo -e "http://www.unicode.org/copyright.html#License\n"
-        echo -e "----------------------------------------------------------------\n"
-        echo "If you don't agree, press Ctrl+C to terminate"
-        WAIT_QUESTION="Hit ENTER to continue (or wait 10 seconds)"
-        if [[ $ALWAYS_YES == 1 ]]; then
-            echo "$WAIT_QUESTION : Y"
-        else
-            read -t 10 -p "$WAIT_QUESTION"
-        fi
+if [[ $USE_LOCAL_ICU == 1 ]]; then
+    LOCAL_ICU_DIR="$CHAKRACORE_DIR/deps/Chakra.ICU/icu"
+    if [[ ! -d $LOCAL_ICU_DIR ]]; then
+        python "$CHAKRACORE_DIR/tools/configure_icu.py" 57.1 $ALWAYS_YES
+    fi
 
-        SAFE_RUN `mkdir -p ${CHAKRACORE_DIR}/deps/`
-        cd "${CHAKRACORE_DIR}/deps/";
-        ABS_DIR=`pwd`
-        if [ ! -d "${ABS_DIR}/icu/" ]; then
-            echo "Downloading ICU ${ICU_URL}"
-            if [ ! -f "/usr/bin/svn" ]; then
-                echo -e "\nYou should install 'svn' client in order to use this feature"
-                if [ $OS_APT_GET == 1 ]; then
-                    echo "tip: Try 'sudo apt-get install subversion'"
-                fi
-                exit 1
-            fi
-            svn export -q $ICU_URL icu
-            ERROR_EXIT "rm -rf ${ABS_DIR}/icu/"
-        fi
+    LOCAL_ICU_DIST="$LOCAL_ICU_DIR/output"
 
-        cd "${ABS_DIR}/icu/source";./configure --with-data-packaging=static\
-                --prefix="${ABS_DIR}/icu/source/output/"\
-                --enable-static --disable-shared --with-library-bits=64\
-                --disable-icuio --disable-layout\
-                CXXFLAGS="-fPIC" CFLAGS="-fPIC"
+    if [ ! -d "$LOCAL_ICU_DIST" ]; then
+        set -e
 
-        ERROR_EXIT "rm -rf ${ABS_DIR}/icu/source/output/"
+        pushd "$LOCAL_ICU_DIR"
+
+        ./configure --with-data-packaging=static\
+                    --prefix="$LOCAL_ICU_DIST"\
+                    --enable-static\
+                    --disable-shared\
+                    --with-library-bits=64\
+                    --disable-icuio\
+                    --disable-layout\
+                    CXXFLAGS="-fPIC"\
+                    CFLAGS="-fPIC"
+
+        ERROR_EXIT "rm -rf $LOCAL_ICU_DIST"
         make STATICCFLAGS="-fPIC" STATICCXXFLAGS="-fPIC" STATICCPPFLAGS="-DPIC" install
-        ERROR_EXIT "rm -rf ${ABS_DIR}/icu/source/output/"
-        cd "${ABS_DIR}/../"
+        ERROR_EXIT "rm -rf $LOCAL_ICU_DIST"
+        popd
+    fi
+    CMAKE_ICU="-DICU_INCLUDE_PATH_SH=$LOCAL_ICU_DIST/include"
+fi
+
+if [[ "$MAKE" == "ninja" ]]; then
+    if [[ "$VERBOSE" == "1" ]]; then
+        VERBOSE="-v"
+    else
+        VERBOSE=""
+    fi
+else
+    if [[ "$VERBOSE" == "1" ]]; then
+        VERBOSE="VERBOSE=1"
+    else
+        VERBOSE=""
     fi
-    ICU_PATH="-DCC_EMBED_ICU_SH=1"
 fi
 
-if [[ ${#_VERBOSE} > 0 ]]; then
+if [[ "$VERBOSE" != "0" ]]; then
     # echo options back to the user
     echo "Printing command line options back to the user:"
     echo "_CXX=${_CXX}"
     echo "_CC=${_CC}"
     echo "BUILD_TYPE=${BUILD_TYPE}"
     echo "MULTICORE_BUILD=${MULTICORE_BUILD}"
-    echo "ICU_PATH=${ICU_PATH}"
+    echo "CMAKE_ICU=${CMAKE_ICU}"
     echo "CMAKE_GEN=${CMAKE_GEN}"
-    echo "MAKE=${MAKE} $_VERBOSE"
+    echo "MAKE=${MAKE} $VERBOSE"
     echo ""
 fi
 
@@ -619,8 +619,8 @@ fi
 
 echo Generating $BUILD_TYPE makefiles
 echo $EXTRA_DEFINES
-cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $LTO $LTTNG $STATIC_LIBRARY $ARCH $TARGET_OS \
-    $ENABLE_CC_XPLAT_TRACE $EXTRA_DEFINES -DCMAKE_BUILD_TYPE=$BUILD_TYPE $SANITIZE $NO_JIT $INTL_ICU \
+cmake $CMAKE_GEN $CC_PREFIX $CMAKE_ICU $LTO $LTTNG $STATIC_LIBRARY $ARCH $TARGET_OS \
+    $ENABLE_CC_XPLAT_TRACE $EXTRA_DEFINES -DCMAKE_BUILD_TYPE=$BUILD_TYPE $SANITIZE $NO_JIT $CMAKE_INTL \
     $WITHOUT_FEATURES $WB_FLAG $WB_ARGS $CMAKE_EXPORT_COMPILE_COMMANDS $LIBS_ONLY_BUILD\
     $VALGRIND $BUILD_RELATIVE_DIRECTORY
 
@@ -634,9 +634,9 @@ if [[ $? == 0 ]]; then
                 # Get -j flag from the host
                 MULTICORE_BUILD=""
             fi
-            $MAKE $MFLAGS $MULTICORE_BUILD $_VERBOSE $WB_TARGET 2>&1 | tee build.log
+            $MAKE $MFLAGS $MULTICORE_BUILD $VERBOSE $WB_TARGET 2>&1 | tee build.log
         else
-            $MAKE $MULTICORE_BUILD $_VERBOSE $WB_TARGET 2>&1 | tee build.log
+            $MAKE $MULTICORE_BUILD $VERBOSE $WB_TARGET 2>&1 | tee build.log
         fi
         _RET=${PIPESTATUS[0]}
     else

+ 32 - 0
deps/Chakra.ICU/Chakra.ICU.Build.props

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <!-- ICU warning output is exceptionally noisy -->
+      <WarningLevel>TurnOffAllWarnings</WarningLevel>
+      <TreatWarningAsError>false</TreatWarningAsError>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+
+      <PreprocessorDefinitions Condition="'$(ChakraICU)'!='shared'">
+        U_STATIC_IMPLEMENTATION=1;
+        %(PreprocessorDefinitions)
+      </PreprocessorDefinitions>
+
+      <!-- These are mostly similar definitions to those used by Node -->
+      <PreprocessorDefinitions>
+        UCONFIG_NO_BREAK_ITERATION=1;
+        UCONFIG_NO_REGULAR_EXPRESSIONS=1;
+        UCONFIG_NO_SERVICE=1;
+        %(PreprocessorDefinitions)
+      </PreprocessorDefinitions>
+
+      <!-- Default ICU Configuration (see source\common\common.vcxproj) -->
+      <!-- Note that we already configure most of what common.vcxproj handles elsewhere -->
+      <PreprocessorDefinitions>
+        U_ATTRIBUTE_DEPRECATED=;
+        _CRT_SECURE_NO_DEPRECATE;
+        %(PreprocessorDefinitions)
+      </PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+</Project>

+ 38 - 0
deps/Chakra.ICU/Chakra.ICU.Common.vcxproj

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.Common</TargetName>
+    <ProjectGuid>{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.Common</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType Condition="'$(ChakraICU)'!='shared'">StaticLibrary</ConfigurationType>
+    <ConfigurationType Condition="'$(ChakraICU)'=='shared'">DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>
+        %(PreprocessorDefinitions);
+        U_COMMON_IMPLEMENTATION=1
+      </PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <ClCompile Include="$(IcuCommonSources)" />
+    <ClInclude Include="$(IcuCommonHeaders)" />
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 38 - 0
deps/Chakra.ICU/Chakra.ICU.Data.vcxproj

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.Data</TargetName>
+    <ProjectGuid>{347824B1-7100-4EE6-8A6B-4FF64E66B0C0}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.Data</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType Condition="'$(ChakraICU)'!='shared'">StaticLibrary</ConfigurationType>
+    <ConfigurationType Condition="'$(ChakraICU)'=='shared'">DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <GenCCodePath>$(OutBaseDir)\bin\$(PlatformPathName.ToLower())_$(Configuration.ToLower())\Chakra.ICU.GenCCode.exe</GenCCodePath>
+  </PropertyGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <None Include="$(IntDir)icudt$(IcuVersionMajor)l_dat.obj" /> <!-- forces the automagic build system to create a lib from the obj -->
+    <CustomBuild Include="$(MSBuildThisFileDirectory)source\data\in\icudt$(IcuVersionMajor)l.dat">
+      <Command>$(GenCCodePath) --object --destdir $(IntDir) --entrypoint icudt$(IcuVersionMajor) $(IcuSourceDirectory)\data\in\icudt$(IcuVersionMajor)l.dat</Command>
+      <Outputs>$(IntDir)icudt$(IcuVersionMajor)l_dat.obj</Outputs>
+    </CustomBuild>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)Chakra.ICU.GenCCode.vcxproj">
+      <Project>{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 59 - 0
deps/Chakra.ICU/Chakra.ICU.GenCCode.vcxproj

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.GenCCode</TargetName>
+    <ProjectGuid>{FA9E9590-0E6C-40F9-9527-E608F2DFA76D}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.GenCCode</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>
+        %(AdditionalIncludeDirectories);
+        $(IcuSourceDirectory)\common;
+        $(IcuSourceDirectory)\i18n;
+        $(IcuSourceDirectory)\tools\toolutil
+      </AdditionalIncludeDirectories>
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <ClCompile Include="$(IcuGenccodeSources)" />
+    <ClInclude Include="$(IcuGenccodeHeaders)" />
+    <ProjectReference Include="$(MSBuildThisFileDirectory)Chakra.ICU.Common.vcxproj">
+      <Project>{EE2A3111-4D85-427C-B0AB-E6B0EA7FFB44}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)Chakra.ICU.i18n.vcxproj">
+      <Project>{0494C753-5BB9-45AA-874E-E61B9922E88F}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)Chakra.ICU.Toolutil.vcxproj">
+      <Project>{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)Chakra.ICU.Stubdata.vcxproj">
+      <Project>{E14F373D-05A0-4259-A5E9-AFE8405FB847}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 42 - 0
deps/Chakra.ICU/Chakra.ICU.Stubdata.vcxproj

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.Stubdata</TargetName>
+    <ProjectGuid>{E14F373D-05A0-4259-A5E9-AFE8405FB847}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.Stubdata</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>
+        %(PreprocessorDefinitions);
+        STUBDATA_BUILD=1
+      </PreprocessorDefinitions>
+
+      <AdditionalIncludeDirectories>
+        %(AdditionalIncludeDirectories);
+        $(IcuSourceDirectory)\common
+      </AdditionalIncludeDirectories>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <ClCompile Include="$(IcuStubdataSources)" />
+    <ClInclude Include="$(IcuStubdataHeaders)" />
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 43 - 0
deps/Chakra.ICU/Chakra.ICU.Toolutil.vcxproj

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.Toolutil</TargetName>
+    <ProjectGuid>{A87105AD-8F4A-4D7A-9096-EFD30DBA3E01}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.Toolutil</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>
+        %(PreprocessorDefinitions);
+        U_TOOLUTIL_IMPLEMENTATION=1
+      </PreprocessorDefinitions>
+
+      <AdditionalIncludeDirectories>
+        %(AdditionalIncludeDirectories);
+        $(IcuSourceDirectory)\common;
+        $(IcuSourceDirectory)\i18n
+      </AdditionalIncludeDirectories>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <ClCompile Include="$(IcuToolutilSources)" />
+    <ClInclude Include="$(IcuToolutilHeaders)" />
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 46 - 0
deps/Chakra.ICU/Chakra.ICU.i18n.vcxproj

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.props" />
+  <PropertyGroup Label="Globals">
+    <TargetName>Chakra.ICU.i18n</TargetName>
+    <ProjectGuid>{0494C753-5BB9-45AA-874E-E61B9922E88F}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>Chakra.ICU.i18n</ProjectName>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType Condition="'$(ChakraICU)'!='shared'">StaticLibrary</ConfigurationType>
+    <ConfigurationType Condition="'$(ChakraICU)'=='shared'">DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.props" />
+  <Import Project="$(MSBuildThisFileDirectory)Chakra.ICU.Build.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>
+        %(PreprocessorDefinitions);
+        U_I18N_IMPLEMENTATION=1
+      </PreprocessorDefinitions>
+
+      <AdditionalIncludeDirectories>
+        %(AdditionalIncludeDirectories);
+        $(IcuSourceDirectory)\common
+      </AdditionalIncludeDirectories>
+
+      <!-- Some ICU files use embedded UTF-8 -->
+      <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup Condition="'$(ChakraICU)'!='false'">
+    <ClCompile Include="$(IcuI18nSources)" />
+    <ClInclude Include="$(IcuI18nHeaders)" />
+  </ItemGroup>
+  <Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 0 - 6
lib/Runtime/Base/WindowsGlobalizationAdapter.cpp

@@ -459,12 +459,6 @@ if (this->object) \
         }
     }
 
-    void WindowsGlobalizationAdapter::ResetTimeZoneFactoryObjects()
-    {
-        DetachAndReleaseFactoryObjects(timeZoneCalendar);
-        DetachAndReleaseFactoryObjects(defaultTimeZoneCalendar);
-    }
-
     void WindowsGlobalizationAdapter::ResetDateTimeFormatFactoryObjects()
     {
         // Reset only if its not initialized completely.

+ 0 - 1
lib/Runtime/Base/WindowsGlobalizationAdapter.h

@@ -127,7 +127,6 @@ namespace Js
         HRESULT GetClock(_In_ Windows::Globalization::DateTimeFormatting::IDateTimeFormatter* formatter, HSTRING * hClock);
         HRESULT GetItemAt(_In_ Windows::Foundation::Collections::IVectorView<HSTRING>* vector, _In_ uint32 index, HSTRING * item);
         void ResetCommonFactoryObjects();
-        void ResetTimeZoneFactoryObjects();
         void ResetDateTimeFormatFactoryObjects();
         void ResetNumberFormatFactoryObjects();
 #endif // ENABLE_INTL_OBJECT

+ 7 - 1
lib/Runtime/Library/Chakra.Runtime.Library.vcxproj

@@ -2,6 +2,7 @@
 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
   <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Condition="'$(ChakraICU)'!='false'" Project="$(ChakraCoreRootDirectory)deps\Chakra.ICU\Chakra.ICU.props" />
   <PropertyGroup Label="Globals">
     <TargetName>Chakra.Runtime.Library</TargetName>
     <ProjectGuid>{706083F7-6AA4-4558-A153-6352EF9110F7}</ProjectGuid>
@@ -153,7 +154,12 @@
     <ClCompile Include="$(MSBuildThisFileDirectory)SubString.cpp" />
     <ClCompile Include="$(MSBuildThisFileDirectory)UriHelper.cpp" />
     <ClCompile Include="$(MSBuildThisFileDirectory)ExternalLibraryBase.cpp" />
-    <ClCompile Include="$(MSBuildThisFileDirectory)IntlEngineInterfaceExtensionObject.cpp" />
+    <ClCompile Include="$(MSBuildThisFileDirectory)IntlEngineInterfaceExtensionObject.cpp">
+      <AdditionalIncludeDirectories Condition="'$(IcuIncludeDirectories)'!=''">
+        $(IcuIncludeDirectories);
+        %(AdditionalIncludeDirectories)
+      </AdditionalIncludeDirectories>
+    </ClCompile>
     <ClCompile Include="$(MSBuildThisFileDirectory)JsBuiltInEngineInterfaceExtensionObject.cpp" />
     <ClCompile Include="$(MSBuildThisFileDirectory)WasmLibrary.cpp" />
     <ClCompile Include="$(MSBuildThisFileDirectory)JavascriptListIterator.cpp" />

+ 11 - 9
lib/Runtime/Library/IntlEngineInterfaceExtensionObject.cpp

@@ -22,16 +22,18 @@ using namespace Windows::Globalization;
 #include <CommonPal.h>
 #include "PlatformAgnostic/IPlatformAgnosticResource.h"
 using namespace PlatformAgnostic::Resource;
-#define U_STATIC_IMPLEMENTATION
-#define U_SHOW_CPLUSPLUS_API 0
-#include <unicode/ucol.h>
-#include <unicode/udat.h>
-#include <unicode/unum.h>
-#include <unicode/unumsys.h>
+#include "PlatformAgnostic/ICU.h"
 
 #define ICU_ERROR_FMT _u("INTL: %S failed with error code %S\n")
 #define ICU_EXPR_FMT _u("INTL: %S failed expression check %S\n")
 
+// Different assertion code is used in ChakraFull that enforces that messages are char literals
+#ifdef _CHAKRACOREBUILD
+#define ICU_ERRORMESSAGE(e) u_errorName(e)
+#else
+#define ICU_ERRORMESSAGE(e) "Bad status returned from ICU"
+#endif
+
 #ifdef INTL_ICU_DEBUG
 #define ICU_DEBUG_PRINT(fmt, msg) Output::Print(fmt, __func__, (msg))
 #else
@@ -45,12 +47,12 @@ using namespace PlatformAgnostic::Resource;
     {                                                                         \
         if (ICU_FAILURE(e))                                                   \
         {                                                                     \
-            ICU_DEBUG_PRINT(ICU_ERROR_FMT, u_errorName(e));                   \
-            AssertOrFailFastMsg(false, u_errorName(e));                       \
+            ICU_DEBUG_PRINT(ICU_ERROR_FMT, ICU_ERRORMESSAGE(e));              \
+            AssertOrFailFastMsg(false, ICU_ERRORMESSAGE(e));                  \
         }                                                                     \
         else if (!(expr))                                                     \
         {                                                                     \
-            ICU_DEBUG_PRINT(ICU_EXPR_FMT, u_errorName(e));                    \
+            ICU_DEBUG_PRINT(ICU_EXPR_FMT, ICU_ERRORMESSAGE(e));               \
             AssertOrFailFast(expr);                                           \
         }                                                                     \
     } while (false)

+ 0 - 9
lib/Runtime/Library/RuntimeLibraryPch.h

@@ -97,15 +97,6 @@
 #include "Library/ConcatString.inl"
 #include "Language/CacheOperators.inl"
 
-#ifdef INTL_ICU
-#define U_STATIC_IMPLEMENTATION
-#define U_SHOW_CPLUSPLUS_API 0
-#pragma warning(push)
-#pragma warning(disable:4995)
-#include <unicode/uloc.h>
-#pragma warning(pop)
-#endif
-
 #endif // !IsJsDiag
 
 #ifdef IsJsDiag

+ 8 - 2
lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj

@@ -2,6 +2,7 @@
 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
   <Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
+  <Import Condition="'$(ChakraICU)'!='false'" Project="$(ChakraCoreRootDirectory)deps\Chakra.ICU\Chakra.ICU.props" />
   <PropertyGroup Label="Globals">
     <TargetName>Chakra.Runtime.PlatformAgnostic</TargetName>
     <ProjectGuid>{129ac184-877c-441f-ac49-a692ce700e62}</ProjectGuid>
@@ -33,6 +34,10 @@
         $(MSBuildThisFileDirectory);
         %(AdditionalIncludeDirectories)
       </AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories Condition="'$(IcuIncludeDirectories)'!=''">
+        $(IcuIncludeDirectories);
+        %(AdditionalIncludeDirectories)
+      </AdditionalIncludeDirectories>
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>RuntimePlatformAgnosticPch.h</PrecompiledHeaderFile>
     </ClCompile>
@@ -51,7 +56,7 @@
     <ClCompile Include="$(MSBuildThisFileDirectory)Platform\Common\UnicodeText.Common.cpp" />
     <ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\PerfTrace.cpp" />
   </ItemGroup>
-  <ItemGroup Condition="'$(IntlICU)'=='true'">
+  <ItemGroup Condition="'$(EnableIntl)'=='true' AND '$(UseICU)'=='true'">
     <ClCompile Include="$(MSBuildThisFileDirectory)Platform\Common\Intl.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -61,8 +66,9 @@
     <ClInclude Include="UnicodeText.h" />
     <ClInclude Include="IPlatformAgnosticResource.h" />
   </ItemGroup>
-  <ItemGroup Condition="'$(IntlICU)'=='true'">
+  <ItemGroup Condition="'$(EnableIntl)'=='true' AND '$(UseICU)'=='true'">
     <ClInclude Include="Intl.h" />
+    <ClInclude Include="ICU.h" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\JITIDL\Chakra.JITIDL.vcxproj">

+ 20 - 0
lib/Runtime/PlatformAgnostic/ICU.h

@@ -0,0 +1,20 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+#pragma once
+
+#ifdef INTL_ICU // TODO(jahorto): this needs to eventually be HAS_ICU, but HAS_ICU (HAS_REAL_ICU) and ENABLE_GLOBALIZATION conflict
+#ifdef WINDOWS10_ICU
+#include <icu.h>
+#else
+#define U_STATIC_IMPLEMENTATION 1
+#define U_SHOW_CPLUSPLUS_API 0
+#include "unicode/ucal.h"
+#include "unicode/ucol.h"
+#include "unicode/udat.h"
+#include "unicode/udatpg.h"
+#include "unicode/uloc.h"
+#include "unicode/unumsys.h"
+#endif
+#endif

+ 1 - 18
lib/Runtime/PlatformAgnostic/Platform/Common/Intl.cpp

@@ -42,19 +42,9 @@ typedef uint64_t uint64;
 #include "Core/AllocSizeMath.h"
 
 #include "Intl.h"
+#include "ICU.h"
 #include "IPlatformAgnosticResource.h"
 
-#define U_STATIC_IMPLEMENTATION
-#define U_SHOW_CPLUSPLUS_API 1
-#include <unicode/uloc.h>
-#include <unicode/numfmt.h>
-#include <unicode/enumset.h>
-#include <unicode/decimfmt.h>
-#include <unicode/ucol.h>
-#include <unicode/ucal.h>
-#include <unicode/udat.h>
-#include <unicode/udatpg.h>
-
 #include "CommonDefines.h" // INTL_ICU_DEBUG
 
 #if defined(__GNUC__) || defined(__clang__)
@@ -170,13 +160,6 @@ namespace Intl
 {
     using namespace PlatformAgnostic::Resource;
 
-    // This file uses dynamic_cast and RTTI
-    // While most of ChakraCore has left this feature disabled for a number of reasons, ICU uses it heavily internally
-    // For instance, in creating NumberFormats, the documentation recommends the use of the NumberFormat::create* factory methods
-    // However, to use attributes and significant digits, you must be working with a DecimalFormat
-    // NumberFormat offers no indicator fields or convenience methods to convert to a DecimalFormat, as ICU expects RTTI to be enabled
-    // As such, RTTI is enabled only in the PlatformAgnostic project and only if IntlICU=true
-
     // lots of logic below requires utf8char_t ~= char and UChar ~= char16
     static_assert(sizeof(utf8char_t) == sizeof(char), "ICU-based Intl logic assumes that utf8char_t is compatible with char");
 

+ 227 - 0
tools/configure_icu.py

@@ -0,0 +1,227 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+import hashlib
+import os
+import shutil
+import sys
+import tarfile
+import urllib
+import urllib2
+from zipfile import ZipFile
+from argparse import ArgumentParser
+
+# Parse Makefile.in to find the OBJECTS = ... list of object files
+# This is the officially recommended way of integrating ICU into a large project's build system
+def get_sources(icuroot, mkin_path):
+    # ignore these files, similar to Node
+    ignore = [
+        "source/tools/toolutil/udbgutil.cpp",
+        "source/tools/toolutil/dbgutil.cpp",
+    ]
+    ignore = [os.path.join(icuroot, os.path.normpath(source)) for source in ignore]
+
+    def get_source(object_path):
+        base = os.path.splitext(object_path)[0]
+        cpp = base + ".cpp"
+        c = base + ".c"
+
+        # return None if we find a source but explicitly exclude it, compared
+        # to raising an exception if a source is referenced that doesn't exist,
+        # since that is more likely to be an issue with the source/ folder
+        if cpp in ignore or c in ignore:
+            return None
+
+        if os.path.isfile(cpp):
+            return cpp
+        elif os.path.isfile(c):
+            return c
+
+        raise Exception("%s has no corresponding source file" % object_path)
+
+    with open(mkin_path, "r") as mkin_contents:
+        in_objs = False
+        sources = []
+
+        for line in mkin_contents:
+            line = line.strip()
+
+            if line[:7] == "OBJECTS":
+                in_objs = True
+                # trim " = " in "OBJECTS = {object files}"
+                line = line[10:]
+
+            elif in_objs == True and len(line) == 0:
+                # done with OBJECTS, return
+                return sources
+
+            if in_objs == True:
+                # trim " \" in "{object files} \"
+                linelen = len(line)
+                line = line[:linelen - 1].strip() if line[linelen - 1] == "\\" else line
+
+                objects = map(lambda o: os.path.join(os.path.dirname(mkin_path), o), line.split())
+                cpps = map(get_source, objects)
+                cpps = filter(lambda cpp: cpp != None, cpps)
+                sources.extend(cpps)
+
+        # should have returned by now
+        raise Exception("Could not extract sources from %s" % mkin_path)
+
+def get_headers(icuroot, headers_path):
+    # ignore these files, similar to Node
+    ignore = [
+        "source/tools/toolutil/udbgutil.h",
+        "source/tools/toolutil/dbgutil.h",
+    ]
+    ignore = [os.path.join(icuroot, os.path.normpath(source)) for source in ignore]
+
+    if not os.path.isdir(headers_path):
+        raise Exception("%s is not a valid headers path" % headers_path)
+
+    headers = map(lambda h: os.path.join(headers_path, h), os.listdir(headers_path))
+    headers = filter(lambda h: os.path.splitext(h)[1] == ".h", headers) # only include .h files
+    headers = filter(lambda h: h not in ignore, headers) # don't include ignored headers
+    return headers
+
+def create_msvc_props(chakra_icu_root, icu_sources_root, version):
+    prelude = """<?xml version="1.0" encoding="utf-8"?>
+<!-- DO NOT EDIT THIS FILE. It is auto-generated by $ChakraCore/tools/%s -->
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>""" % os.path.basename(__file__)
+
+    prop_template = """
+    <Icu{0}{1}>
+      {2}
+    </Icu{0}{1}>"""
+
+    conclusion = """
+  </PropertyGroup>
+</Project>
+"""
+    joiner = ";\n      "
+
+    def add_props(propfile, deproot, dep):
+        sources = get_sources(icu_sources_root, os.path.join(deproot, dep, "Makefile.in"))
+        sources_prop = prop_template.format(dep.capitalize(), "Sources", joiner.join(sources))
+        propfile.write(sources_prop)
+
+        headers = get_headers(icu_sources_root, os.path.join(deproot, dep))
+        headers_prop = prop_template.format(dep.capitalize(), "Headers", joiner.join(headers))
+        propfile.write(headers_prop)
+
+    with open(os.path.join(chakra_icu_root, "Chakra.ICU.props"), "w") as propfile:
+        propfile.write(prelude)
+
+        # Write all of the sources and header files to Icu${Dep}${DepKind}, such as IcuCommonSources
+        sourceroot = os.path.join(icu_sources_root, "source")
+        for dep in ["common", "i18n", "stubdata"]:
+            add_props(propfile, sourceroot, dep)
+
+        # tools are handled somewhat differently, since theyre in source/tools
+        toolsroot = os.path.join(sourceroot, "tools")
+        for dep in ["toolutil", "genccode"]:
+            add_props(propfile, toolsroot, dep)
+
+        version_parts = version.split(".")
+        no_newline_prop_template = "\n    <Icu{0}>{1}</Icu{0}>"
+        propfile.write(no_newline_prop_template.format("VersionMajor", version_parts[0]))
+        propfile.write(no_newline_prop_template.format("VersionMinor", version_parts[1] if len(version_parts) > 1 else "0"))
+
+        propfile.write(no_newline_prop_template.format("SourceDirectory", sourceroot))
+
+        include_dirs = [os.path.join(sourceroot, component) for component in ["common", "i18n"]]
+        propfile.write(prop_template.format("Include", "Directories", joiner.join(include_dirs)))
+
+        propfile.write(conclusion)
+
+def download_icu(icuroot, version, yes):
+    # download either the zip or tar, depending on the os
+    extension = "zip" if os.name == "nt" else "tgz"
+
+    archive_file = "icu4c-{0}-src.{1}".format(version.replace(".", "_"), extension)
+    md5_file = "icu4c-src-{0}.md5".format(version.replace(".", "_"))
+
+    archive_url = "http://download.icu-project.org/files/icu4c/{0}/{1}".format(version, archive_file)
+    md5_url = "https://ssl.icu-project.org/files/icu4c/{0}/{1}".format(version, md5_file)
+
+    license_confirmation = """
+{1}
+This script downloads ICU from {0}.
+It is licensed to you by its publisher, not Microsoft.
+Microsoft is not responsible for the software.
+Your installation and use of ICU is subject to the publisher's terms,
+which are available here: http://www.unicode.org/copyright.html#License
+{1}
+""".format(archive_url, "-" * 80)
+    if not yes:
+        print(license_confirmation)
+        response = raw_input("Do you agree to these terms? [Y/n] ")
+        if response != "" and response != "y" and response != "Y":
+            sys.exit(0)
+
+    print("Downloading ICU from %s" % archive_url)
+
+    archive_path = urllib.urlretrieve(archive_url)[0]
+
+    print("Downloaded ICU to %s" % archive_path)
+
+    # check the hash of the download zipfile/tarball
+    checksum = ""
+    with open(archive_path, "rb") as download:
+        md5 = hashlib.md5()
+        md5.update(download.read())
+        checksum = md5.hexdigest()
+
+    md5_path = os.path.join(icuroot, md5_file)
+    md5_request = urllib2.urlopen(md5_url)
+    md5s = md5_request.read().decode("ascii").split("\n")
+    relevant_md5 = filter(lambda line: line[len(line) - len(archive_file):] == archive_file, md5s)
+    if len(relevant_md5) != 1:
+        raise Exception("Could not find md5 hash for %s in %s" % archive_file, md5_url)
+
+    correct_hash = relevant_md5[0]
+    correct_hash = correct_hash.split(" ")[0]
+    if (correct_hash == checksum):
+        print("MD5 checksums match, continuing")
+        return archive_path
+    else:
+        raise Exception("MD5 checksums do not match. Expected %s, got %s" % correct_hash, checksum)
+
+def extract_icu(icuroot, archive_path):
+    tempdir = os.path.normpath(os.path.join(icuroot, "temp"))
+    print("Extracting ICU to %s" % tempdir)
+    opener = ZipFile if os.name == "nt" else tarfile.open
+    with opener(archive_path, "r") as archive:
+        archive.extractall(tempdir)
+
+    icu_folder = os.path.join(icuroot, "icu")
+    if os.path.isdir(icu_folder):
+        shutil.rmtree(icu_folder)
+
+    shutil.move(os.path.join(tempdir, "icu"), icu_folder)
+    shutil.rmtree(tempdir)
+
+def main():
+    chakra_icu_root = os.path.normpath(os.path.join(os.path.realpath(__file__), "..", "..", "deps", "Chakra.ICU"))
+
+    argparser = ArgumentParser(description = "Download and set up ICU for use in ChakraCore")
+    argparser.add_argument("-y", "--yes", action = "store_true", help = "Skip ICU License prompt text")
+    argparser.add_argument("version", help = "ICU version to download. Not compatible with --archive")
+    argparser.add_argument("-i", "--icu-root",
+        help = "Path to directory to extract ICU to. Resulting directory will contain a single subfolder, 'icu', which contains ICU's source tree",
+        default = chakra_icu_root
+    )
+    argparser.add_argument("-a", "--archive", help = "Path to icu.zip (Windows) or icu.tar (POSIX) that you have already downloaded")
+    args = argparser.parse_args()
+
+    archive_path = args.archive
+    if args.version is not None and args.archive is None:
+        archive_path = download_icu(args.icu_root, args.version, args.yes)
+
+    extract_icu(args.icu_root, archive_path)
+    if os.name == "nt":
+        create_msvc_props(chakra_icu_root, os.path.join(args.icu_root, "icu"), args.version)
+
+if __name__ == "__main__":
+    main()