mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-10 00:42:17 -07:00
* .gitignore: Update with new files. Do not ignore std*.in.h. * INSTALL.android: Explain how to build Emacs with external dependencies. * Makefile.in (xcompile, cross): Rename to `cross'. (clean_dirs): Clean cross, not xcompile. * README: Document new directories. * build-aux/ndk-build-helper-1.mk (build_kind, NDK_SO_NAMES): * build-aux/ndk-build-helper-2.mk (build_kind, NDK_SO_NAMES): * build-aux/ndk-build-helper-3.mk (build_kind): * build-aux/ndk-build-helper-4.mk: * build-aux/ndk-build-helper.mk (NDK_BUILD_DIR, my-dir): * build-aux/ndk-module-extract.awk: New files. * configure.ac: Set up libgif, libwebp, and libpng for ndk-build. * cross/ndk-build/Makefile.in (srcdir, NDK_BUILD_ANDROID_MK): * cross/ndk-build/ndk-build-executable.mk: * cross/ndk-build/ndk-build-shared-library.mk (eq, objname): * cross/ndk-build/ndk-build-static-library.mk (eq, objname): * cross/ndk-build/ndk-build.in (NDK_BUILD_MODULES): * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_MODULES) (NDK_BUILD_SHARED): * cross/ndk-build/ndk-clear-vars.mk: * cross/ndk-build/ndk-prebuilt-shared-library.mk: * cross/ndk-build/ndk-prebuilt-static-library.mk: New files. * doc/emacs/android.texi (Android, Android Environment): Document clipboard support on Android. * doc/emacs/emacs.texi (Top): Update menus. * etc/MACHINES: Document Android. * java/AndroidManifest.xml.in: Respect new `--with-android-debug' option. * java/Makefile.in (CROSS_BINS, CROSS_LIBS): Adjust for rename. Include ndk-build.mk.:(emacs.apk-in): Depend on shared libraries. Then, package shared libraries. * java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New class. * java/org/gnu/emacs/EmacsFontDriver.java: Update comment to say this is unused. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function `sendExpose'. * java/org/gnu/emacs/EmacsSdk11Clipboard.java (EmacsSdk11Clipboard): * java/org/gnu/emacs/EmacsSdk8Clipboard.java (EmacsSdk8Clipboard): New classes. * java/org/gnu/emacs/EmacsView.java (EmacsView, handleDirtyBitmap) (onDetachedFromWindow): When window is reattached, expose the frame. * lib/Makefile.in (VPATH): (ALL_CFLAGS): Adjust for rename. * lisp/term/android-win.el (android-clipboard-exists-p) (android-get-clipboard, android-set-clipboard) (android-clipboard-owner-p, android-primary-selection) (android-get-clipboard-1, android-get-primary) (android-selection-bounds, android-encode-select-string) (gui-backend-get-selection, gui-backend-selection-exists-p) (gui-backend-selection-owner-p, gui-backend-set-selection): New functions. * m4/ndk-build.m4: New file. * src/Makefile.in (GIF_CFLAGS, ANDROID_LDFLAGS): New variables. (EMACS_CFLAGS): Add GIF_CFLAGS. Include ndk-build.mk. (libemacs.so): Depend on and link with required libraries. * src/android.c (android_check_compressed_file): New function. (android_open): Work around Android platform bug. (sendExpose): New function. (android_readdir): Set d_type if this is a directory. * src/androidgui.h (enum android_event_type) (struct android_expose_event, union android_event): Add expose events. * src/androidselect.c (struct android_emacs_clipboard) (android_init_emacs_clipboard, Fandroid_clipboard_owner_p) (Fandroid_set_clipboard, Fandroid_get_clipboard) (Fandroid_clipboard_exists_p, init_androidselect) (syms_of_androidselect): New file. * src/androidterm.c (handle_one_android_event): Handle exposures. * src/androidterm.h: Update prototypes. * src/emacs.c (android_emacs_init): Initialize androidselect.
443 lines
18 KiB
Text
443 lines
18 KiB
Text
Installation instructions for Android
|
||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||
See the end of the file for license conditions.
|
||
|
||
Please read the entirety of this file before attempting to build Emacs
|
||
as an application package which can run on Android devices.
|
||
|
||
When building from the source repository, make sure to read
|
||
INSTALL.REPO as well.
|
||
|
||
|
||
|
||
Android is an unusual operating system in that program binaries cannot
|
||
be produced on computers running Android themselves. Instead, they
|
||
must be built on some other computer using a set of tools known as the
|
||
``Android SDK'' (Software Development Kit) and the ``Android NDK''
|
||
(Native Development Kit). Appropriate versions of both must be
|
||
obtained to build GNU Emacs; after being built, the generated binaries
|
||
will work on almost all Android devices. This document does not
|
||
elaborate on how both sets of tools can be obtained. However, for
|
||
your freedom's sake, you should use the Android SDK provided by the
|
||
Debian project.
|
||
|
||
In addition to the Android SDK and Android NDK, Emacs also requires
|
||
the Java compiler from OpenJDK 1.7.0 to be installed on your system.
|
||
|
||
Once all of those tools are obtained, you may invoke the `configure'
|
||
script like so:
|
||
|
||
./configure --with-android=/path/to/android.jar \
|
||
ANDROID_CC=/path/to/android/ndk/cc \
|
||
SDK_BUILD_TOOLS=/path/to/sdk/build/tools
|
||
|
||
Replacing the paths in the command line above with:
|
||
|
||
- the path to the `android.jar' headers which come with the Android
|
||
SDK. They must correspond to Android version 13 or later.
|
||
|
||
- the path to the C compiler in the Android NDK, for the machine you
|
||
are building Emacs to run on.
|
||
|
||
- the path to the directory in the Android SDK containing binaries
|
||
such as `aapt' and `d8'. These are used to build the application
|
||
package.
|
||
|
||
After the configuration process completes, you may run:
|
||
|
||
make all
|
||
|
||
Once `make' finishes, there should be a file in the `java' directory
|
||
named along the lines of:
|
||
|
||
emacs-<version>-<api-version>-<abi>.apk
|
||
|
||
where <api-version> is the oldest version of Android that the package
|
||
will run on, and <abi> is the type of Android machine the package was
|
||
built for.
|
||
|
||
The generated package can be uploaded onto an SD card (or similar
|
||
medium) and installed on-device.
|
||
|
||
BUILDING WITH OLD NDK VERSIONS
|
||
|
||
Building Emacs with an old version of the Android NDK requires special
|
||
setup. This is because there is no separate C compiler binary for
|
||
each version of Android in those versions of the NDK.
|
||
|
||
Before running `configure', you must identify three variables:
|
||
|
||
- What kind of Android system you are building Emacs for.
|
||
|
||
- The minimum API version of Android you want to build Emacs for.
|
||
|
||
- The locations of the system root and include files for that
|
||
version of Android in the NDK.
|
||
|
||
That information must then be specified as arguments to the NDK C
|
||
compiler. For example:
|
||
|
||
./configure [...] \
|
||
ANDROID_CC="i686-linux-android-gcc \
|
||
--sysroot=/path/to/ndk/platforms/android-14/arch-x86/"
|
||
ANDROID_CFLAGS="-isystem /path/to/ndk/sysroot/usr/include \
|
||
-isystem /path/to/ndk/sysroot/usr/include/i686-linux-android \
|
||
-D__ANDROID_API__=14"
|
||
|
||
Where __ANDROID_API__ and the version identifier in
|
||
"platforms/android-14" defines the version of Android you are building
|
||
for, and the include directories specify the paths to the relevant
|
||
Android headers. In addition, it may be necessary to specify
|
||
"-gdwarf-2", due to a bug in the Android NDK.
|
||
|
||
Emacs is known to build for Android 2.2 (API version 8) or later, and
|
||
run on Android 2.3 or later. It is supposed to run on Android 2.2 as
|
||
well.
|
||
|
||
DEBUG AND RELEASE BUILDS
|
||
|
||
Android makes a distinction between ``debug'' and ``release'' builds
|
||
of applications. With ``release'' builds, the system will apply
|
||
stronger optimizations to the application at the cost of being unable
|
||
to debug them with the steps in etc/DEBUG.
|
||
|
||
Emacs is built as a debuggable package by default, but:
|
||
|
||
./configure --without-android-debug
|
||
|
||
will create a release build of Emacs instead. This may be useful when
|
||
running Emacs on resource constrained machines.
|
||
|
||
If you are building an Emacs package for redistribution, we urge you
|
||
to provide both debug and release versions.
|
||
|
||
BUILDING WITH THIRD PARTY LIBRARIES
|
||
|
||
The Android NDK does not support the usual ways of locating third
|
||
party libraries, especially not via `pkg-config'. Instead, it uses
|
||
its own system called `ndk-build'. The one exception to this rule is
|
||
zlib, which is considered a part of the Android OS itself and is
|
||
available on all devices running Android.
|
||
|
||
Android also requires that each application include its own
|
||
dependencies, as the system makes no guarantee about the existence of
|
||
any particular library.
|
||
|
||
Emacs is not built with the `ndk-build' system. Instead, it is built
|
||
with Autoconf and Make.
|
||
|
||
However, it supports building and including dependencies which use the
|
||
similarly Make-based `ndk-build' system.
|
||
|
||
To use dependencies built through `ndk-build', you must specify a list
|
||
of directories within which Emacs will search for ``Android.mk''
|
||
files, like so:
|
||
|
||
./configure "--with-ndk-path=directory1 directory2"
|
||
|
||
Emacs will then read the ``Android.mk'' file in each directory, and
|
||
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:
|
||
|
||
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))
|
||
|
||
We anticipate that most untested non-trivial ndk-build dependencies
|
||
will need adjustments in Emacs to work, as the Emacs build system
|
||
which emulates ndk-build is in an extremely early state.
|
||
|
||
NDK BUILD SYSTEM IMPLEMENTATION
|
||
|
||
Emacs implements ndk-build itself, because the version that comes with
|
||
the Android NDK is not easy to use from another Makefile, and keeps
|
||
accumulating incompatible changes.
|
||
|
||
The Emacs implementation of ndk-build consists of one m4 file:
|
||
|
||
m4/ndk-build.m4
|
||
|
||
four Makefiles in build-aux, run during configure:
|
||
|
||
build-aux/ndk-build-helper-1.mk
|
||
build-aux/ndk-build-helper-2.mk
|
||
build-aux/ndk-build-helper-3.mk
|
||
build-aux/ndk-build-helper.mk
|
||
|
||
one awk script in build-awx, run during configure:
|
||
|
||
build-aux/ndk-module-extract.awk
|
||
|
||
six Makefiles in cross/ndk-build,
|
||
|
||
cross/ndk-build/ndk-build-shared-library.mk
|
||
cross/ndk-build/ndk-build-static-library.mk
|
||
cross/ndk-build/ndk-build-executable.mk
|
||
cross/ndk-build/ndk-clear-vars.mk
|
||
cross/ndk-build/ndk-prebuilt-shared-library.mk
|
||
cross/ndk-build/ndk-prebuilt-static-library.mk
|
||
|
||
and finally, two more Makefiles in cross/ndk-build, generated by
|
||
configure:
|
||
|
||
cross/ndk-build/Makefile (generated from cross/ndk-build/Makefile.in)
|
||
cross/ndk-build/ndk-build.mk (generated from cross/ndk-build/ndk-build.mk.in)
|
||
|
||
m4/ndk-build.m4 is a collection of macros which are used by the
|
||
configure script to set up the ndk-build system, look for modules, add
|
||
the appropriate options to LIBS and CFLAGS, and generate the Makefiles
|
||
necessary to build the rest of Emacs.
|
||
|
||
Immediately after determining the list of directories in which to look
|
||
for ``Android.mk'' files, the version and type of Android system being
|
||
built for, configure calls:
|
||
|
||
ndk_INIT([$android_abi], [$ANDROID_SDK], [cross/ndk-build])
|
||
|
||
This expands to a sequence of shell script that enumerates all of the
|
||
Android.mk files specified in "$with_ndk_path", sets up some shell
|
||
functions used by the rest of the ndk-build code run by the configure
|
||
script, and teaches the ndk-build system that the Makefiles to be
|
||
generated are found in the directory "cross/ndk-build/Makefile".
|
||
|
||
When configure is cross-compiling for Android, the macro
|
||
EMACS_CHECK_MODULES will expand to the macro ndk_CHECK_MODULES,
|
||
instead of pkg-config.m4's PKG_CHECK_MODULES. Thus, the following
|
||
code:
|
||
|
||
EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0])
|
||
|
||
will actually expand to:
|
||
|
||
ndk_CHECK_MODULES([PNG], [libpng >= 1.0.0], [HAVE_PNG=yes],
|
||
[HAVE_PNG=no])
|
||
|
||
which in turn expands to a sequence shell script that first invokes:
|
||
|
||
make -f build-aux/ndk-build-helper.mk
|
||
|
||
for each ``Android.mk'' file found by ndk_INIT, with the following
|
||
variables given to Make:
|
||
|
||
EMACS_SRCDIR=. # the source directory (in which configure is running)
|
||
EMACS_ABI=$ndk_ABI # this is the $android_abi given to ndk_INIT
|
||
ANDROID_MAKEFILE="/opt/android/libpng/Android.mk"
|
||
ANDROID_MODULE_DIRECTORY="/opt/android/libpng"
|
||
NDK_BUILD_DIR="$ndk_DIR" # this is the directory given as to ndk_INIT
|
||
|
||
build-aux/ndk-build-helper.mk will then evaluate the contents
|
||
$(ANDROID_MAKEFILE), the ``Android.mk'' file, for the first time. The
|
||
purpose of this evaluation is to establish a list of packages (or
|
||
modules) provided by the ``Android.mk'' file, and the corresponding
|
||
Makefile targets and compiler and linker flags required to build and
|
||
link to those tagets.
|
||
|
||
Before doing so, build-aux/ndk-build-helper.mk will define several
|
||
variables and functions required by all ``Android.mk'' files. The
|
||
most important of these are:
|
||
|
||
my-dir # the directory containing the Android.mk file.
|
||
BUILD_SHARED_LIBRARY # build-aux/ndk-build-helper-1.mk
|
||
BUILD_STATIC_LIBRARY # build-aux/ndk-build-helper-2.mk
|
||
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).
|
||
|
||
Each one of those three scripts will then read from the variables set
|
||
by ``Android.mk'', resolve dependencies, and print out some text
|
||
describing the module to Emacs. For example, the shared library
|
||
module "libpng" results in the following text being printed:
|
||
|
||
Building shared
|
||
libpng
|
||
/opt/android/libpng/png.c /opt/android/libpng/pngerror.c /opt/android/libpng/pngget.c /opt/android/libpng/pngmem.c /opt/android/libpng/pngpread.c /opt/android/libpng/pngread.c /opt/android/libpng/pngrio.c /opt/android/libpng/pngrtran.c /opt/android/libpng/pngrutil.c /opt/android/libpng/pngset.c /opt/android/libpng/pngtrans.c /opt/android/libpng/pngwio.c /opt/android/libpng/pngwrite.c /opt/android/libpng/pngwtran.c /opt/android/libpng/pngwutil.c
|
||
-I/opt/android/libpng
|
||
|
||
-L/opt/emacs/cross/ndk-build -l:libpng_emacs.so
|
||
libpng_emacs.so
|
||
End
|
||
|
||
The output is arranged as follows:
|
||
|
||
- The first line consists of the word ``Building'', followed by
|
||
either ``shared'', ``static'', or ``executable'', depending on
|
||
what type of module being built.
|
||
|
||
- The second line consists of the name of the module currently being
|
||
built.
|
||
|
||
- The third line consists of all of the source code files comprising
|
||
the module.
|
||
|
||
- The fourth line consists of the text that has to be added to
|
||
CFLAGS in order to find the includes associated with the module.
|
||
|
||
- The fifth line consists of the text that has to be added to LIBS
|
||
in order to link with this module and all of its dependencies.
|
||
|
||
- The sixth line consists of the Make targets (more on this later)
|
||
that will build the final shared object or library archive of this
|
||
module, along with all of its dependencies.
|
||
|
||
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:
|
||
|
||
awk -f build-aux/ndk-module-extract.awk MODULE=libpng
|
||
|
||
eventually generating this section of shell script:
|
||
|
||
module_name=libpng
|
||
module_kind=shared
|
||
module_src="/opt/android/libpng/png.c /opt/android/libpng/pngerror.c /opt/android/libpng/pngget.c /opt/android/libpng/pngmem.c /opt/android/libpng/pngpread.c /opt/android/libpng/pngread.c /opt/android/libpng/pngrio.c /opt/android/libpng/pngrtran.c /opt/android/libpng/pngrutil.c /opt/android/libpng/pngset.c /opt/android/libpng/pngtrans.c /opt/android/libpng/pngwio.c /opt/android/libpng/pngwrite.c /opt/android/libpng/pngwtran.c /opt/android/libpng/pngwutil.c"
|
||
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"
|
||
|
||
which is then evaluated by `configure'. Once the variable
|
||
`module_name' is set, configure apends the remaining
|
||
$(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.
|
||
|
||
Finally, immediately before generating src/Makefile.android, configure
|
||
expands:
|
||
|
||
ndk_CONFIG_FILES
|
||
|
||
to generate $ndk_DIR/Makefile and $ndk_DIR/ndk-build.mk.
|
||
|
||
Now, the $ndk_DIR directory is set up to build all modules upon which
|
||
depends, and $ndk_DIR/ndk-build.mk includes a list of files required
|
||
to link Emacs, along with the rules to chdir into $ndk_DIR in order to
|
||
build them.
|
||
|
||
$ndk_DIR/ndk-build.mk is included by cross/src/Makefile
|
||
(Makefile.android) and java/Makefile. It defines three different
|
||
variables:
|
||
|
||
NDK_BUILD_MODULES the file names of all modules to be built.
|
||
NDK_BUILD_STATIC absolute names of all library archives
|
||
to be built.
|
||
NDK_BUILD_SHARED absolute names of all shared libraries to
|
||
be built.
|
||
|
||
and then proceeds to define rules to build each of the modules in
|
||
$(NDK_BUILD_MODULES).
|
||
|
||
cross/src/Makefile arranges to have all dependencies of Emacs not
|
||
already built built before linking ``libemacs.so'' with them.
|
||
|
||
java/Makefile additionally arranges to have all shared object
|
||
dependencies built before the application package is built, which is
|
||
normally redundant because they should have already been built before
|
||
linking ``libemacs.so''.
|
||
|
||
Building the modules is performed through $ndk_DIR/Makefile, which
|
||
contains the actual implementation of the ``ndk-build'' build system.
|
||
First, it defines certain variables constant within the ``ndk-build''
|
||
build system, such as the files included by ``Android.mk'' to build
|
||
shared or static libraries, and CLEAR_VARS. The most important of
|
||
these are:
|
||
|
||
CLEAR_VARS cross/ndk-build/ndk-clear-vars.mk
|
||
BUILD_EXECUTABLE cross/ndk-build/ndk-build-executable.mk
|
||
BUILD_SHARED_LIBRARY cross/ndk-build/ndk-build-shared-library.mk
|
||
BUILD_STATIC_LIBRARY cross/ndk-build/ndk-build-static-library.mk
|
||
PREBUILT_SHARED_LIBRARY cross/ndk-build/ndk-prebuilt-shared-library.mk
|
||
PREBUILT_STATIC_LIBRARY cross/ndk-build/ndk-prebuilt-static-library.mk
|
||
|
||
Then, it loads each Emacs dependency's ``Android.mk'' file. For each
|
||
module defined there, ``Android.mk'' includes $(CLEAR_VARS) to unset
|
||
all variables specific to each module, and then includes
|
||
$(BUILD_SHARED_LIBRARY) or $(BUILD_STATIC_LIBRARY) for each shared or
|
||
static library module.
|
||
|
||
This results in cross/ndk-build/ndk-build-shared-library.mk or
|
||
cross/ndk-build/ndk-build-static-library being included, just like the
|
||
Makefiles in build-aux were inside the configure script.
|
||
|
||
Each one of those two scripts then defines rules to build all of the
|
||
object files associated with the module, and then link or archive
|
||
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.
|
||
|
||
However, none of the Makefiles in
|
||
cross/ndk-build/ndk-build-shared-library.mk perform any kind of
|
||
dependency resolution! Instead, they only define rules to build
|
||
individual modules, leaving dependency resolution up to the Makefiles
|
||
in the `build-aux' directory.
|
||
|
||
libpng is a very simple module, providing only a single shared object
|
||
module. This module is named libpng_emacs.so and is eventually built
|
||
and packaged into the library directory of the Emacs application
|
||
package. Now, let us look at a more complex module, libwebp:
|
||
|
||
|
||
|
||
When built with libwebp, Emacs depends on a single library,
|
||
libwebpdemux. This library is named ``libwebpdemux'' on Unix systems,
|
||
and that is the name by which it is found with pkg-config.
|
||
|
||
However, the library's module is only named ``webpdemux'' on Android.
|
||
When ndk_CHECK_MODULES begins to look for a module, it first tries to
|
||
see if its name is found in the variable `ndk_package_map', which was
|
||
set inside ndk_INIT. In this case, it finds the following word:
|
||
|
||
libwebpdemux:webpdemux
|
||
|
||
and immediately replaces ``libwebpdemux'' with ``webpdemux''.
|
||
|
||
Then, it locates the ``Android.mk'' file containing a static library
|
||
module named webpdemux and gives the output from
|
||
build-aux/ndk-build-helper.mk to the awk script, resulting in:
|
||
|
||
module_name=webpdemux
|
||
module_kind=static
|
||
module_src="/opt/android/webp/src/demux/anim_decode.c /opt/android/webp/src/demux/demux.c"
|
||
module_includes="-I/opt/android/webp/src"
|
||
module_cflags=""
|
||
module_ldflags=" cross/ndk-build/libwebpdemux.a cross/ndk-build/libwebp.a cross/ndk-build/libwebpdecoder_static.a "
|
||
module_target="libwebpdemux.a libwebp.a libwebpdecoder_static.a"
|
||
|
||
The attentive reader will notice that in addition to the
|
||
``libwebpdemux.a'' archive associated with the ``webpdemux'' library,
|
||
Emacs has been made to link with two additional libraries. This is
|
||
because the ``webpdemux'' module specifies a dependency on the
|
||
``webp'' module (defined in the same Android.mk).
|
||
build-aux/ndk-build-helper.mk resolved that dependency, noticing that
|
||
it in turn specified another dependency on ``webpdecoder_static'',
|
||
which in turn was added to the linker command line and list of targets
|
||
to build.
|
||
|
||
As a result, all three dependencies will be built and linked to Emacs,
|
||
instead of just the single ``webpdemux'' dependency that was
|
||
specified.
|
||
|
||
|
||
|
||
This file is part of GNU Emacs.
|
||
|
||
GNU Emacs is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
GNU Emacs is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
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 <https://www.gnu.org/licenses/>.
|