Repository navigation
Pass CMAKE_ICU_DIR headers to System.Globalization.Native configure checks - #135572
Conversation
When CMAKE_ICU_DIR is set on a Unix target other than Android, Apple,
Browser and WASI, CMakeLists.txt skips find_path(UCURR_H) and adds
${CMAKE_ICU_DIR}/include only after configure.cmake has run. The
configure checks then compile without the ICU headers from that
directory: with no system ICU headers, config.h gets 0 for both
HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS and HAVE_UCOL_CLONE, and with
system headers installed the checks read those instead.
Add ${CMAKE_ICU_DIR}/include to CMAKE_REQUIRED_INCLUDES for the checks
when CMAKE_ICU_DIR is defined.
Fix dotnet#135571
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-system-globalization |
|
@caraioniurie47 Could With the normal ICU configuration, Is ICU without symbol renaming intended to be supported through |
|
CC @janvorli |
@tarekgh Thanks. In this repo only the wasm build sets |
With ICU symbol renaming disabled, ucol_clone is a function declaration rather than a macro, so check_symbol_exists also links the test program. On the CMAKE_ICU_DIR path ICUUC and ICUI18N are never set, so that link fails and HAVE_UCOL_CLONE is 0 although the ICU provides ucol_clone. When CMAKE_ICU_DIR is defined, build the check as a static library, so it only compiles. The headers and the libraries come from the same directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@tarekgh Confirmed: with renaming disabled the check still gave
I chose compile-only because a link check has to list ICU's dependencies in link order: the same archives in the order Note AI-generated, written at my direction and reviewed by me before posting. |
When
CMAKE_ICU_DIRis set for a Unix target other than Android, Apple, Browser and WASI,CMakeLists.txtskipsfind_path(UCURR_H ...)and adds${CMAKE_ICU_DIR}/includeonly afterinclude(configure.cmake). The configure checks forHAVE_UDAT_STANDALONE_SHORTER_WEEKDAYSandHAVE_UCOL_CLONEtherefore compile without the ICU headers from that directory.With no ICU headers in the default include path, both checks fail with "file not found" and
config.hgets 0 for both, while the build still succeeds. With system ICU headers installed, the checks find those through the default include path instead of the ones inCMAKE_ICU_DIR.With
HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS 0,pal_calendarData.cusesUDAT_STANDALONE_NARROW_WEEKDAYSfor super-short day names. WithHAVE_UCOL_CLONE 0andSTATIC_ICUdefined (theLOCAL_BUILDconfiguration),pal_collation.ccallsucol_safeClone, which is deprecated in ICU 78.3 and fails the build under-Werror.The fix adds
${CMAKE_ICU_DIR}/includetoCMAKE_REQUIRED_INCLUDESinconfigure.cmakewhenCMAKE_ICU_DIRis defined, and then builds theucol_clonecheck as a static library, so it only compiles. With ICU symbol renaming disabled,ucol_cloneis a function declaration, and the check would otherwise need to link against ICU libraries that this path never sets. Builds that do not setCMAKE_ICU_DIRare unaffected.src/native/libs/System.Globalization.Nativehas no tests of its own, so the change was checked by building:./build.sh libs.native -c Release -cmakeargs "-DCMAKE_ICU_DIR=<prefix>"with a static ICU 78.3 (--enable-static --disable-shared) on a machine without system ICU headers:config.hhad both values 0 before the change and both 1 after it, from a cleanartifacts/obj/native.libicu-dev74.2) installed: after the change the try-compile command lines inCMakeConfigureLog.yamlinclude-I<prefix>/include; before it they had no-Ioption.CC=clang cmake -S src/native/libs/System.Globalization.Native -B <build-dir> -DLOCAL_BUILD:STRING=1 -DCLR_CMAKE_TARGET_UNIX:STRING=1 -DCMAKE_ICU_DIR=<prefix> -DCMAKE_C_FLAGS=-Werrorthenmake -C <build-dir>, without system ICU headers: failed on'ucol_safeClone_78' is deprecatedbefore the change; built without warnings after it.cmakeandmakewith a static ICU 78.3 built with--disable-renaming, applied either by putting itsuconfig.h.prependat the top ofuconfig.hor by adding-DU_DISABLE_RENAMING=1toCMAKE_C_FLAGS: with the include change alone,HAVE_UCOL_CLONEwas 0 (undefined reference to 'ucol_clone') and the build failed on'ucol_safeClone' is deprecated; with the check compile-only, it was 1 and the build succeeded../build.sh libs.native -c ReleasewithoutCMAKE_ICU_DIR:config.handlibSystem.Globalization.Native.soare byte-identical before and after the change.A build directory configured with
CMAKE_ICU_DIRbefore this change keeps its cached check results; configure it again from an empty directory.Resolves #135571
Note
AI-generated, written at my direction and reviewed by me before posting.
ICU 78.3 throughout (
icu4c-78.3-sources.tgz,--enable-static --disable-shared).The first three bullets were measured for the first commit on dotnet/runtime d148189 (
System.Globalization.Nativeis unchanged from there to this PR's base), Ubuntu 24.04.4 LTS x64, clang 18.1.3, CMake 3.28.3, .NET SDK 11.0.100-rc.1.26420.103.At this PR's base on Ubuntu 22.04.5 LTS x64, clang 14.0.0, CMake 3.31.12 (system
libicu-dev70.1, its headers hidden by a bind mount where a bullet says "without system ICU headers"), with both commits: the first and third bullets again, the--disable-renamingbullet and the last bullet. The paragraph after the bullets was measured there for the first commit: a build with the change reverted, then the change applied and the same command run again in the same directory.Commands: the builds listed above, each from a removed build directory, with
grep HAVE_on the generatedconfig.h, the try-compile entries ofCMakeConfigureLog.yaml, andsha256sumoflibSystem.Globalization.Native.so.