Generate Android shared library list automatically
* .gitignore: Ignore new generated files. * cross/Makefile.in (src/Makefile): Remove leftover specification of the source Gnulib directory. * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_READELF): New variable. * java/Makefile.in (CONFIG_FILE, ALL_DEPENDENCIES, READELF) (cf-stamp-1, cf-stamp): New variables and rules; compute the set of library files in the order of loading and generate a file with this information. (ALL_CLASS_FILES): New variable; if builddir is not srcdir, $($(CONFIG_FILE), $(CLASS_FILES)): Depend on EmacsConfig.java. add generated files in the build directory. (classes.dex): Adjust to match. * java/org/gnu/emacs/EmacsNative.java (EmacsNative) <static initializer>: Load shared libraries from EMACS_SHARED_LIBRARIES rather than a hard-coded list. * m4/ndk-build.m4 (ndk_INIT): Search for readelf... (ndk_CHECK_MODULES): ...and substitute its path as NDK_BUILD_READELF.
This commit is contained in:
parent
4d9629b087
commit
3bcdf010a9
6 changed files with 125 additions and 34 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -66,6 +66,10 @@ java/org/gnu/emacs/*.class
|
|||
# Built by `aapt'.
|
||||
java/org/gnu/emacs/R.java
|
||||
|
||||
# Built by `make'.
|
||||
java/org/gnu/emacs/EmacsConfig.java
|
||||
java/org/gnu/emacs/cf-stamp
|
||||
|
||||
# Built by `config.status'.
|
||||
java/AndroidManifest.xml
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ src/Makefile: $(top_builddir)/src/Makefile.android
|
|||
-e 's/\.\.\/admin\/charsets/..\/..\/admin\/charsets/g' \
|
||||
-e 's/^libsrc =.*$$/libsrc = \.\.\/\.\.\/lib-src/g' \
|
||||
-e 's/libsrc =.*$$/libsrc = \.\.\/\.\.\/lib-src/g' \
|
||||
-e 's/-I\$$(top_srcdir)\/lib/-I..\/$(subst /,\/,$(srcdir))\/lib/g' \
|
||||
-e 's/-I\$$(top_srcdir)\/lib//g' \
|
||||
< $(top_builddir)/src/Makefile.android > $@
|
||||
|
||||
src/epaths.h: $(top_builddir)/src/epaths.h
|
||||
|
|
|
@ -27,6 +27,7 @@ NDK_BUILD_CXX_LDFLAGS = @NDK_BUILD_CXX_LDFLAGS@
|
|||
NDK_BUILD_ANY_CXX_MODULE = @NDK_BUILD_ANY_CXX_MODULE@
|
||||
NDK_BUILD_SHARED =
|
||||
NDK_BUILD_STATIC =
|
||||
NDK_BUILD_READELF = @NDK_BUILD_READELF@
|
||||
|
||||
define uniqify
|
||||
$(if $1,$(firstword $1) $(call uniqify,$(filter-out $(firstword $1),$1)))
|
||||
|
|
|
@ -83,6 +83,10 @@ RESOURCE_FILES := $(foreach file,$(wildcard $(srcdir)/res/*), \
|
|||
# code. Instead, it is automatically included by the Java compiler.
|
||||
RESOURCE_FILE := $(srcdir)/org/gnu/emacs/R.java
|
||||
|
||||
# EmacsConfig.java is a file that holds information regarding the set of
|
||||
# shared libraries this binary links to, and similar build variables.
|
||||
CONFIG_FILE := $(builddir)/org/gnu/emacs/EmacsConfig.java
|
||||
|
||||
# CLASS_FILES is what should actually be built and included in the
|
||||
# resulting Emacs executable. The Java compiler might generate more
|
||||
# than one class file for each source file, so this only serves as a
|
||||
|
@ -294,8 +298,72 @@ $(RESOURCE_FILE): $(RESOURCE_FILES)
|
|||
-J $(dir $@) -M AndroidManifest.xml \
|
||||
-S $(top_srcdir)/java/res
|
||||
|
||||
# Make all class files depend on R.java being built.
|
||||
$(CLASS_FILES): $(RESOURCE_FILE)
|
||||
# Generate a list of libemacs's dependencies with each item ordered
|
||||
# before its dependents for the startup process to load in advance, as
|
||||
# older versions of the dynamic linker do not consider these libraries
|
||||
# when resolving its imports. The several following statements are
|
||||
# executed from a recursive `make' run after shared libraries are
|
||||
# generated.
|
||||
|
||||
ALL_DEPENDENCIES :=
|
||||
|
||||
ifneq (,$(filter cf-stamp-1,$(MAKECMDGOALS)))
|
||||
# Don't be sidetracked by dependencies of shared libraries outside the
|
||||
# ndk-build directory.
|
||||
define get-dependencies
|
||||
$(foreach x, \
|
||||
$(and $(wildcard $(top_builddir)/cross/ndk-build/$1.so), \
|
||||
$(shell $(NDK_BUILD_READELF) -d \
|
||||
$(wildcard $(top_builddir)/cross/ndk-build/$1.so) \
|
||||
| sed -n 's/.*(NEEDED).*\[\(.*\.so\)\].*/\1/p')), \
|
||||
$(basename $(notdir $(x))))
|
||||
endef #get-dependencies
|
||||
define resolve-one-dependency
|
||||
$(foreach dependency,$(call get-dependencies,$1),\
|
||||
$(if $(findstring "$(dependency)",$(ALL_DEPENDENCIES)),,\
|
||||
$(call resolve-one-dependency,$(basename $(notdir $(dependency)))) \
|
||||
$(eval ALL_DEPENDENCIES := $(ALL_DEPENDENCIES) "$(dependency)",)))
|
||||
endef #resolve-one-dependency
|
||||
DEPENDENCIES := $(foreach file,$(NDK_BUILD_SHARED),\
|
||||
$(basename $(notdir $(file))))
|
||||
$(foreach file,$(DEPENDENCIES),\
|
||||
$(if $(findstring "$(file)",$(ALL_DEPENDENCIES)),,\
|
||||
$(call resolve-one-dependency,$(file)) \
|
||||
$(eval ALL_DEPENDENCIES := $(ALL_DEPENDENCIES) "$(file)",)))
|
||||
endif
|
||||
|
||||
# EmacsConfig.java:
|
||||
ifeq (${V},1)
|
||||
AM_V_EMACSCONFIG =
|
||||
else
|
||||
AM_V_EMACSCONFIG = @$(info $. GEN org/gnu/emacs/EmacsConfig.java)
|
||||
endif
|
||||
|
||||
.PHONY: cf-stamp-1
|
||||
cf-stamp-1:
|
||||
$(AM_V_at) echo 'package org.gnu.emacs;\
|
||||
public class EmacsConfig\
|
||||
{\
|
||||
/* This is a generated file. Do not edit! */\
|
||||
public static final String[] EMACS_SHARED_LIBRARIES\
|
||||
= {$(ALL_DEPENDENCIES)};\
|
||||
}' | sed 's/\\//g' > globals.tmp
|
||||
$(AM_V_at) mkdir -p org/gnu/emacs
|
||||
$(AM_V_at) $(top_srcdir)/build-aux/move-if-change \
|
||||
globals.tmp org/gnu/emacs/EmacsConfig.java
|
||||
|
||||
# cf-stamp-1 is a phony target invoked in a second `make' instance after
|
||||
# all shared libraries are compiled, because the computation of
|
||||
# ALL_DEPENDENCIES cannot be postponed until that stage in this instance
|
||||
# of Make.
|
||||
cf-stamp: $(NDK_BUILD_SHARED) $(CROSS_LIBS)
|
||||
$(AM_V_EMACSCONFIG) $(MAKE) cf-stamp-1
|
||||
$(AM_V_at) touch $@
|
||||
$(CONFIG_FILE): cf-stamp; @true
|
||||
|
||||
# Make all class files depend on R.java and EmacsConfig.java being
|
||||
# built.
|
||||
$(CLASS_FILES): $(RESOURCE_FILE) $(CONFIG_FILE)
|
||||
|
||||
.SUFFIXES: .java .class
|
||||
$(CLASS_FILES) &: $(JAVA_FILES)
|
||||
|
@ -305,13 +373,23 @@ $(CLASS_FILES) &: $(JAVA_FILES)
|
|||
# N.B. that find must be called all over again in case javac generated
|
||||
# nested classes.
|
||||
|
||||
ALL_CLASS_FILES = \
|
||||
$(subst $$,\$$,$(shell find $(srcdir) -type f -name *.class))
|
||||
|
||||
ifneq ($(builddir),$(srcdir))
|
||||
# If the build directory is distinct from the source directory, also
|
||||
# include generated class files located there.
|
||||
ALL_CLASS_FILES = $(ALL_CLASS_FILES) \
|
||||
$(subst $$,\$$,$(shell find $(builddir) -type f -name *.class))
|
||||
endif
|
||||
|
||||
classes.dex: $(CLASS_FILES) $(if $(IS_D8_R8), $(srcdir)/proguard.conf)
|
||||
$(AM_V_D8) $(D8) --classpath $(ANDROID_JAR) \
|
||||
$(subst $$,\$$,$(shell find $(srcdir) -type f \
|
||||
-name *.class)) --output $(builddir) \
|
||||
$(ALL_CLASS_FILES) \
|
||||
--output $(builddir) \
|
||||
--min-api $(ANDROID_MIN_SDK) \
|
||||
$(if $(filter false,$(ANDROID_DEBUGGABLE)),--release, \
|
||||
--debug) \
|
||||
--debug) \
|
||||
$(if $(IS_D8_R8),--pg-conf $(srcdir)/proguard.conf)
|
||||
|
||||
# When emacs.keystore expires, regenerate it with:
|
||||
|
@ -345,7 +423,8 @@ TAGS: $(ETAGS) $(tagsfiles)
|
|||
$(AM_V_GEN) $(ETAGS) $(tagsfiles)
|
||||
|
||||
clean:
|
||||
rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig
|
||||
rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig \
|
||||
cf-stamp $(CONFIG_FILE)
|
||||
rm -rf install-temp $(RESOURCE_FILE) TAGS
|
||||
find . -name '*.class' $(FIND_DELETE)
|
||||
|
||||
|
|
|
@ -321,39 +321,35 @@ public static native void blitRect (Bitmap src, Bitmap dest, int x1,
|
|||
|
||||
static
|
||||
{
|
||||
/* Older versions of Android cannot link correctly with shared
|
||||
libraries that link with other shared libraries built along
|
||||
Emacs unless all requisite shared libraries are explicitly
|
||||
loaded from Java.
|
||||
/* A library search path misconfiguration prevents older versions of
|
||||
Android from successfully loading application shared libraries
|
||||
unless all requisite shared libraries provided by the application
|
||||
are explicitly loaded from Java. The build process arranges that
|
||||
EmacsConfig.EMACS_SHARED_LIBRARIES hold the names of each of
|
||||
these libraries in the correct order, so load them now. */
|
||||
|
||||
Every time you add a new shared library dependency to Emacs,
|
||||
please insert it here as well, before other shared libraries of
|
||||
which it might be a dependency. */
|
||||
|
||||
libraryDeps = new String[] { "c++_shared", "gnustl_shared",
|
||||
"stlport_shared", "gabi++_shared",
|
||||
"png_emacs", "pcre_emacs",
|
||||
"selinux_emacs", "crypto_emacs",
|
||||
"packagelistparser_emacs",
|
||||
"gmp_emacs", "nettle_emacs",
|
||||
"p11-kit_emacs", "tasn1_emacs",
|
||||
"hogweed_emacs", "gnutls_emacs",
|
||||
"jpeg_emacs", "tiff_emacs",
|
||||
"icuuc_emacs", "xml2_emacs",
|
||||
"harfbuzz_emacs", "tree-sitter_emacs", };
|
||||
libraryDeps = EmacsConfig.EMACS_SHARED_LIBRARIES;
|
||||
|
||||
for (String dependency : libraryDeps)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.loadLibrary (dependency);
|
||||
}
|
||||
catch (UnsatisfiedLinkError exception)
|
||||
{
|
||||
/* Ignore this exception. */
|
||||
}
|
||||
/* Remove the "lib" prefix, if any. */
|
||||
if (dependency.startsWith ("lib"))
|
||||
dependency = dependency.substring (3);
|
||||
|
||||
/* If this library is provided by the operating system, don't
|
||||
link to it. */
|
||||
if (dependency.equals ("z")
|
||||
|| dependency.equals ("c")
|
||||
|| dependency.equals ("m")
|
||||
|| dependency.equals ("dl")
|
||||
|| dependency.equals ("log")
|
||||
|| dependency.equals ("android"))
|
||||
continue;
|
||||
|
||||
System.loadLibrary (dependency);
|
||||
}
|
||||
|
||||
/* At this point, it should be alright to load Emacs. */
|
||||
System.loadLibrary ("emacs");
|
||||
};
|
||||
};
|
||||
|
|
|
@ -339,6 +339,16 @@ NDK_BUILD_NASM=
|
|||
AS_IF([test "$ndk_ARCH" = "x86" || test "$ndk_ARCH" = "x86_64"],
|
||||
[AC_CHECK_PROGS([NDK_BUILD_NASM], [nasm])])
|
||||
|
||||
# Search for a suitable readelf binary, which is required to generate
|
||||
# the shared library list loaded on old Android systems.
|
||||
AC_PATH_PROGS([READELF], [readelf llvm-readelf $host_alias-readelf],
|
||||
[], [$ndk_ranlib_search_path:$PATH])
|
||||
AS_IF([test -z "$READELF"],
|
||||
[AC_MSG_ERROR([A suitable `readelf' utility cannot be located.
|
||||
Please verify that the Android NDK has been installed correctly,
|
||||
or install a functioning `readelf' yourself.])])
|
||||
NDK_BUILD_READELF="$READELF"
|
||||
|
||||
# Search for a C++ compiler. Upon failure, pretend the C compiler is a
|
||||
# C++ compiler and use that instead.
|
||||
|
||||
|
@ -644,6 +654,7 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES],
|
|||
AC_SUBST([NDK_BUILD_CXX_LDFLAGS])
|
||||
AC_SUBST([NDK_BUILD_ANY_CXX_MODULE])
|
||||
AC_SUBST([NDK_BUILD_CFLAGS])
|
||||
AC_SUBST([NDK_BUILD_READELF])
|
||||
|
||||
AC_CONFIG_FILES([$ndk_DIR/Makefile])
|
||||
AC_CONFIG_FILES([$ndk_DIR/ndk-build.mk])
|
||||
|
|
Loading…
Add table
Reference in a new issue