aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2024-04-22 16:27:30 +0800
committerPo Lu2024-04-22 16:30:15 +0800
commit3bcdf010a9f2576bac0d7f23af70fa9dff81ef95 (patch)
tree600a98286f5469579cf87dac7c920590b5af4082 /java
parent4d9629b087fe6df941b553c6931b2f8996901e21 (diff)
downloademacs-3bcdf010a9f2576bac0d7f23af70fa9dff81ef95.tar.gz
emacs-3bcdf010a9f2576bac0d7f23af70fa9dff81ef95.zip
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.
Diffstat (limited to 'java')
-rw-r--r--java/Makefile.in91
-rw-r--r--java/org/gnu/emacs/EmacsNative.java52
2 files changed, 109 insertions, 34 deletions
diff --git a/java/Makefile.in b/java/Makefile.in
index 7d732be8f91..bd1938689d5 100644
--- a/java/Makefile.in
+++ b/java/Makefile.in
@@ -83,6 +83,10 @@ RESOURCE_FILES := $(foreach file,$(wildcard $(srcdir)/res/*), \
83# code. Instead, it is automatically included by the Java compiler. 83# code. Instead, it is automatically included by the Java compiler.
84RESOURCE_FILE := $(srcdir)/org/gnu/emacs/R.java 84RESOURCE_FILE := $(srcdir)/org/gnu/emacs/R.java
85 85
86# EmacsConfig.java is a file that holds information regarding the set of
87# shared libraries this binary links to, and similar build variables.
88CONFIG_FILE := $(builddir)/org/gnu/emacs/EmacsConfig.java
89
86# CLASS_FILES is what should actually be built and included in the 90# CLASS_FILES is what should actually be built and included in the
87# resulting Emacs executable. The Java compiler might generate more 91# resulting Emacs executable. The Java compiler might generate more
88# than one class file for each source file, so this only serves as a 92# than one class file for each source file, so this only serves as a
@@ -294,8 +298,72 @@ $(RESOURCE_FILE): $(RESOURCE_FILES)
294 -J $(dir $@) -M AndroidManifest.xml \ 298 -J $(dir $@) -M AndroidManifest.xml \
295 -S $(top_srcdir)/java/res 299 -S $(top_srcdir)/java/res
296 300
297# Make all class files depend on R.java being built. 301# Generate a list of libemacs's dependencies with each item ordered
298$(CLASS_FILES): $(RESOURCE_FILE) 302# before its dependents for the startup process to load in advance, as
303# older versions of the dynamic linker do not consider these libraries
304# when resolving its imports. The several following statements are
305# executed from a recursive `make' run after shared libraries are
306# generated.
307
308ALL_DEPENDENCIES :=
309
310ifneq (,$(filter cf-stamp-1,$(MAKECMDGOALS)))
311# Don't be sidetracked by dependencies of shared libraries outside the
312# ndk-build directory.
313define get-dependencies
314$(foreach x, \
315$(and $(wildcard $(top_builddir)/cross/ndk-build/$1.so), \
316 $(shell $(NDK_BUILD_READELF) -d \
317 $(wildcard $(top_builddir)/cross/ndk-build/$1.so) \
318 | sed -n 's/.*(NEEDED).*\[\(.*\.so\)\].*/\1/p')), \
319$(basename $(notdir $(x))))
320endef #get-dependencies
321define resolve-one-dependency
322$(foreach dependency,$(call get-dependencies,$1),\
323 $(if $(findstring "$(dependency)",$(ALL_DEPENDENCIES)),,\
324 $(call resolve-one-dependency,$(basename $(notdir $(dependency)))) \
325 $(eval ALL_DEPENDENCIES := $(ALL_DEPENDENCIES) "$(dependency)",)))
326endef #resolve-one-dependency
327DEPENDENCIES := $(foreach file,$(NDK_BUILD_SHARED),\
328 $(basename $(notdir $(file))))
329$(foreach file,$(DEPENDENCIES),\
330 $(if $(findstring "$(file)",$(ALL_DEPENDENCIES)),,\
331 $(call resolve-one-dependency,$(file)) \
332 $(eval ALL_DEPENDENCIES := $(ALL_DEPENDENCIES) "$(file)",)))
333endif
334
335# EmacsConfig.java:
336ifeq (${V},1)
337AM_V_EMACSCONFIG =
338else
339AM_V_EMACSCONFIG = @$(info $. GEN org/gnu/emacs/EmacsConfig.java)
340endif
341
342.PHONY: cf-stamp-1
343cf-stamp-1:
344 $(AM_V_at) echo 'package org.gnu.emacs;\
345public class EmacsConfig\
346{\
347/* This is a generated file. Do not edit! */\
348public static final String[] EMACS_SHARED_LIBRARIES\
349= {$(ALL_DEPENDENCIES)};\
350}' | sed 's/\\//g' > globals.tmp
351 $(AM_V_at) mkdir -p org/gnu/emacs
352 $(AM_V_at) $(top_srcdir)/build-aux/move-if-change \
353 globals.tmp org/gnu/emacs/EmacsConfig.java
354
355# cf-stamp-1 is a phony target invoked in a second `make' instance after
356# all shared libraries are compiled, because the computation of
357# ALL_DEPENDENCIES cannot be postponed until that stage in this instance
358# of Make.
359cf-stamp: $(NDK_BUILD_SHARED) $(CROSS_LIBS)
360 $(AM_V_EMACSCONFIG) $(MAKE) cf-stamp-1
361 $(AM_V_at) touch $@
362$(CONFIG_FILE): cf-stamp; @true
363
364# Make all class files depend on R.java and EmacsConfig.java being
365# built.
366$(CLASS_FILES): $(RESOURCE_FILE) $(CONFIG_FILE)
299 367
300.SUFFIXES: .java .class 368.SUFFIXES: .java .class
301$(CLASS_FILES) &: $(JAVA_FILES) 369$(CLASS_FILES) &: $(JAVA_FILES)
@@ -305,13 +373,23 @@ $(CLASS_FILES) &: $(JAVA_FILES)
305# N.B. that find must be called all over again in case javac generated 373# N.B. that find must be called all over again in case javac generated
306# nested classes. 374# nested classes.
307 375
376ALL_CLASS_FILES = \
377 $(subst $$,\$$,$(shell find $(srcdir) -type f -name *.class))
378
379ifneq ($(builddir),$(srcdir))
380# If the build directory is distinct from the source directory, also
381# include generated class files located there.
382ALL_CLASS_FILES = $(ALL_CLASS_FILES) \
383 $(subst $$,\$$,$(shell find $(builddir) -type f -name *.class))
384endif
385
308classes.dex: $(CLASS_FILES) $(if $(IS_D8_R8), $(srcdir)/proguard.conf) 386classes.dex: $(CLASS_FILES) $(if $(IS_D8_R8), $(srcdir)/proguard.conf)
309 $(AM_V_D8) $(D8) --classpath $(ANDROID_JAR) \ 387 $(AM_V_D8) $(D8) --classpath $(ANDROID_JAR) \
310 $(subst $$,\$$,$(shell find $(srcdir) -type f \ 388 $(ALL_CLASS_FILES) \
311 -name *.class)) --output $(builddir) \ 389 --output $(builddir) \
312 --min-api $(ANDROID_MIN_SDK) \ 390 --min-api $(ANDROID_MIN_SDK) \
313 $(if $(filter false,$(ANDROID_DEBUGGABLE)),--release, \ 391 $(if $(filter false,$(ANDROID_DEBUGGABLE)),--release, \
314 --debug) \ 392 --debug) \
315 $(if $(IS_D8_R8),--pg-conf $(srcdir)/proguard.conf) 393 $(if $(IS_D8_R8),--pg-conf $(srcdir)/proguard.conf)
316 394
317# When emacs.keystore expires, regenerate it with: 395# When emacs.keystore expires, regenerate it with:
@@ -345,7 +423,8 @@ TAGS: $(ETAGS) $(tagsfiles)
345 $(AM_V_GEN) $(ETAGS) $(tagsfiles) 423 $(AM_V_GEN) $(ETAGS) $(tagsfiles)
346 424
347clean: 425clean:
348 rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig 426 rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig \
427 cf-stamp $(CONFIG_FILE)
349 rm -rf install-temp $(RESOURCE_FILE) TAGS 428 rm -rf install-temp $(RESOURCE_FILE) TAGS
350 find . -name '*.class' $(FIND_DELETE) 429 find . -name '*.class' $(FIND_DELETE)
351 430
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java
index 567242f2ec3..9b3e60e1a84 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -321,39 +321,35 @@ public final class EmacsNative
321 321
322 static 322 static
323 { 323 {
324 /* Older versions of Android cannot link correctly with shared 324 /* A library search path misconfiguration prevents older versions of
325 libraries that link with other shared libraries built along 325 Android from successfully loading application shared libraries
326 Emacs unless all requisite shared libraries are explicitly 326 unless all requisite shared libraries provided by the application
327 loaded from Java. 327 are explicitly loaded from Java. The build process arranges that
328 328 EmacsConfig.EMACS_SHARED_LIBRARIES hold the names of each of
329 Every time you add a new shared library dependency to Emacs, 329 these libraries in the correct order, so load them now. */
330 please insert it here as well, before other shared libraries of 330
331 which it might be a dependency. */ 331 libraryDeps = EmacsConfig.EMACS_SHARED_LIBRARIES;
332
333 libraryDeps = new String[] { "c++_shared", "gnustl_shared",
334 "stlport_shared", "gabi++_shared",
335 "png_emacs", "pcre_emacs",
336 "selinux_emacs", "crypto_emacs",
337 "packagelistparser_emacs",
338 "gmp_emacs", "nettle_emacs",
339 "p11-kit_emacs", "tasn1_emacs",
340 "hogweed_emacs", "gnutls_emacs",
341 "jpeg_emacs", "tiff_emacs",
342 "icuuc_emacs", "xml2_emacs",
343 "harfbuzz_emacs", "tree-sitter_emacs", };
344 332
345 for (String dependency : libraryDeps) 333 for (String dependency : libraryDeps)
346 { 334 {
347 try 335 /* Remove the "lib" prefix, if any. */
348 { 336 if (dependency.startsWith ("lib"))
349 System.loadLibrary (dependency); 337 dependency = dependency.substring (3);
350 } 338
351 catch (UnsatisfiedLinkError exception) 339 /* If this library is provided by the operating system, don't
352 { 340 link to it. */
353 /* Ignore this exception. */ 341 if (dependency.equals ("z")
354 } 342 || dependency.equals ("c")
343 || dependency.equals ("m")
344 || dependency.equals ("dl")
345 || dependency.equals ("log")
346 || dependency.equals ("android"))
347 continue;
348
349 System.loadLibrary (dependency);
355 } 350 }
356 351
352 /* At this point, it should be alright to load Emacs. */
357 System.loadLibrary ("emacs"); 353 System.loadLibrary ("emacs");
358 }; 354 };
359}; 355};