This change is needed for Android because dynamically linking libicu is
not reliable on Android. There are multiple problems:
libICU is sometimes an internal/private component on Android. In some
cases it appears that tryiing to LoadLibrary on libICU will silently
skip because the OS already has one loaded. If the symbol names don't
match, you get unresolved symbol errors at runtime resulting from a
crash without a good understanding why. (This happened to me on my Nexus
7 2013 with 5.0.2). And if the symbols match, but the versions are
different, you may have even tougher problems.
If your application needs ICU, you now run the risk of having
conflicting versions of ICU. This is a particular risk for middleware
where the user may have not built Swift themselves.
Dealing with loading the ICU dependencies is annoying on Android
because you must write Java code to load all the libraries, and in the
correct order. And your build process must also be aware of all the
dependencies so all the .so's get packaged.
So static linking ICU solves all these problems.
But additionally, the issue of linking the C++ standard library becomes
an issue. Again, there are similar issues with dynamically linking
because Android doesn't provide a pre-installed system-wide one we can
rely on. Additionally:
Android actually provides 3 or 4 different C++ standard libraries you
can pick from, all of which are incompatible with each other.
Every new NDK release risks a new version of each of the standard
libraries which breaks binary compatibility. If the user is just using
the Swift compiler and doesn't think about these issues, this may cause
hard problems.
Also, statically linking ICU caused building command line executables
(tests) to fail with unresolved symbols. Statically linking C++ fixes
this problem and the original behavior is preserved.
So static linking solves these problems too.
Two new switches are needed to build for Android:
--android-icu-data-include /path/to/include
--android-icu-data /path/to/libicudata
Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 1 | |Component/s | Compiler | |Labels | Improvement, Android, ICU | |Assignee | jblatecky (JIRA) | |Priority | Medium | md5: 57cffc55e2d8137ac432f00b13ecc676Issue Description:
This merges with my prior FindICU.cmake general patch which allow for ICU to be
static libraries. (See https://bugs.swift.org/browse/SR-1358)
This change is needed for Android because dynamically linking libicu is
not reliable on Android. There are multiple problems:
cases it appears that tryiing to LoadLibrary on libICU will silently
skip because the OS already has one loaded. If the symbol names don't
match, you get unresolved symbol errors at runtime resulting from a
crash without a good understanding why. (This happened to me on my Nexus
7 2013 with 5.0.2). And if the symbols match, but the versions are
different, you may have even tougher problems.
conflicting versions of ICU. This is a particular risk for middleware
where the user may have not built Swift themselves.
because you must write Java code to load all the libraries, and in the
correct order. And your build process must also be aware of all the
dependencies so all the .so's get packaged.
So static linking ICU solves all these problems.
But additionally, the issue of linking the C++ standard library becomes
an issue. Again, there are similar issues with dynamically linking
because Android doesn't provide a pre-installed system-wide one we can
rely on. Additionally:
can pick from, all of which are incompatible with each other.
libraries which breaks binary compatibility. If the user is just using
the Swift compiler and doesn't think about these issues, this may cause
hard problems.
(tests) to fail with unresolved symbols. Statically linking C++ fixes
this problem and the original behavior is preserved.
So static linking solves these problems too.
Two new switches are needed to build for Android:
--android-icu-data-include /path/to/include
--android-icu-data /path/to/libicudata
My patch is here:
https://github.com/ewmailing/swift/commit/8af36d6c724abc52ba35fcd096acb571c5af0875