Enable libjpeg on Android

* INSTALL.android: Update documentation.
* build-aux/ndk-build-helper-1.mk: When building shared
libraries, do not link libemacs.so with dependent archive files.
* build-aux/ndk-build-helper-2.mk: Add whole archive
dependencies as well.

* configure.ac (HAVE_JPEG): Enable on Android.

* cross/ndk-build/ndk-build-shared-library.mk: Link the shared
object with archive file dependencies.
* cross/ndk-build/ndk-build-static-library.mk: Build all code
position-independently.
* cross/ndk-build/ndk-resolve.mk: Separately resolve a names of
archive and whole archive dependencies.

* src/Makefile.in (JPEG_CFLAGS): New variable.
(EMACS_CFLAGS): Add it.
This commit is contained in:
Po Lu 2023-01-24 19:10:58 +08:00
parent 56e55a8008
commit 54836c47c7
8 changed files with 113 additions and 79 deletions

View file

@ -140,13 +140,16 @@ automatically build and use those modules.
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:
work, along with what has to be patched to make them work:
libpng - https://android.googlesource.com/platform/external/libpng
libwebp - https://android.googlesource.com/platform/external/webp
giflib - https://android.googlesource.com/platform/external/giflib
(You must add LOCAL_EXPORT_CFLAGS := -I$(LOCAL_PATH) before
its Android.mk includes $(BUILD_STATIC_LIBRARY))
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))
In addition, some Emacs dependencies provide `ndk-build' support
themselves:
@ -382,12 +385,16 @@ them. The name under which the module is linked is the same as the
Make target found on the sixth line of output from
build-aux/ndk-build-helper.mk.
While the rules defined by the Makefiles in cross/ndk-build do not
have their dependencies as prerequisites (with the assumption that the
ndk-build.m4 and the Makefiles in build-aux have already added all of
the necessary targets to ndk-build.mk), dependency resolution is still
performed, as the CFLAGS and includes from dependencies must be
appended to the module's CFLAGS.
In doing so, they both include the file ndk-resolve.mk.
ndk-resolve.mk is expected to recursively add all of the exported
CFLAGS and includes of any dependencies to the compiler and linker
command lines for the module being built.
When building a shared library module, ndk-resolve.mk is also expected
to define the variables NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) and
NDK_WHOLE_A_NAMES_$(LOCAL_MODULE), containing all static library
dependencies' archive files. They are to be linked in to the
resulting shared object file.
This is done by including cross/ndk-build/ndk-resolve.mk each time a
shared or static library module is going to be built. How is this

View file

@ -47,22 +47,6 @@ else
NDK_SO_NAMES = $(LOCAL_MODULE_FILENAME).so
endif
define add-a-name
ifeq ($(findstring lib,$(1)),lib)
NDK_A_NAME = $(1).a
else
NDK_A_NAME = lib$(1).a
endif
ifeq ($$(NDK_A_NAMES:$$(NDK_A_NAME)=),$$(NDK_A_NAMES))
NDK_A_NAMES := $$(NDK_A_NAMES) $$(NDK_A_NAME)
# Now recurse over this module's dependencies.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARIES)),$$(eval $$(call add-a-name,$$(module))))
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)),$$(eval $$(call add-so-name,$$(module))))
endif
endef
define add-so-name
ifeq ($(findstring lib,$(1)),lib)
NDK_SO_NAME = $(1)_emacs.so
@ -74,17 +58,17 @@ ifeq ($$(NDK_SO_NAMES:$$(NDK_SO_NAME)=),$$(NDK_SO_NAMES))
NDK_SO_NAMES := $$(NDK_SO_NAMES) $$(NDK_SO_NAME)
# Now recurse over this module's dependencies.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARIES)),$$(eval $$(call add-a-name,$$(module))))
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)),$$(eval $$(call add-so-name,$$(module))))
endif
endef
# Resolve additional dependencies based on LOCAL_STATIC_LIBRARIES and
# LOCAL_SHARED_LIBRARIES.
# 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
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_STATIC_LIBRARIES)),$(eval $(call add-a-name,$(module))))
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module))))
$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname)))

View file

@ -79,7 +79,7 @@ endef
SYSTEM_LIBRARIES = z libz
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_STATIC_LIBRARIES)),$(eval $(call add-a-name,$(module))))
$(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))))
$(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))))

View file

@ -1046,6 +1046,7 @@ package will likely install on older systems but crash on startup.])
passthrough="$passthrough --with-webp=$with_webp"
passthrough="$passthrough --with-gif=$with_gif"
passthrough="$passthrough --with-json=$with_json"
passthrough="$passthrough --with-jpeg=$with_jpeg"
AS_IF([XCONFIGURE=android ANDROID_CC="$ANDROID_CC" \
ANDROID_SDK="$android_sdk" android_abi=$android_abi \
@ -1104,7 +1105,6 @@ if test "$ANDROID" = "yes"; then
# disabled, both within the recursive invocation of configure and
# outside.
with_xpm=no
with_jpeg=no
with_tiff=no
# Some of these dependencies are now supported within Android, so
@ -1114,6 +1114,7 @@ if test "$ANDROID" = "yes"; then
with_webp=no
with_gif=no
with_json=no
with_jpeg=no
fi
with_xml2=no
@ -4551,52 +4552,66 @@ AC_SUBST([LIBXPM])
### Use -ljpeg if available, unless '--with-jpeg=no'.
HAVE_JPEG=no
LIBJPEG=
JPEG_CFLAGS=
if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
|| test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
|| test "$window_system" = "pgtk" \
|| test "${REALLY_ANDROID}" = "yes"; then
if test "${with_jpeg}" != "no"; then
AC_CACHE_CHECK([for jpeglib 6b or later],
[emacs_cv_jpeglib],
[OLD_LIBS=$LIBS
for emacs_cv_jpeglib in yes -ljpeg no; do
case $emacs_cv_jpeglib in
yes) ;;
no) break;;
*) LIBS="$LIBS $emacs_cv_jpeglib";;
esac
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#undef HAVE_STDLIB_H /* Avoid config.h/jpeglib.h collision. */
#include <stdio.h> /* jpeglib.h needs FILE and size_t. */
#include <jpeglib.h>
#include <jerror.h>
char verify[JPEG_LIB_VERSION < 62 ? -1 : 1];
struct jpeg_decompress_struct cinfo;
]],
[[
jpeg_create_decompress (&cinfo);
WARNMS (&cinfo, JWRN_JPEG_EOF);
jpeg_destroy_decompress (&cinfo);
]])],
[emacs_link_ok=yes],
[emacs_link_ok=no])
LIBS=$OLD_LIBS
test $emacs_link_ok = yes && break
done])
if test "$emacs_cv_jpeglib" != no; then
HAVE_JPEG=yes
AC_DEFINE([HAVE_JPEG], [1],
[Define to 1 if you have the jpeg library (typically -ljpeg).])
### mingw32 doesn't use -ljpeg, since it loads the library
### dynamically when needed, and doesn't want a run-time
### dependency on the jpeglib DLL.
test "$emacs_cv_jpeglib" != yes && test "${opsys}" != "mingw32" \
&& LIBJPEG=$emacs_cv_jpeglib
if test "${REALLY_ANDROID}" = "yes"; then
# Look for libjpeg using the NDK.
ndk_SEARCH_MODULE([libjpeg], [JPEG], [HAVE_JPEG=yes])
if test "$HAVE_JPEG" = "yes"; then
LIBJPEG="$JPEG_LIBS"
AC_DEFINE([HAVE_JPEG], [1],
[Define to 1 if you have the jpeg library (typically -ljpeg).])
fi
else
AC_CACHE_CHECK([for jpeglib 6b or later],
[emacs_cv_jpeglib],
[OLD_LIBS=$LIBS
for emacs_cv_jpeglib in yes -ljpeg no; do
case $emacs_cv_jpeglib in
yes) ;;
no) break;;
*) LIBS="$LIBS $emacs_cv_jpeglib";;
esac
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#undef HAVE_STDLIB_H /* Avoid config.h/jpeglib.h collision. */
#include <stdio.h> /* jpeglib.h needs FILE and size_t. */
#include <jpeglib.h>
#include <jerror.h>
char verify[JPEG_LIB_VERSION < 62 ? -1 : 1];
struct jpeg_decompress_struct cinfo;
]],
[[
jpeg_create_decompress (&cinfo);
WARNMS (&cinfo, JWRN_JPEG_EOF);
jpeg_destroy_decompress (&cinfo);
]])],
[emacs_link_ok=yes],
[emacs_link_ok=no])
LIBS=$OLD_LIBS
test $emacs_link_ok = yes && break
done])
if test "$emacs_cv_jpeglib" != no; then
HAVE_JPEG=yes
AC_DEFINE([HAVE_JPEG], [1],
[Define to 1 if you have the jpeg library (typically -ljpeg).])
### mingw32 doesn't use -ljpeg, since it loads the library
### dynamically when needed, and doesn't want a run-time
### dependency on the jpeglib DLL.
test "$emacs_cv_jpeglib" != yes && test "${opsys}" != "mingw32" \
&& LIBJPEG=$emacs_cv_jpeglib
fi
fi
fi
fi
AC_SUBST([LIBJPEG])
AC_SUBST([JPEG_CFLAGS])
HAVE_LCMS2=no
LCMS2_CFLAGS=

View file

@ -60,15 +60,11 @@ NDK_CFLAGS ::= -mthumb
endif
endif
LOCAL_MODULE_FILENAME := $(strip $(LOCAL_MODULE_FILENAME))
ifndef LOCAL_MODULE_FILENAME
ifeq ($(findstring lib,$(LOCAL_MODULE)),lib)
LOCAL_MODULE_FILENAME := $(LOCAL_MODULE)_emacs
else
LOCAL_MODULE_FILENAME := lib$(LOCAL_MODULE)_emacs
endif
endif
# Since a shared library is being built, suffix the library with
# _emacs. Otherwise, libraries already on the system will be found
@ -89,6 +85,16 @@ ALL_OBJECT_FILES$(LOCAL_MODULE) =
$(foreach source,$(ALL_SOURCE_FILES),$(eval $(call single-object-target,$(source))))
# Now define the rule to build the shared library.
$(LOCAL_MODULE_FILENAME): $(ALL_OBJECT_FILES$(LOCAL_MODULE))
$(NDK_BUILD_CC) $^ -o $@ -shared $(NDK_LDFLAGS$(LOCAL_MODULE))
# Now define the rule to build the shared library. Shared libraries
# link with all of the archive files from the static libraries on
# which they depend.
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))
endef
NDK_WHOLE_ARCHIVE_PREFIX = -Wl,--whole-archive
NDK_WHOLE_ARCHIVE_SUFFIX = -Wl,--no-whole-archive
$(eval $(call define-module-rule,$(ALL_OBJECT_FILES$(LOCAL_MODULE)) $(NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)),$(and $(strip $(NDK_WHOLE_A_NAMES_$(LOCAL_MODULE))),$(NDK_WHOLE_ARCHIVE_PREFIX) $(NDK_WHOLE_A_NAMES_$(LOCAL_MODULE)) $(NDK_WHOLE_ARCHIVE_SUFFIX))))

View file

@ -44,7 +44,7 @@ ALL_OBJECT_FILES$(LOCAL_MODULE) += $(call objname,$(LOCAL_MODULE),$(basename $(1
endef
NDK_CFLAGS_$(LOCAL_MODULE) := $(addprefix -I,$(LOCAL_C_INCLUDES))
NDK_CFLAGS_$(LOCAL_MODULE) += -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)
ALL_OBJECT_FILES$(LOCAL_MODULE) :=

View file

@ -22,9 +22,12 @@
# Save information.
NDK_LOCAL_PATH_$(LOCAL_MODULE) := $(LOCAL_PATH)
NDK_LOCAL_STATIC_LIBRARIES_$(LOCAL_MODULE) := $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)
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_A_NAMES_$(LOCAL_MODULE) :=
NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) :=
# List of all dependencies resolved for this module thus far.
# Used to avoid infinite recursion.
@ -33,15 +36,33 @@ NDK_RESOLVED_$(LOCAL_MODULE) :=
define ndk-resolve
ifeq ($(patsubst $(1),,$(NDK_RESOLVED$(LOCAL_MODULE))),$(NDK_RESOLVED$(LOCAL_MODULE)))
NDK_RESOLVED$(LOCAL_MODULE) += $(1)
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)))
$$(foreach module,$$(NDK_LOCAL_STATIC_LIBRARIES_$(1)),$$(eval $$(call ndk-resolve,$$(module))))
$$(foreach module,$$(NDK_LOCAL_SHARED_LIBRARIES_$(1)),$$(eval $$(call ndk-resolve,$$(module))))
ifneq ($(2),)
ifneq ($(findstring lib,$(1)),)
NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += $(1).a
else
NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += lib$(1).a
endif
endif
ifneq ($(3),)
ifneq ($(findstring lib,$(1)),)
NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) += $(1).a
else
NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) += lib$(1).a
endif
endif
$$(foreach module,$$(NDK_LOCAL_STATIC_LIBRARIES_$(1)),$$(eval $$(call ndk-resolve,$$(module),1,)))
$$(foreach module,$$(NDK_LOCAL_SHARED_LIBRARIES_$(1)),$$(eval $$(call ndk-resolve,$$(module),,)))
$$(foreach module,$$(NDK_LOCAL_WHOLE_LIBRARIES_$(1)),$$(eval $$(call ndk-resolve,$$(module),,1)))
endif
endef
$(foreach module,$(LOCAL_SHARED_LIBRARIES),$(eval $(call ndk-resolve,$(module))))
$(foreach module,$(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES),$(eval $(call ndk-resolve,$(module))))
$(foreach module,$(LOCAL_SHARED_LIBRARIES),$(eval $(call ndk-resolve,$(module),,)))
$(foreach module,$(LOCAL_STATIC_LIBRARIES),$(eval $(call ndk-resolve,$(module),1,)))
$(foreach module,$(LOCAL_WHOLE_STATIC_LIBRARIES), $(eval $(call ndk-resolve,$(module),,1)))

View file

@ -139,6 +139,7 @@ LIB_PTHREAD=@LIB_PTHREAD@
LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@ @WEBP_LIBS@
GIF_CFLAGS=@GIF_CFLAGS@
JPEG_CFLAGS=@JPEG_CFLAGS@
XCB_LIBS=@XCB_LIBS@
XFT_LIBS=@XFT_LIBS@
@ -431,7 +432,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) $(XSHAPE_CFLAGS) \
$(ANDROID_CFLAGS) $(GIF_CFLAGS)
$(ANDROID_CFLAGS) $(GIF_CFLAGS) $(JPEG_CFLAGS)
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \