随着代码的不断更新,原来的文章有很多地方已经不适用于现在,所有增加了本文章,对过去NDK交叉编译gettext源码进行更改和补充。
下载gettext源码gettext-0.21.tar.gz:
Index of /pub/gnu/gettexthttps://ftp.gnu.org/pub/gnu/gettext/?C=M;O=A
tar -zxvf gettext-0.21.tar.gz
cd gettext-0.21 && mkdir build&&cd build
CC="aarch64-linux-android33-clang" CPP="aarch64-linux-android33-clang -E" CPPFLAGS="-I${SYSROOT}/usr/include" CXX="aarch64-linux-android33-clang++" CXXCPP="aarch64-linux-android33-clang++ -E" ../configure --prefix="/home/dubu/installtest" --host=arm-linux-android33 CFLAGS="-fPIC" --with-libiconv-prefix=${SYSROOT}/usr --with-sysroot=${SYSROOT}
make
make install
执行上述交叉编译以后,在make install的时候报错如下:
libtool: relink: aarch64-linux-android33-clang -shared -fPIC -DPIC .libs/libgettextsrc_la-message.o .libs/libgettextsrc_la-po-error.o .libs/libgettextsrc_la-po-xerror.o .libs/libgettextsrc_la-read-catalog-abstract.o .libs/libgettextsrc_la-po-lex.o .libs/libgettextsrc_la-po-gram-gen.o .libs/libgettextsrc_la-po-charset.o .libs/libgettextsrc_la-read-po.o .libs/libgettextsrc_la-read-properties.o .libs/libgettextsrc_la-read-stringtable.o .libs/libgettextsrc_la-open-catalog.o .libs/libgettextsrc_la-dir-list.o .libs/libgettextsrc_la-str-list.o .libs/libgettextsrc_la-read-catalog.o .libs/libgettextsrc_la-write-catalog.o .libs/libgettextsrc_la-write-properties.o .libs/libgettextsrc_la-write-stringtable.o .libs/libgettextsrc_la-write-po.o .libs/libgettextsrc_la-msgl-ascii.o .libs/libgettextsrc_la-msgl-iconv.o .libs/libgettextsrc_la-msgl-equal.o .libs/libgettextsrc_la-msgl-cat.o .libs/libgettextsrc_la-msgl-header.o .libs/libgettextsrc_la-msgl-english.o .libs/libgettextsrc_la-msgl-check.o .libs/libgettextsrc_la-file-list.o .libs/libgettextsrc_la-msgl-charset.o .libs/libgettextsrc_la-po-time.o .libs/libgettextsrc_la-plural-exp.o .libs/libgettextsrc_la-plural-eval.o .libs/libgettextsrc_la-plural-table.o .libs/libgettextsrc_la-sentence.o .libs/libgettextsrc_la-format.o .libs/libgettextsrc_la-format-c.o .libs/libgettextsrc_la-format-python.o .libs/libgettextsrc_la-format-python-brace.o .libs/libgettextsrc_la-format-java.o .libs/libgettextsrc_la-format-java-printf.o .libs/libgettextsrc_la-format-csharp.o .libs/libgettextsrc_la-format-javascript.o .libs/libgettextsrc_la-format-scheme.o .libs/libgettextsrc_la-format-lisp.o .libs/libgettextsrc_la-format-elisp.o .libs/libgettextsrc_la-format-librep.o .libs/libgettextsrc_la-format-ruby.o .libs/libgettextsrc_la-format-sh.o .libs/libgettextsrc_la-format-awk.o .libs/libgettextsrc_la-format-lua.o .libs/libgettextsrc_la-format-pascal.o .libs/libgettextsrc_la-format-smalltalk.o .libs/libgettextsrc_la-format-qt.o .libs/libgettextsrc_la-format-qt-plural.o .libs/libgettextsrc_la-format-kde.o .libs/libgettextsrc_la-format-kde-kuit.o .libs/libgettextsrc_la-format-boost.o .libs/libgettextsrc_la-format-tcl.o .libs/libgettextsrc_la-format-perl.o .libs/libgettextsrc_la-format-perl-brace.o .libs/libgettextsrc_la-format-php.o .libs/libgettextsrc_la-format-gcc-internal.o .libs/libgettextsrc_la-format-gfc-internal.o .libs/libgettextsrc_la-read-desktop.o .libs/libgettextsrc_la-locating-rule.o .libs/libgettextsrc_la-its.o .libs/libgettextsrc_la-search-path.o -L/home/dubu/installtest/lib -L/home/dubu/android-ndk-r25/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib -L=/usr/lib -L/home/dubu/gettext-0.21/build2/gettext-tools/intl/.libs
-L/home/dubu/installtest/lib -lgettextlib
-L/home/dubu/android-ndk-r25/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib -ltextstyle
-lm -lintl -liconv -lc -Wl,-soname -Wl,libgettextsrc-0.21.so
-o .libs/libgettextsrc-0.21.so
ld: error: unable to find library -lgettextlib
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
libtool: error: error: relink 'libgettextsrc.la' with the above command before installing it
make[5]: *** [Makefile:3069:install-libLTLIBRARIES] 错误 1
make[5]: 离开目录“/home/dubu/gettext-0.21/build2/gettext-tools/src”
解决方法:
vi ~/gettext-0.21/build/gettext-tools/gnulib-lib/Makefile
找到如下内容:
install-exec-clean:
case "linux-android33" in \
aix*) ;; \
*) rm -f $(DESTDIR)$(libdir)/libgettextlib.a ;; \
esac并将其修改为:
install-exec-clean:
case "linux-android33" in \
aix*) ;; \
*) rm -f $(DESTDIR)$(libdir)/libgettextlib.a && \
ln -sf $(DESTDIR)$(libdir)/libgettextlib-0.21.so $(DESTDIR)$(libdir)/libgettextlib.so ;; \
esac问题即可解决。
上面的修改是在make或者make install以后进行的。
问题到目前为止已经解决,接下来的内容是给不相信我的人看的,就是分析这样作的原因,给大家一个信服我的理由。如果你相信我,那就可以让make install永生了。
先看看报错内容:
在交叉编译生成.libs/libgettextsrc-0.21.so的时候找不到要链接的库-lgettextlib所以才报的错。
再看一下编译命令的其中一段:-L/home/dubu/installtest/lib -lgettextlib
这一段的意思是要去/home/dubu/installtest/lib这个路径下找动态库libgettextlib.so或者libgettextlib.a静态库,结果在这个路径下没有找到,为什么没有找到呢?
我们回溯一下,make clean&&make 2>&1 1>1,重新make并且把make的输出内容重定向到文件1中,vi 1,然后搜索libgettextlib.a,会找到如下内容
libtool: install: /usr/bin/install -c .libs/libgettextlib.a /home/dubu/installtest/lib/libgettextlib.a
libtool: install: chmod 644 /home/dubu/installtest/lib/libgettextlib.a
libtool: install: ranlib /home/dubu/installtest/lib/libgettextlib.a
case "linux-android33" in \
aix*) ;; \
*) rm -f /home/dubu/installtest/lib/libgettextlib.a ;; \
esac
make的时候已经安装了libgettextlib.a,但是因为不是aix系统,所以又把libgettextlib.a这个静态库给删除了,所以下面编译生成.libs/libgettextsrc-0.21.so找不到-lgettextlib了。
但是如果不用交叉编译的话,直接进行如下命令:
cd gettext-0.21 && mkdir buildbak && cd buildbak
../configure
make 2>&1 1>1
make install
这是没有问题的。那么为什么在这里make install 就可以成功,交叉编译make install 就会失败。
我们来看看输出文档,vi 1 (这里的文件1是在buildbak目录下,不是在build目录下),然后搜索libgettextlib.so,找出如下内容:
libtool: link: (cd ".libs" && rm -f "libgettextlib.so" && ln -s "libgettextlib-0.21.so" "libgettextlib.so")
由此可以看出 libgettextlib.so是libgettextlib-0.21.so的连接文件。
并且用NDK对gettext进行交叉编译的时候是没有 libgettextlib.so生成的,所以就在交叉编译make 以后,用上面的解决方法就可以了。