From 4255d7f0514c5fa1badded6b0bc445ec2d2764c0 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 26 Jan 2023 15:37:04 +0800 Subject: [PATCH] Update Android port * .gitignore: Ignore lib/math.h. * INSTALL.android: Update accordingly. * build-aux/ndk-build-helper-1.mk: * build-aux/ndk-build-helper-2.mk: * build-aux/ndk-build-helper.mk: * build-aux/ndk-module-extract.awk: Handle C++ modules. * configure.ac: Enable libxml2 on Android. * cross/ndk-build/Makefile.in: * cross/ndk-build/ndk-build-shared-library.mk: * cross/ndk-build/ndk-build-static-library.mk: * cross/ndk-build/ndk-build.mk.in: * cross/ndk-build/ndk-resolve.mk: Fix dependency resolution of includes. * java/org/gnu/emacs/EmacsView.java (popupMenu): Fix minimum SDK version for actual popup menus. * lib/math.h: Delete file. * m4/ndk-build.m4 (ndk_SEARCH_MODULE, ndk_CHECK_MODULES): Look for nasm and C++ libraries. * src/android.c (faccessat): Rename to `android_faccessat'. * src/android.h: Update prototypes. * src/dired.c (file_name_completion_dirp): * src/fileio.c (file_access_p, Faccess_file, file_directory_p): * src/lisp.h: * src/lread.c (openp): * src/process.c (allocate_pty): Use sys_faccessat. * src/sysdep.c (sys_faccessat): New function. --- .gitignore | 2 + INSTALL.android | 127 +++++++++++++- build-aux/ndk-build-helper-1.mk | 31 +++- build-aux/ndk-build-helper-2.mk | 22 ++- build-aux/ndk-build-helper.mk | 35 +++- build-aux/ndk-module-extract.awk | 30 +++- configure.ac | 26 ++- cross/ndk-build/Makefile.in | 29 +++- cross/ndk-build/ndk-build-shared-library.mk | 37 +++- cross/ndk-build/ndk-build-static-library.mk | 30 ++++ cross/ndk-build/ndk-build.mk.in | 18 ++ cross/ndk-build/ndk-resolve.mk | 31 +++- java/org/gnu/emacs/EmacsView.java | 5 +- m4/ndk-build.m4 | 180 +++++++++++++++++++- src/android.c | 24 +-- src/android.h | 1 + src/dired.c | 3 +- src/fileio.c | 8 +- src/lisp.h | 1 + src/lread.c | 6 +- src/process.c | 3 +- src/sysdep.c | 10 ++ 22 files changed, 598 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index 6b624767c66..6ca011312e9 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ lib/limits.h lib/malloc/*.gl.h lib/signal.h lib/std*.h +lib/math.h !lib/std*.in.h !lib/stdio-impl.h lib/string.h @@ -115,6 +116,7 @@ cross/lib/signal.h cross/lib/std*.h !cross/lib/std*.in.h !cross/lib/stdio-impl.h +cross/lib/math.h cross/lib/string.h cross/lib/sys/ cross/lib/time.h diff --git a/INSTALL.android b/INSTALL.android index 975a6249bb2..ed0bd0f68dc 100644 --- a/INSTALL.android +++ b/INSTALL.android @@ -135,9 +135,19 @@ files, like so: ./configure "--with-ndk-path=directory1 directory2" +If `configure' complains about not being able to find +``libc++_shared.so'', then you must locate that file in your copy of +the NDK, and specify it like so: + + ./configure --with-ndk-cxx-shared=/path/to/sysroot/libc++_shared.so + Emacs will then read the ``Android.mk'' file in each directory, and automatically build and use those modules. +When building for Intel systems, some ``ndk-build'' modules require +the Netwide Assembler, usually installed under ``nasm'', to be present +on the system that is building Emacs. + Google, Inc. has adapted many common Emacs dependencies to use the `ndk-build' system. Here is a non-exhaustive list of what is known to work, along with what has to be patched to make them work: @@ -150,6 +160,16 @@ work, along with what has to be patched to make them work: libjpeg-turbo - https://android.googlesource.com/platform/external/libjpeg-turbo (You must add LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) before its Android.mk includes $(BUILD_SHARED_LIBRARY)) + libxml2 - https://android.googlesource.com/platform/external/libxml2/ + (You must also place the dependency icu4c in ``--with-ndk-path'', + and apply the patch at the end of this file.) + icu4c - https://android.googlesource.com/platform/external/icu/ + (You must apply the patch at the end of this file.) + +Many of these dependencies have been migrated over to the +``Android.bp'' build system now used to build Android itself. +However, the old ``Android.mk'' Makefiles are still present in older +branches, and can be easily adapte to newer versions. In addition, some Emacs dependencies provide `ndk-build' support themselves: @@ -259,10 +279,11 @@ most important of these are: BUILD_EXECUTABLE # build-aux/ndk-build-helper-3.mk CLEAR_VARS # build-aux/ndk-build-helper-4.mk -Then, ``Android.mk'' will include $(CLEAN_VARS) (to clear variables -previously set), set several variables describing each module to the -ndk-build system, and include one of $(BUILD_SHARED_LIBRARY), -$(BUILD_STATIC_LIBRARY) and $(BUILD_EXECUTABLE). +Then, ``Android.mk'' will include $(CLEAN_VARS), possibly other +``Android.mk'' files, (to clear variables previously set), set several +variables describing each module to the ndk-build system, and include +one of $(BUILD_SHARED_LIBRARY), $(BUILD_STATIC_LIBRARY) and +$(BUILD_EXECUTABLE). Each one of those three scripts will then read from the variables set by ``Android.mk'', resolve dependencies, and print out some text @@ -300,6 +321,11 @@ The output is arranged as follows: that will build the final shared object or library archive of this module, along with all of its dependencies. + - The seventh line is either empty, or the name of a dependency on + the C++ standard library. This is used to determine whether or + not Emacs will include the C++ standard library in the application + package. + The output from Make is given to an awk script, build-aux/ndk-module-extract.awk. This is responsible for parsing the that output and filtering out modules other than what is being built: @@ -315,6 +341,8 @@ module_includes="-I/opt/android/libpng" module_cflags="" module_ldflags=" -L/opt/emacs/cross/ndk-build -l:libpng_emacs.so" module_target="libpng_emacs.so" +module_cxx_deps="" +module_imports="" which is then evaluated by `configure'. Once the variable `module_name' is set, configure apends the remaining @@ -322,6 +350,37 @@ $(module_includes), $(module_cflags) and $(module_ldflags) to the module's CFLAGS and LIBS variables, and appends the list of Makefile targets specified to the variable NDK_BUILD_MODULES. +In some cases, an ``Android.mk'' file may chose to import a module +defined in ``--with-ndk-path'', but not defined inside its own +``Android.mk'' file. build-aux/ndk-build-helper.mk defines the +`import-module' function to add the modules being imported to a +variable, which is then printed out after ``ndk-build-helper.mk'' +completes. For example, libxml2 imports the ``libicucc'' module, +which results in the following text being printed: + +Building shared +libxml2 +/home/oldosfan/libxml2/SAX.c /home/oldosfan/libxml2/entities.c /home/oldosfan/libxml2/encoding.c /home/oldosfan/libxml2/error.c /home/oldosfan/libxml2/parserInternals.c /home/oldosfan/libxml2/parser.c /home/oldosfan/libxml2/tree.c /home/oldosfan/libxml2/hash.c /home/oldosfan/libxml2/list.c /home/oldosfan/libxml2/xmlIO.c /home/oldosfan/libxml2/xmlmemory.c /home/oldosfan/libxml2/uri.c /home/oldosfan/libxml2/valid.c /home/oldosfan/libxml2/xlink.c /home/oldosfan/libxml2/debugXML.c /home/oldosfan/libxml2/xpath.c /home/oldosfan/libxml2/xpointer.c /home/oldosfan/libxml2/xinclude.c /home/oldosfan/libxml2/DOCBparser.c /home/oldosfan/libxml2/catalog.c /home/oldosfan/libxml2/globals.c /home/oldosfan/libxml2/threads.c /home/oldosfan/libxml2/c14n.c /home/oldosfan/libxml2/xmlstring.c /home/oldosfan/libxml2/buf.c /home/oldosfan/libxml2/xmlregexp.c /home/oldosfan/libxml2/xmlschemas.c /home/oldosfan/libxml2/xmlschemastypes.c /home/oldosfan/libxml2/xmlunicode.c /home/oldosfan/libxml2/xmlreader.c /home/oldosfan/libxml2/relaxng.c /home/oldosfan/libxml2/dict.c /home/oldosfan/libxml2/SAX2.c /home/oldosfan/libxml2/xmlwriter.c /home/oldosfan/libxml2/legacy.c /home/oldosfan/libxml2/chvalid.c /home/oldosfan/libxml2/pattern.c /home/oldosfan/libxml2/xmlsave.c /home/oldosfan/libxml2/xmlmodule.c /home/oldosfan/libxml2/schematron.c /home/oldosfan/libxml2/SAX.c /home/oldosfan/libxml2/entities.c /home/oldosfan/libxml2/encoding.c /home/oldosfan/libxml2/error.c /home/oldosfan/libxml2/parserInternals.c /home/oldosfan/libxml2/parser.c /home/oldosfan/libxml2/tree.c /home/oldosfan/libxml2/hash.c /home/oldosfan/libxml2/list.c /home/oldosfan/libxml2/xmlIO.c /home/oldosfan/libxml2/xmlmemory.c /home/oldosfan/libxml2/uri.c /home/oldosfan/libxml2/valid.c /home/oldosfan/libxml2/xlink.c /home/oldosfan/libxml2/debugXML.c /home/oldosfan/libxml2/xpath.c /home/oldosfan/libxml2/xpointer.c /home/oldosfan/libxml2/xinclude.c /home/oldosfan/libxml2/DOCBparser.c /home/oldosfan/libxml2/catalog.c /home/oldosfan/libxml2/globals.c /home/oldosfan/libxml2/threads.c /home/oldosfan/libxml2/c14n.c /home/oldosfan/libxml2/xmlstring.c /home/oldosfan/libxml2/buf.c /home/oldosfan/libxml2/xmlregexp.c /home/oldosfan/libxml2/xmlschemas.c /home/oldosfan/libxml2/xmlschemastypes.c /home/oldosfan/libxml2/xmlunicode.c /home/oldosfan/libxml2/xmlreader.c /home/oldosfan/libxml2/relaxng.c /home/oldosfan/libxml2/dict.c /home/oldosfan/libxml2/SAX2.c /home/oldosfan/libxml2/xmlwriter.c /home/oldosfan/libxml2/legacy.c /home/oldosfan/libxml2/chvalid.c /home/oldosfan/libxml2/pattern.c /home/oldosfan/libxml2/xmlsave.c /home/oldosfan/libxml2/xmlmodule.c /home/oldosfan/libxml2/schematron.c + + + -L/home/oldosfan/emacs-dev/emacs-android/cross/ndk-build -l:libxml2_emacs.so -l:libicuuc_emacs.so +libxml2_emacs.so libicuuc_emacs.so +End +Start Imports +libicuuc +End Imports + +Upon encountering the ``Start Imports'' section, +build-aux/ndk-module-extract.awk collects all imports until it +encounters the line ``End Imports'', at which point it prints: + +module_imports="libicuuc" + +Then, if the list of imports is not empty, ndk_CHECK_MODULES +additionally calls itself for each import before appending the +module's own ``Android.mk'', ensuring that the module's imported +dependencies are included by $ndk_DIR/Makefile before itself. + Finally, immediately before generating src/Makefile.android, configure expands: @@ -473,3 +532,63 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . + + + +PATCH FOR LIBXML2 + +This patch must be applied to the Android.mk in Google's version of +libxml2 before it can be built for Emacs. In addition, you must also +revert the commit `edb5870767fed8712a9b77ef34097209b61ab2db'. + +diff --git a/Android.mk b/Android.mk +index 07c7b372..24f67e49 100644 +--- a/Android.mk ++++ b/Android.mk +@@ -80,6 +80,7 @@ LOCAL_SHARED_LIBRARIES := libicuuc + LOCAL_MODULE:= libxml2 + LOCAL_CLANG := true + LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk ++LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH) + include $(BUILD_SHARED_LIBRARY) + + # For the host +@@ -94,3 +95,5 @@ LOCAL_MODULE := libxml2 + LOCAL_CLANG := true + LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk + include $(BUILD_HOST_STATIC_LIBRARY) ++ ++$(call import-module,libicuuc) + +PATCH FOR ICU + +This patch must be applied to icu4j/Android.mk in Google's version of +icu before it can be built for Emacs. + +diff --git a/icu4j/Android.mk b/icu4j/Android.mk +index d1ab3d5..69eff81 100644 +--- a/icu4j/Android.mk ++++ b/icu4j/Android.mk +@@ -69,7 +69,7 @@ include $(BUILD_STATIC_JAVA_LIBRARY) + # Path to the ICU4C data files in the Android device file system: + icu4c_data := /system/usr/icu + icu4j_config_root := $(LOCAL_PATH)/main/classes/core/src +-include external/icu/icu4j/adjust_icudt_path.mk ++include $(LOCAL_PATH)/adjust_icudt_path.mk + + include $(CLEAR_VARS) + LOCAL_SRC_FILES := $(icu4j_src_files) + +diff --git a/icu4c/source/common/Android.mk b/icu4c/source/common/Android.mk +index 8e5f757..44bb130 100644 +--- a/icu4c/source/common/Android.mk ++++ b/icu4c/source/common/Android.mk +@@ -231,7 +231,7 @@ include $(CLEAR_VARS) + LOCAL_SRC_FILES += $(src_files) + LOCAL_C_INCLUDES += $(c_includes) $(optional_android_logging_includes) + LOCAL_CFLAGS += $(local_cflags) -DPIC -fPIC +-LOCAL_SHARED_LIBRARIES += libdl $(optional_android_logging_libraries) ++LOCAL_SHARED_LIBRARIES += libdl libstdc++ $(optional_android_logging_libraries) + LOCAL_MODULE_TAGS := optional + LOCAL_MODULE := libicuuc + LOCAL_RTTI_FLAG := -frtti diff --git a/build-aux/ndk-build-helper-1.mk b/build-aux/ndk-build-helper-1.mk index 86e3ebd6558..4ffe0d423e4 100644 --- a/build-aux/ndk-build-helper-1.mk +++ b/build-aux/ndk-build-helper-1.mk @@ -30,13 +30,12 @@ NDK_A_NAMES = # on to recurse over libraries. NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES := $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES) NDK_$(LOCAL_MODULE)_SHARED_LIBRARIES := $(LOCAL_SHARED_LIBRARIES) +NDK_$(LOCAL_MODULE)_EXPORT_INCLUDES := $(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES) $(info Building $(build_kind)) $(info $(LOCAL_MODULE)) -$(info $(addprefix $(ANDROID_MODULE_DIRECTORY)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) +$(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) -$(info $(foreach dir,$(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES),-I$(dir))) -$(info $(LOCAL_EXPORT_CFLAGS)) ifeq ($(LOCAL_MODULE_FILENAME),) ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) NDK_SO_NAMES = $(LOCAL_MODULE)_emacs.so @@ -62,15 +61,31 @@ $$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARI endif endef -# Resolve additional dependencies based on LOCAL_STATIC_LIBRARIES and -# LOCAL_SHARED_LIBRARIES. Static library dependencies can be ignored -# while building a shared library, as they will be linked in to the -# resulting shared object file later. +# Figure out includes from dependencies as well. +NDK_INCLUDES := $(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES) + +define add-includes +ifeq ($$(findstring $$(NDK_$(1)_EXPORT_INCLUDES),$$(NDK_INCLUDES)),) +NDK_INCLUDES += $$(NDK_$(1)_EXPORT_INCLUDES) + +$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)) $$(NDK_$(1)_STATIC_LIBRARIES),$$(eval $$(call add-includes,$$(module)))) +endif +endef + +# Resolve additional dependencies and their export includes based on +# LOCAL_STATIC_LIBRARIES and LOCAL_SHARED_LIBRARIES. Static library +# dependencies can be ignored while building a shared library, as they +# will be linked in to the resulting shared object file later. -SYSTEM_LIBRARIES = z libz libc c +SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ $(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module)))) +$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_LIBRARIES)),$(eval $(call add-includes,$(module)))) + +$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir))) +$(info $(LOCAL_EXPORT_CFLAGS)) $(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname))) $(info $(NDK_SO_NAMES)) +$(info $(filter %stdc++,$(LOCAL_SHARED_LIBRARIES))) $(info End) diff --git a/build-aux/ndk-build-helper-2.mk b/build-aux/ndk-build-helper-2.mk index bd50e8b3efa..9c9e7cf09a9 100644 --- a/build-aux/ndk-build-helper-2.mk +++ b/build-aux/ndk-build-helper-2.mk @@ -24,13 +24,12 @@ NDK_A_NAMES = # on to recurse over libraries. NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES := $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES) NDK_$(LOCAL_MODULE)_SHARED_LIBRARIES := $(LOCAL_SHARED_LIBRARIES) +NDK_$(LOCAL_MODULE)_EXPORT_INCLUDES := $(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES) $(info Building $(build_kind)) $(info $(LOCAL_MODULE)) -$(info $(addprefix $(ANDROID_MODULE_DIRECTORY)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) +$(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) -$(info $(foreach dir,$(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES),-I$(dir))) -$(info $(LOCAL_EXPORT_CFLAGS)) ifeq ($(LOCAL_MODULE_FILENAME),) ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) @@ -74,14 +73,29 @@ $$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARI endif endef +# Figure out includes from dependencies as well. +NDK_INCLUDES := $(LOCAL_EXPORT_C_INCLUDE_DIRS) $(LOCAL_EXPORT_C_INCLUDES) + +define add-includes +ifeq ($$(findstring $$(NDK_$(1)_EXPORT_INCLUDES),$$(NDK_INCLUDES)),) +NDK_INCLUDES += $$(NDK_$(1)_EXPORT_INCLUDES) + +$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)) $$(NDK_$(1)_STATIC_LIBRARIES),$$(eval $$(call add-includes,$$(module)))) +endif +endef + # Resolve additional dependencies based on LOCAL_STATIC_LIBRARIES and # LOCAL_SHARED_LIBRARIES. -SYSTEM_LIBRARIES = z libz +SYSTEM_LIBRARIES = z libz libc c libdl dl libstdc++ stdc++ $(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)),$(eval $(call add-a-name,$(module)))) $(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module)))) +$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_LIBRARIES)),$(eval $(call add-includes,$(module)))) +$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir))) +$(info $(LOCAL_EXPORT_CFLAGS)) $(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) $(and $(NDK_SO_NAMES), -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname)))) $(info $(NDK_A_NAMES)) +$(info $(filter %stdc++,$(LOCAL_SHARED_LIBRARIES))) $(info End) diff --git a/build-aux/ndk-build-helper.mk b/build-aux/ndk-build-helper.mk index beb32cae3f1..886459b1378 100644 --- a/build-aux/ndk-build-helper.mk +++ b/build-aux/ndk-build-helper.mk @@ -21,20 +21,38 @@ # See the text under ``NDK BUILD SYSTEM IMPLEMENTATION'' in # INSTALL.android for more details. +# NDK_LAST_MAKEFILE is the last Makefile that was included. +NDK_LAST_MAKEFILE = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST))) + +# local-makefile is the current Makefile being loaded. +local-makefile = $(NDK_LAST_MAKEFILE) + # Make NDK_BUILD_DIR absolute. NDK_BUILD_DIR := $(absname $(NDK_BUILD_DIR)) -# my-dir is a function that returns the Android module directory. -my-dir = $(ANDROID_MODULE_DIRECTORY) +# Make EMACS_SRCDIR absolute. This must be absolute, or nested +# Android.mk files will not be able to find CLEAR_VARS. +EMACS_SRCDIR := $(absname $(EMACS_SRCDIR)) + +# my-dir is a function that returns the Android module directory. If +# no Android.mk has been loaded, use ANDROID_MODULE_DIRECTORY. +my-dir = $(or $(and $(local-makefile),$(dir $(local-makefile))),$(ANDROID_MODULE_DIRECTORY)) + +# Return all Android.mk files under the first arg. +all-makefiles-under = $(wildcard $(1)/*/Android.mk) -# all-subdir-makefiles is a function which returns all Android.mk -# files within this directory. -all-subdir-makefiles = $(shell find . -name "Android.mk") +# Return all Android.mk files in subdirectories of this Makefile's +# location. +all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir)) # These functions are not implemented. parent-makefile = grand-parent-makefile = -import-module = + +NDK_IMPORTS := + +# Add the specified module (arg 1) to NDK_IMPORTS. +import-module = $(eval NDK_IMPORTS += $(1)) # Print out module information every time BUILD_SHARED_LIBRARY is # called. @@ -48,5 +66,10 @@ CLEAR_VARS=$(EMACS_SRCDIR)/build-aux/ndk-build-helper-4.mk include $(ANDROID_MAKEFILE) +# Finally, print out the imports. +$(info Start Imports) +$(info $(NDK_IMPORTS)) +$(info End Imports) + # Dummy target. all: diff --git a/build-aux/ndk-module-extract.awk b/build-aux/ndk-module-extract.awk index eaea3e96dd8..681f20237fa 100644 --- a/build-aux/ndk-module-extract.awk +++ b/build-aux/ndk-module-extract.awk @@ -2,13 +2,27 @@ kind = $2 } +/^Start Imports$/ { + imports = 1 +} + // { - if (!match ($0, /^End$/) && !match ($0, /^Building.+$/)) + if (imports && ++imports > 2) + { + if (!match ($0, /^End Imports$/)) + makefile_imports = makefile_imports " " $1 + } + else if (!match ($0, /^End$/) && !match ($0, /^Building.+$/)) { if (kind) { - if (ldflags_found) - target = $0 + if (target_found) + cxx_deps = $0 + else if (ldflags_found) + { + target = $0 + target_found = 1 + } else if (cflags_found) { ldflags = $0 @@ -48,6 +62,7 @@ printf "module_cflags=\"%s\"\n", cflags printf "module_ldflags=\"%s\"\n", ldflags printf "module_target=\"%s\"\n", target + printf "module_cxx_deps=\"%s\"\n", cxx_deps } src = "" @@ -61,4 +76,13 @@ includes_found = "" cflags_found = "" ldflags_found = "" + target_found = "" +} + +/^End Imports$/ { + imports = "" + # Strip off leading whitespace. + gsub (/^[ \t]+/, "", makefile_imports) + printf "module_imports=\"%s\"\n", makefile_imports + makefile_imports = "" } diff --git a/configure.ac b/configure.ac index 983fa3ebab1..95bb0cfca88 100644 --- a/configure.ac +++ b/configure.ac @@ -1041,12 +1041,16 @@ package will likely install on older systems but crash on startup.]) mv -f confdefs.h _confdefs.h mv -f config.log _config.log + # Make sure these files are removed upon exit. + trap "rm -rf _confdefs.h _config.log" 0 + # Figure out what --with-FOO options to pass through. passthrough="$passthrough --with-png=$with_png" passthrough="$passthrough --with-webp=$with_webp" passthrough="$passthrough --with-gif=$with_gif" passthrough="$passthrough --with-json=$with_json" passthrough="$passthrough --with-jpeg=$with_jpeg" + passthrough="$passthrough --with-xml2=$with_xml2" AS_IF([XCONFIGURE=android ANDROID_CC="$ANDROID_CC" \ ANDROID_SDK="$android_sdk" android_abi=$android_abi \ @@ -1115,9 +1119,9 @@ if test "$ANDROID" = "yes"; then with_gif=no with_json=no with_jpeg=no + with_xml2=no fi - with_xml2=no with_rsvg=no with_sqlite3=no with_lcms2=no @@ -2256,6 +2260,18 @@ AC_DEFUN([EMACS_CHECK_MODULES], m4_default([$3], [HAVE_$1=yes])], [m4_default([$4], [HAVE_$1=no])])])]) +dnl EMACS_CHECK_LIB(NAME, FUNCTION, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND, +dnl OTHER-LIBRARIES, INCLUDES) +dnl --------------------------------------------------------------------- +dnl This is like AC_CHECK_LIB; however, there is no default action, and +dnl when cross-configuring for Android, AC_CHECK_DECLS is called with NAME +dnl and INCLUDES instead, as the library being checked against will likely +dnl be built together with Emacs. +AC_DEFUN([EMACS_CHECK_LIB], + [AS_IF([test -n "$ndk_INITIALIZED"], + [AC_CHECK_DECL([$2], [$3], [$4], [$6])], + [AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5])])]) + HAVE_SOUND=no if test "${with_sound}" != "no"; then # Sound support for GNU/Linux, the free BSDs, MinGW, and Cygwin. @@ -3323,7 +3339,6 @@ if test "${with_webp}" != "no"; then fi if test $HAVE_WEBP = yes; then AC_DEFINE([HAVE_WEBP], [1], [Define to 1 if using libwebp.]) - CFLAGS="$CFLAGS $WEBP_CFLAGS" # Windows loads libwebp dynamically if test "${opsys}" = "mingw32"; then WEBP_LIBS= @@ -5400,10 +5415,13 @@ if test "${with_xml2}" != "no"; then fi if test "${HAVE_LIBXML2}" = "yes"; then if test "${opsys}" != "mingw32"; then - AC_CHECK_LIB([xml2], [htmlReadMemory], + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $LIBXML2_CFLAGS" + EMACS_CHECK_LIB([xml2], [htmlReadMemory], [HAVE_LIBXML2=yes], [HAVE_LIBXML2=no], - [$LIBXML2_LIBS]) + [$LIBXML2_LIBS], [#include ]) + CFLAGS="$SAVE_CFLAGS" else LIBXML2_LIBS="" fi diff --git a/cross/ndk-build/Makefile.in b/cross/ndk-build/Makefile.in index ec8e6205680..125c825e506 100644 --- a/cross/ndk-build/Makefile.in +++ b/cross/ndk-build/Makefile.in @@ -30,6 +30,7 @@ NDK_BUILD_ANDROID_MK = @NDK_BUILD_ANDROID_MK@ NDK_BUILD_SDK = @NDK_BUILD_SDK@ NDK_BUILD_CC = @NDK_BUILD_CC@ NDK_BUILD_AR = @NDK_BUILD_AR@ + NDK_BUILD_NASM = @NDK_BUILD_NASM@ # This is a list of targets to build. NDK_BUILD_MODULES = @NDK_BUILD_MODULES@ @@ -49,13 +50,33 @@ endef # Remove duplicate files. NDK_BUILD_ANDROID_MK := $(call uniqify,$(NDK_BUILD_ANDROID_MK)) +# Remove duplicate modules as well. These can occur when a single +# module imports a module and also declares it in +# LOCAL_SHARED_LIBRARIES. +NDK_BUILD_MODULES := $(call uniqify,$(NDK_BUILD_MODULES)) + define subr-1 -# Define ndk-build functions. +# Define ndk-build functions. Many of these are identical to those in +# build-aux/ndk-build-helper.mk. -define my-dir -$(dir $(abspath $(1))) -endef +# NDK_LAST_MAKEFILE is the last Makefile that was included. +NDK_LAST_MAKEFILE = $$(lastword $$(filter %Android.mk,$$(MAKEFILE_LIST))) + +# local-makefile is the current Makefile being loaded. +local-makefile = $$(NDK_LAST_MAKEFILE) + +# my-dir is a function that returns the Android module directory. If +# no Android.mk has been loaded, use the directory of the Makefile +# being included. +my-dir = $$(or $$(and $$(local-makefile),$$(dir $$(local-makefile))),$(dir $(1))) + +# Return all Android.mk files under the first arg. +all-makefiles-under = $$(wildcard $$(1)/*/Android.mk) + +# Return all Android.mk files in subdirectories of this Makefile's +# location. +all-subdir-makefiles = $$(call all-makefiles-under,$$(call my-dir)) # NDK-defined include variables. diff --git a/cross/ndk-build/ndk-build-shared-library.mk b/cross/ndk-build/ndk-build-shared-library.mk index 6a607049a9c..a4b7b47f749 100644 --- a/cross/ndk-build/ndk-build-shared-library.mk +++ b/cross/ndk-build/ndk-build-shared-library.mk @@ -22,6 +22,9 @@ eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1))) objname = $(1)-$(subst /,_,$(2).o) +# Here are the default flags to link shared libraries with. +NDK_SO_DEFAULT_LDFLAGS := -lc -lm + define single-object-target ifeq (x$(suffix $(1)),x.c) @@ -29,6 +32,12 @@ ifeq (x$(suffix $(1)),x.c) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) +else +ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp)) + +$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) + $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + else ifneq ($(or $(call eq,x$(suffix $(1)),x.s),$(call eq,x$(suffix $(1)),x.S)),) @@ -36,7 +45,19 @@ $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_ASFLAGS_$(LOCAL_MODULE)) else +ifneq (x$(suffix $(1)),x.asm) $$(error Unsupported suffix: $(suffix $(1))) +else +ifeq ($(findstring x86,$(NDK_BUILD_ARCH)),) +$$(error Trying to build nasm file on non-Intel platform!) +else + +$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) + $(NDK_BUILD_NASM) -o $$@ -i $(LOCAL_PATH) -i $$(dir $$<) $(NDK_ASFLAGS_$(LOCAL_MODULE)) $$< + +endif +endif +endif endif endif @@ -47,9 +68,21 @@ endef # Make sure to not add a prefix to local includes that already specify # $(LOCAL_PATH). NDK_CFLAGS_$(LOCAL_MODULE) := $(addprefix -I,$(LOCAL_C_INCLUDES)) -NDK_CFLAGS_$(LOCAL_MODULE) += -fPIC -iquote $(LOCAL_PATH) $(LOCAL_EXPORT_CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_CFLAGS$(NDK_BUILD_ARCH)) +NDK_CFLAGS_$(LOCAL_MODULE) += -fPIC -iquote $(LOCAL_PATH) $(LOCAL_EXPORT_CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_CFLAGS_$(NDK_BUILD_ARCH)) NDK_ASFLAGS_$(LOCAL_MODULE) := $(LOCAL_ASFLAGS) $(LOCAL_ASFLAGS_$(NDK_BUILD_ARCH)) NDK_LDFLAGS_$(LOCAL_MODULE) := $(LOCAL_LDLIBS) $(LOCAL_LDFLAGS) +NDK_CXXFLAGS_$(LOCAL_MODULE) := $(LOCAL_CPPFLAGS) $(LOCAL_RTTI_FLAG) + +# Now look for features in LOCAL_CPP_FEATURES and enable them. + +ifneq ($(findstring exceptions,$(LOCAL_CPPFLAGS)),) +NDK_CXXFLAGS_$(LOCAL_MODULE) += -fexceptions +endif + +ifneq ($(findstring rtti,$(LOCAL_CPPFLAGS)),) +NDK_CXXFLAGS_$(LOCAL_MODULE) += -frtti +endif + ALL_OBJECT_FILES$(LOCAL_MODULE) := ifeq ($(NDK_BUILD_ARCH)$(NDK_ARM_MODE),armarm) @@ -91,7 +124,7 @@ $(foreach source,$(ALL_SOURCE_FILES),$(eval $(call single-object-target,$(source define define-module-rule $(LOCAL_MODULE_FILENAME): $(ALL_OBJECT_FILES$(LOCAL_MODULE)) $(NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)) $(NDK_WHOLE_A_NAMES_$(LOCAL_MODULE)) - $(NDK_BUILD_CC) $(1) $(2) -o $$@ -shared $(NDK_LDFLAGS$(LOCAL_MODULE)) + $(NDK_BUILD_CC) $(1) $(2) -o $$@ -shared $(NDK_LDFLAGS$(LOCAL_MODULE)) $(NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)) $(NDK_SO_DEFAULT_LDFLAGS) endef NDK_WHOLE_ARCHIVE_PREFIX = -Wl,--whole-archive diff --git a/cross/ndk-build/ndk-build-static-library.mk b/cross/ndk-build/ndk-build-static-library.mk index 2e4893a997b..4d16d81330c 100644 --- a/cross/ndk-build/ndk-build-static-library.mk +++ b/cross/ndk-build/ndk-build-static-library.mk @@ -29,6 +29,12 @@ ifeq (x$(suffix $(1)),x.c) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) +else +ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp)) + +$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) + $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + else ifneq ($(or $(call eq,x$(suffix $(1)),x.s),$(call eq,x$(suffix $(1)),x.S)),) @@ -36,7 +42,19 @@ $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_ASFLAGS_$(LOCAL_MODULE)) else +ifneq (x$(suffix $(1)),x.asm) $$(error Unsupported suffix: $(suffix $(1))) +else +ifeq ($(findstring x86,$(NDK_BUILD_ARCH)),) +$$(error Trying to build nasm file on non-Intel platform!) +else + +$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1) + $(NDK_BUILD_NASM) -o $$@ -i $(LOCAL_PATH) -i $$(dir $$<) $(NDK_ASFLAGS_$(LOCAL_MODULE)) $$< + +endif +endif +endif endif endif @@ -47,8 +65,20 @@ NDK_CFLAGS_$(LOCAL_MODULE) := $(addprefix -I,$(LOCAL_C_INCLUDES)) NDK_CFLAGS_$(LOCAL_MODULE) += -fPIC -iquote $(LOCAL_PATH) $(LOCAL_EXPORT_CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_CFLAGS_$(NDK_BUILD_ARCH)) NDK_ASFLAGS_$(LOCAL_MODULE) := $(LOCAL_ASFLAGS) $(LOCAL_ASFLAGS_$(NDK_BUILD_ARCH)) NDK_LDFLAGS_$(LOCAL_MODULE) := $(LOCAL_LDLIBS) $(LOCAL_LDFLAGS) +NDK_CXXFLAGS_$(LOCAL_MODULE) := $(LOCAL_CPPFLAGS) $(LOCAL_RTTI_FLAG) ALL_OBJECT_FILES$(LOCAL_MODULE) := +# Now look for features in LOCAL_CPP_FEATURES and enable them. + +ifneq ($(findstring exceptions,$(LOCAL_CPPFLAGS)),) +NDK_CXXFLAGS_$(LOCAL_MODULE) += -fexceptions +endif + +ifneq ($(findstring rtti,$(LOCAL_CPPFLAGS)),) +NDK_CXXFLAGS_$(LOCAL_MODULE) += -frtti +endif + + ifeq ($(NDK_BUILD_ARCH)$(NDK_ARM_MODE),armarm) NDK_CFLAGS ::= -marm else diff --git a/cross/ndk-build/ndk-build.mk.in b/cross/ndk-build/ndk-build.mk.in index 6ad577ccc35..798dcf6c19e 100644 --- a/cross/ndk-build/ndk-build.mk.in +++ b/cross/ndk-build/ndk-build.mk.in @@ -20,9 +20,27 @@ # This file is included all over the place to build prerequisites. NDK_BUILD_MODULES = @NDK_BUILD_MODULES@ +NDK_BUILD_CXX_SHARED = @NDK_BUILD_CXX_SHARED@ +NDK_BUILD_ANY_CXX_MODULE = @NDK_BUILD_ANY_CXX_MODULE@ NDK_BUILD_SHARED = NDK_BUILD_STATIC = +define uniqify +$(if $1,$(firstword $1) $(call uniqify,$(filter-out $(firstword $1),$1))) +endef + +# Remove duplicate modules. These can occur when a single module +# imports a module and also declares it in LOCAL_SHARED_LIBRARIES. +NDK_BUILD_MODULES := $(call uniqify,$(NDK_BUILD_MODULES)) + +# The C++ standard library must be extracted from the Android NDK +# directories and included in the application package, if any module +# requires the C++ standard library. + +ifneq ($(NDK_BUILD_ANY_CXX_MODULE),) +NDK_BUILD_SHARED += $(NDK_BUILD_ANY_CXX_SHARED) +endif + define subr-1 $(top_builddir)/cross/ndk-build/$(1): diff --git a/cross/ndk-build/ndk-resolve.mk b/cross/ndk-build/ndk-resolve.mk index 7fe807e35cc..910be8dab53 100644 --- a/cross/ndk-build/ndk-resolve.mk +++ b/cross/ndk-build/ndk-resolve.mk @@ -25,9 +25,10 @@ NDK_LOCAL_STATIC_LIBRARIES_$(LOCAL_MODULE) := $(LOCAL_STATIC_LIBRARIES) $(LOCAL_ NDK_LOCAL_WHOLE_LIBRARIES_$(LOCAL_MODULE) := $(LOCAL_WHOLE_STATIC_LIBRARIES) NDK_LOCAL_SHARED_LIBRARIES_$(LOCAL_MODULE) := $(LOCAL_SHARED_LIBRARIES) NDK_LOCAL_EXPORT_CFLAGS_$(LOCAL_MODULE) := $(LOCAL_EXPORT_CFLAGS) -NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE) := $(LOCAL_EXPORT_C_INCLUDES) +NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE) := $(LOCAL_EXPORT_C_INCLUDES) $(LOCAL_EXPORT_C_INCLUDE_DIRS) NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) := NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) := +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) := # List of all dependencies resolved for this module thus far. # Used to avoid infinite recursion. @@ -40,6 +41,34 @@ NDK_RESOLVED_$(LOCAL_MODULE) += $(1) NDK_CFLAGS_$(LOCAL_MODULE) += $(NDK_LOCAL_EXPORT_CFLAGS_$(1)) NDK_CFLAGS_$(LOCAL_MODULE) += $(addprefix -I,$(NDK_LOCAL_EXPORT_C_INCLUDES_$(1))) +# If the module happens to be zlib, then add -lz to the shared library +# flags. +ifneq ($(strip $(1)),libz) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lz +endif + +ifneq ($(strip $(1)),z) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lz +endif + +# Likewise for libdl. +ifneq ($(strip $(1)),libdl) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -ldl +endif + +ifneq ($(strip $(1)),dl) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -ldl +endif + +# Likewise for libstdc++. +ifneq ($(strip $(1)),libstdc++) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lstdc++ +endif + +ifneq ($(strip $(1)),dl) +NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lstdc++ +endif + ifneq ($(2),) ifneq ($(findstring lib,$(1)),) NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += $(1).a diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 881cbc363ba..a1953f683bd 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -531,8 +531,9 @@ public class EmacsView extends ViewGroup contextMenu = menu; popupActive = true; - /* On API 21 or later, use showContextMenu (float, float). */ - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) + /* Use showContextMenu (float, float) on N to get actual popup + behavior. */ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) return showContextMenu ((float) xPosition, (float) yPosition); else return showContextMenu (); diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4 index d3614a9f490..27092e4b400 100644 --- a/m4/ndk-build.m4 +++ b/m4/ndk-build.m4 @@ -21,6 +21,10 @@ AC_ARG_WITH([ndk_path], [AS_HELP_STRING([--with-ndk-path], [find Android libraries in these directories])]) +AC_ARG_WITH([ndk_cxx_shared], + [AS_HELP_STRING([--with-ndk-cxx-shared], + [name of the C++ standard library included with the NDK])]) + # ndk_INIT(ABI, API, DIR) # -------- # Initialize the Android NDK. ABI is the ABI being built for. @@ -45,6 +49,7 @@ ndk_MAKEFILES= ndk_INITIALIZED=yes ndk_API=$2 ndk_DIR=$3 +ndk_ANY_CXX= case "$ndk_ABI" in *arm64* ) @@ -103,6 +108,62 @@ ndk_parse_pkg_config_string () { done } +# Resolve $1, a single import. Prepend its makefile to ndk_MAKEFILES +# if found. Also, prepend all includes to the variable +# ndk_import_includes. + +ndk_resolve_import_module () { + module_name= + ndk_module=[$]1 + + AC_MSG_CHECKING([for imported $ndk_module]) + + for ndk_android_mk in $ndk_module_files; do + # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in + # tree build system sets it to a meaning value, but build files + # just use it to test whether or not the NDK is being used. + ndk_commands=$($MAKE -s -f build-aux/ndk-build-helper.mk EMACS_SRCDIR=. \ + EMACS_ABI=$ndk_ABI ANDROID_MAKEFILE="$ndk_android_mk" \ + ANDROID_MODULE_DIRECTORY=$(dirname "$ndk_android_mk") \ + NDK_BUILD_DIR="$ndk_DIR" NDK_ROOT="/tmp" \ + | awk -f build-aux/ndk-module-extract.awk \ + MODULE="$ndk_module") + + AS_IF([test -n "${ndk_commands//\n }"], [eval "$ndk_commands"]) + + if test -n "$module_name"; then + break; + fi + done + + if test -z "$module_name"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([The module currently being built depends on [$]1, but \ +that could not be found in the list of directories specified in \ +`--with-ndk-path'.]) + fi + + if test -n "$module_cxx_deps"; then + ndk_ANY_CXX=yes + fi + + if test "$ndk_ANY_CXX" = "yes" && test -z "$with_ndk_cxx_shared"; then + AC_MSG_ERROR([The module [$]1 requires the C++ standard library \ +(libc++_shared.so), but it was not found.]) + fi + + AC_MSG_RESULT([yes]) + + # Make sure the module is prepended. + ndk_MAKEFILES="$ndk_android_mk $ndk_MAKEFILES" + ndk_import_includes="$module_includes $ndk_import_includes" + + # Now recursively resolve this module's imports. + for ndk_module in $module_imports; do + ndk_resolve_import_module $ndk_module + done +} + # Look for a suitable ar in the same directory as the C compiler. ndk_where_cc=$(which $CC) ndk_ar_search_path=$PATH @@ -117,15 +178,102 @@ if test -z "$AR"; then AC_PATH_PROGS([AR], [$host_alias-ar llvm-ar], [], [$ndk_ar_search_path]) fi +NDK_BUILD_NASM= + +# Next, try to find nasm on x86. This doesn't ship with the NDK. +if test "$ndk_ARCH" = "x86" || test "$ndk_ARCH" = "x86_64"; then + AC_CHECK_PROGS([NDK_BUILD_NASM], [nasm]) +fi + +# Look for a file named ``libc++_shared.so'' in a subdirectory of +# $ndk_where_cc if it was not specified. +AC_MSG_CHECKING([for libc++_shared.so]) + +ndk_where_toolchain= +if test -z "$with_ndk_cxx_shared" && test -n "$ndk_where_cc"; then + # Find the NDK root directory. Go to $ndk_where_cc. + SAVE_PWD=`pwd` + cd $(dirname "$ndk_where_cc") + + # Now, keep moving backwards until pwd ends with ``toolchains''. + while :; do + if test "`pwd`" = "/"; then + cd "$SAVE_PWD" + break + fi + + if test "`basename $(pwd)`" = "toolchains"; then + ndk_where_toolchain=`pwd` + cd "$SAVE_PWD" + break + fi + + cd .. + done + + ndk_matching_libcxx_shared_so= + + # The toolchain directory should be in "$ndk_where_toolchain". + if test -n "$ndk_where_toolchain"; then + # Now, look in the directory behind it. + ndk_cxx_shared_so=`find "$ndk_where_toolchain" -name libc++_shared.so` + + # Look for one with the correct architecture. + for ndk_candidate in $ndk_cxx_shared_so; do + case "$ndk_candidate" in + *arm-linux-android* ) + if test "$ndk_ARCH" = "arm"; then + ndk_matching_libcxx_shared_so=$ndk_candidate + fi + ;; + *aarch64-linux-android* ) + if test "$ndk_ARCH" = "arm64"; then + ndk_matching_libcxx_shared_so=$ndk_candidate + fi + ;; + *i[[3-6]]86-linux-android* ) + if test "$ndk_ARCH" = "x86"; then + ndk_matching_libcxx_shared_so=$ndk_candidate + fi + ;; + *x86_64-linux-android* ) + if test "$ndk_ARCH" = "x86_64"; then + ndk_matching_libcxx_shared_so=$ndk_candidate + fi + ;; + esac + + if test -n "$ndk_matching_libcxx_shared_so"; then + with_ndk_cxx_shared=$ndk_matching_libcxx_shared_so + fi + done + fi +fi + +if test -z "$with_ndk_cxx_shared"; then + AC_MSG_RESULT([no]) + AC_MSG_WARN([The C++ standard library could not be found. \ +If you try to build Emacs with a dependency that requires the C++ standard \ +library, Emacs will not build correctly, unless you manually specify the \ +name of an appropriate ``libc++_shared.so'' binary.]) +else + AC_MSG_RESULT([$with_ndk_cxx_shared]) +fi + +ndk_CXX_SHARED=$with_ndk_cxx_shared + # These variables have now been found. ]) # ndk_SEARCH_MODULE(MODULE, NAME, ACTION-IF-FOUND, [ACTION-IF-NOT-FOUND]) -# -------------------------------------------------------------------- +# ----------------------------------------------------------------------- # Search for a module named MODULE in `with_ndk_path'. Add the file -# name of the module's Android.mk file to the variable ndk_MODULES. -# Set NAME_CFLAGS and NAME_LIBS to the appropriate values. Then, -# call ACTION-IF-FOUND, or ACTION-IF-NOT-FOUND upon failure. +# name of the module's Android.mk file to the variable ndk_MAKEFILES. +# Set NAME_CFLAGS and NAME_LIBS to the appropriate values. Then, call +# ACTION-IF-FOUND, or ACTION-IF-NOT-FOUND upon failure. +# +# Resolve any imports specified by MODULE, and expand AC_MSG_ERROR +# with a suitable error message if imports were not found. AC_DEFUN([ndk_SEARCH_MODULE], [ module_name= @@ -137,7 +285,7 @@ for ndk_android_mk in $ndk_module_files; do # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in # tree build system sets it to a meaning value, but build files just # use it to test whether or not the NDK is being used. - ndk_commands=$(make -s -f build-aux/ndk-build-helper.mk EMACS_SRCDIR=. \ + ndk_commands=$($MAKE -s -f build-aux/ndk-build-helper.mk EMACS_SRCDIR=. \ EMACS_ABI=$ndk_ABI ANDROID_MAKEFILE="$ndk_android_mk" \ ANDROID_MODULE_DIRECTORY=$(dirname "$ndk_android_mk") \ NDK_BUILD_DIR="$ndk_DIR" NDK_ROOT="/tmp" \ @@ -155,12 +303,29 @@ if test -z "$module_name"; then AC_MSG_RESULT([no]) $4 else + if test -n "$module_cxx_deps"; then + ndk_ANY_CXX=yes + fi + + if test "$ndk_ANY_CXX" = "yes" && test -z "$with_ndk_cxx_shared"; then + AC_MSG_ERROR([The module $1 requires the C++ standard library \ +(libc++_shared.so), but it was not found.]) + fi + $2[]_CFLAGS="[$]$2[]_CFLAGS $module_cflags $module_includes" $2[]_LIBS="[$]$2[]_LIBS $module_ldflags" ndk_MAKEFILES="$ndk_MAKEFILES $ndk_android_mk" ndk_MODULES="$ndk_MODULES $module_target" AC_MSG_RESULT([yes]) $3 + + # Now, resolve imports. Make sure the imports' Makefiles comes + # before ndk_MAKEFILES; likewise for its includes. + ndk_import_includes= + for ndk_module in $module_imports; do + ndk_resolve_import_module $ndk_module + $2[]_CFLAGS="$ndk_import_includes [$]$2[]_CFLAGS" + done fi ]) @@ -198,6 +363,8 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES], NDK_BUILD_CC=$CC NDK_BUILD_AR=$AR NDK_BUILD_MODULES="$ndk_MODULES" + NDK_BUILD_CXX_SHARED="$ndk_CXX_SHARED" + NDK_BUILD_ANY_CXX_MODULE=$ndk_ANY_CXX AC_SUBST([NDK_BUILD_ANDROID_MK]) AC_SUBST([NDK_BUILD_ARCH]) @@ -205,7 +372,10 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES], AC_SUBST([NDK_BUILD_SDK]) AC_SUBST([NDK_BUILD_CC]) AC_SUBST([NDK_BUILD_AR]) + AC_SUBST([NDK_BUILD_NASM]) AC_SUBST([NDK_BUILD_MODULES]) + AC_SUBST([NDK_BUILD_CXX_SHARED]) + AC_SUBST([NDK_BUILD_ANY_CXX_MODULE]) AC_CONFIG_FILES([$ndk_DIR/Makefile]) AC_CONFIG_FILES([$ndk_DIR/ndk-build.mk]) diff --git a/src/android.c b/src/android.c index 2f21a03b53f..52de153eefd 100644 --- a/src/android.c +++ b/src/android.c @@ -4214,30 +4214,34 @@ android_window_updated (android_window window, unsigned long serial) -#if __ANDROID_API__ >= 17 - -#undef faccessat +#if __ANDROID_API__ >= 16 /* Replace the system faccessat with one which understands AT_EACCESS. Android's faccessat simply fails upon using AT_EACCESS, so replace it with zero here. This isn't caught during configuration. - This replacement is only done when building for Android 17 or + This replacement is only done when building for Android 16 or later, because earlier versions use the gnulib replacement that lacks these issues. */ int -faccessat (int dirfd, const char *pathname, int mode, int flags) +android_faccessat (int dirfd, const char *pathname, int mode, int flags) { - static int (*real_faccessat) (int, const char *, int, int); + return faccessat (dirfd, pathname, mode, flags & ~AT_EACCESS); +} + +#else /* __ANDROID_API__ < 16 */ - if (!real_faccessat) - real_faccessat = dlsym (RTLD_NEXT, "faccessat"); +/* This is unnecessary on earlier API versions, as gnulib's + rpl_faccessat will be used instead. */ - return real_faccessat (dirfd, pathname, mode, flags & ~AT_EACCESS); +int +android_faccessat (int dirfd, const char *pathname, int mode, int flags) +{ + return faccessat (dirfd, pathname, mode, flags); } -#endif /* __ANDROID_API__ >= 17 */ +#endif diff --git a/src/android.h b/src/android.h index 6c20995e4a1..33fad512d4a 100644 --- a/src/android.h +++ b/src/android.h @@ -52,6 +52,7 @@ extern char *android_user_full_name (struct passwd *); extern int android_fstat (int, struct stat *); extern int android_fstatat (int, const char *restrict, struct stat *restrict, int); +extern int android_faccessat (int, const char *, int, int); extern int android_close (int); extern int android_fclose (FILE *); extern const char *android_get_home_directory (void); diff --git a/src/dired.c b/src/dired.c index ced08a35643..b38416e981a 100644 --- a/src/dired.c +++ b/src/dired.c @@ -894,7 +894,8 @@ file_name_completion_dirp (int fd, struct dirent *dp, ptrdiff_t len) return true; #endif - bool dirp = faccessat (fd, subdir_name, F_OK, AT_EACCESS) == 0; + bool dirp = sys_faccessat (fd, subdir_name, + F_OK, AT_EACCESS) == 0; SAFE_FREE (); return dirp; } diff --git a/src/fileio.c b/src/fileio.c index 492a43d74c3..6f25506dbc2 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -188,7 +188,7 @@ file_access_p (char const *file, int amode) return true; #endif - if (faccessat (AT_FDCWD, file, amode, AT_EACCESS) == 0) + if (sys_faccessat (AT_FDCWD, file, amode, AT_EACCESS) == 0) return true; #ifdef CYGWIN @@ -3024,7 +3024,8 @@ If there is no error, returns nil. */) return Qnil; #endif - if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0) + if (sys_faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, + AT_EACCESS) != 0) report_file_error (SSDATA (string), filename); return Qnil; @@ -3126,7 +3127,8 @@ file_directory_p (Lisp_Object file) { #ifdef DOS_NT /* This is cheaper than 'stat'. */ - bool retval = faccessat (AT_FDCWD, SSDATA (file), D_OK, AT_EACCESS) == 0; + bool retval = sys_faccessat (AT_FDCWD, SSDATA (file), + D_OK, AT_EACCESS) == 0; if (!retval && errno == EACCES) errno = ENOTDIR; /* like the non-DOS_NT branch below does */ return retval; diff --git a/src/lisp.h b/src/lisp.h index f64a27ce113..6fda1e95503 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -5071,6 +5071,7 @@ extern int emacs_fstatat (int, char const *, void *, int); #ifdef HAVE_SYS_STAT_H extern int sys_fstat (int, struct stat *); #endif +extern int sys_faccessat (int, const char *, int, int); #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) extern int emacs_openat (int, char const *, int, int); #endif diff --git a/src/lread.c b/src/lread.c index d585dece392..6abcea556bf 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1964,8 +1964,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, fd = -1; if (INT_MAX < XFIXNAT (predicate)) last_errno = EINVAL; - else if (faccessat (AT_FDCWD, pfn, XFIXNAT (predicate), - AT_EACCESS) + else if (sys_faccessat (AT_FDCWD, pfn, XFIXNAT (predicate), + AT_EACCESS) == 0) { if (file_directory_p (encoded_fn)) @@ -1985,7 +1985,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, it. Only open the file when we are sure that it exists. */ #ifdef WINDOWSNT - if (faccessat (AT_FDCWD, pfn, R_OK, AT_EACCESS)) + if (sys_faccessat (AT_FDCWD, pfn, R_OK, AT_EACCESS)) fd = -1; else #endif diff --git a/src/process.c b/src/process.c index 651b5fa035b..9a8b0d7fd85 100644 --- a/src/process.c +++ b/src/process.c @@ -880,7 +880,8 @@ allocate_pty (char pty_name[PTY_NAME_SIZE]) /* Check to make certain that both sides are available. This avoids a nasty yet stupid bug in rlogins. */ - if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0) + if (sys_faccessat (AT_FDCWD, pty_name, + R_OK | W_OK, AT_EACCESS) != 0) { emacs_close (fd); continue; diff --git a/src/sysdep.c b/src/sysdep.c index 4d89d4f25ae..ac26b12e9a5 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2398,6 +2398,16 @@ sys_fstat (int fd, struct stat *statb) #endif } +int +sys_faccessat (int fd, const char *pathname, int mode, int flags) +{ +#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) + return faccessat (fd, pathname, mode, flags); +#else + return android_faccessat (fd, pathname, mode, flags); +#endif +} + /* Assuming the directory DIRFD, open FILE for Emacs use, using open flags OFLAGS and mode MODE. Use binary I/O on systems that care about text vs binary I/O. -- 2.39.5