Compiling Boost 1.59.0 using the default settings on OS X uses the iconv library. When using things like boost::locale::to_upper()
, with UTF8 characters, iconv causes results like "GRüßEN”
for inputs like "grüßEN”
. As you can see, some characters don't get upper cased correctly.
I read the fix is to use ICU instead of iconv and so I set off to build Boost with ICU. The method I follow, for my use case, is the following:
- Download the unix tar ball (not the ZIP, that has CR/LF line endings and will not work). Un-tar it.
- Modify the code from file
boost/libs/filesystem/src/operations.cpp
at line 1414 to read# if 0
so that the fallback code is always executed. Otherwise I get a linking error telling you thatfchmodat
is not available in OS X 10.9. - Download ICU 56.1 at
http://site.icu-project.org/download/56#TOC-ICU4C-Download
. Un-tar it. - cd to ``icu/source```.
- Run
./configure --enable-static --disable-shared CXXFLAGS="-std=c++14" --prefix="<path to install ICU>"
- Run
gnumake && gnumake install
- cd to
boost_1_59_0/
. - Run
./bootstrap.sh toolset=darwin macosx-version=10.11 macosx-version-min=10.8 --with-icu=<path where icu was installed>
- Run
./b2 toolset=darwin --without-mpi optimization=speed cxxflags="-arch x86_64 -fvisibility=hidden -fvisibility-inlines-hidden -std=c++14 -stdlib=libc++ -ftemplate-depth=512" linkflags="-stdlib=libc++" --reconfigure boost.locale.iconv=off boost.locale.icu=on -sICU_PATH=<path to my icu install dir> -link=static stage
.
Now this correctly compiles a version of the Boost libraries but when using this version, boost::locale::to_upper()
now completely skips UTF8 characters and returns "GREN”
for inputs like "grüßEN”
.
Test code looks like this:
static boolean defaultLocaleWasInitialized = false;
...
void String::p_initDefaultLocale(void)
{
boost::locale::generator gen;
std::locale defaultLocale = gen("");
std::locale::global(defaultLocale);
std::wcout.imbue(defaultLocale);
}
...
String::Pointer String::uppperCaseString(void) const
{
if (!defaultLocaleWasInitialized) {
String::p_initDefaultLocale();
defaultLocaleWasInitialized = true;
}
auto result = boost::locale::to_upper(*this);
auto newString = String::stringWith(result.c_str());
return newString;
}
...
TEST(Base_String, UpperCaseString_StringWithLowerCaseCharacters_ReturnsOneWithUpperCaseCharacters)
{
auto test = String::stringWith("Mp3 grüßEN");
auto result = test->uppperCaseString();
ASSERT_STREQ("MP3 GRÜSSEN", result->toUTF8());
}
Any suggestions as to where I'm going wrong?