Назад | Перейти на главную страницу

Как повторно скомпилировать iconv в Linux (Ubuntu 14.04 LTS) с псевдо-кодировкой UTF8-MAC?

Я часами искал в Google решение моей проблемы, но не смог заставить его работать:

Мне нужно rsync файловой структуры на диске, отформатированном в ext4, на диск в формате hfs +. Папки и имена файлов могут содержать немецкие умляуты (äöüß), а обработка UTF8 отличается в OS X и Linux. Файловые системы OS X используют Unicode Normalization Form D (NFD), где Linux использует Form C (NFC).

Такое поведение вызывает удаление и повторную синхронизацию файлов с умляутами в их именах, что приводит к большим ненужным накладным расходам, особенно если вы выполняете rsync с --backup вариант.

Решением для предотвращения такого поведения является использование --iconv=UTF8,UTF8-MAC но это работает только с более новым iconvlib на Mac. Фактический iconvlib в Ubuntu 14.04 не поддерживает псевдокарсет UTF8-MAC:


root@ubuntu:~/wartung# iconv -l
...
UTF-7, UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE, UTF7, UTF8, UTF16, UTF16BE, UTF16LE, UTF32, UTF32BE, UTF32LE, ...

OS X с последней версией rsync от homebrew сделает это:


bash-3.2$ iconv -l
ANSI_X3.4-1968 ANSI_X3.4-1986 ASCII CP367 IBM367 ISO-IR-6 ISO646-US ISO_646.IRV:1991 US US-ASCII CSASCII
UTF-8 UTF8
**UTF-8-MAC UTF8-MAC**, ...

Связанные вопросы и ответы по моей проблеме:
Параметр rsync --iconv на Mac не работает (синхронизация с удаленного сервера Linux на локальный Mac)
Преобразование имен файлов UTF-8 NFD в UTF-8 NFC в rsync или afpd

РЕДАКТИРОВАТЬ
Немного повозившись, я мог перекомпилировать libiconv для Ubuntu:

sudo -i
# Get the libiconv sources
wget https://ftp.gnu.org/gnu/libiconv/libiconv-1.14.tar.gz
tar -xzvf ./libiconv-1.14.tar.gz -C /usr/src && cd /usr/src/libiconv-1.14

# Get the patch for the Makefile
wget https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-Makefile.devel
patch -p1 ./Makefile.devel < patch-Makefile.devel

# Get the patch for the translation file
wget https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff
patch -p1 < ./patch-utf8mac.diff

# Replace utf8mac.h file
rm lib/utf8mac.h && cd lib
wget http://opensource.apple.com/source/libiconv/libiconv-9/libiconv/lib/utf8mac.h?txt -O utf8mac.h

# Append flags.h with utf8mac
echo "#define ei_utf8mac_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO)" >> flags.h

# Edit stdio.h.in to prevent gcc errors because of insecure 'gets' function
cd ../srclib
sed -i -- 's/(gets/(fgets/g' ./stdio.in.h

# compile & install ...
cd ..
./configure
make -f ./Makefile.devel
make
checkinstall

До этого шага все работает хорошо. Кроме того, мне пришлось указать путь к общей библиотеке с помощью ...

touch /etc/ld.so.conf.d/libiconv.conf
echo "/usr/local/lib" > /etc/ld.so.conf.d/libiconv.conf
ldconfig

Теперь псевдо-кодировка доступна и в Ubuntu:

root@ubuntu:/# iconv -l
ANSI_X3.4-1968 ANSI_X3.4-1986 ASCII CP367 IBM367 ISO-IR-6 ISO646-US ISO_646.IRV:1991 US US-ASCII CSASCII
UTF-8
**UTF-8-MAC UTF8-MAC**, ...

Но сюрприз-сюрприз - он недоступен в rsync ?!

root@ubuntu:/# rsync --iconv=UTF8,UTF8-MAC --force --ignore-errors --delete --numeric-ids --archive --hard-links --sparse --backup --backup-dir=/path/to/TEMP/ /path/SOURCE/ /path/TARGET/
iconv_open("UTF-8", "UTF8-MAC") failed
rsync error: requested action not supported (code 4) at rsync.c(121) [Receiver=3.1.0]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.0]

Когда я тестирую iconv с документом, псевдокарсет работает. Что не так с rsync? Спасибо за помощь!