From ea622e321d500715238214db9d8b994cffe8568e Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sat, 11 May 2019 14:56:56 +0200 Subject: Add nativecomp option to configure --- configure.ac | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 24d21c7afd9..d059b7d6724 100644 --- a/configure.ac +++ b/configure.ac @@ -463,6 +463,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) +OPTION_DEFAULT_ON([nativecomp],[don't compile with emacs lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -3670,6 +3671,17 @@ if test "${HAVE_ZLIB}" = "yes"; then fi AC_SUBST(LIBZ) +HAVE_LIBGCCJIT=no +LIBGCCJIT_LIB= +if test "${with_nativecomp}" != "no"; then + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_LIBGCCJIT=yes, , -lgccjit) + if test "${HAVE_LIBGCCJIT}" = "yes"; then + LIBGCCJIT_LIB=-lgccjit + AC_DEFINE([HAVE_LIBGCCJIT], 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + fi +fi +AC_SUBST([LIBGCCJIT_LIB]) + ### Dynamic modules support LIBMODULES= HAVE_MODULES=no @@ -5714,6 +5726,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D Does Emacs support the portable dumper? ${with_pdumper} Does Emacs support legacy unexec dumping? ${with_unexec} Which dumping strategy does Emacs use? ${with_dumping} + Does Emacs have native lisp compiler? ${with_nativecomp} "]) if test -n "${EMACSDATA}"; then -- cgit v1.2.3 From a2257a531d0cd4c1d2bbfe374f490fa956be0330 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 1 Sep 2019 11:22:35 +0200 Subject: add NATIVE_ELISP_SUFFIX def into congure.ac --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index d059b7d6724..6213051a602 100644 --- a/configure.ac +++ b/configure.ac @@ -3678,6 +3678,8 @@ if test "${with_nativecomp}" != "no"; then if test "${HAVE_LIBGCCJIT}" = "yes"; then LIBGCCJIT_LIB=-lgccjit AC_DEFINE([HAVE_LIBGCCJIT], 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", + [System extension for native compiled elisp]) fi fi AC_SUBST([LIBGCCJIT_LIB]) -- cgit v1.2.3 From 17259826f263f87d45eb98c8effe0ba7ee774f5d Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 8 Sep 2019 09:40:42 +0200 Subject: fix build system for native compiler option --- configure.ac | 10 +++++++--- src/Makefile.in | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 6213051a602..a36a2f32428 100644 --- a/configure.ac +++ b/configure.ac @@ -3671,18 +3671,22 @@ if test "${HAVE_ZLIB}" = "yes"; then fi AC_SUBST(LIBZ) +### Emacs Lisp native compiler support HAVE_LIBGCCJIT=no LIBGCCJIT_LIB= +COMP_OBJ= if test "${with_nativecomp}" != "no"; then AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_LIBGCCJIT=yes, , -lgccjit) if test "${HAVE_LIBGCCJIT}" = "yes"; then - LIBGCCJIT_LIB=-lgccjit - AC_DEFINE([HAVE_LIBGCCJIT], 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + LIBGCCJIT_LIB="-lgccjit -ldl" + COMP_OBJ="dynlib.o comp.o" + AC_DEFINE(HAVE_LIBGCCJIT, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) fi fi -AC_SUBST([LIBGCCJIT_LIB]) +AC_SUBST(LIBGCCJIT_LIB) +AC_SUBST(COMP_OBJ) ### Dynamic modules support LIBMODULES= diff --git a/src/Makefile.in b/src/Makefile.in index 5e0e36d8b4d..6c65275d6da 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -327,6 +327,8 @@ GMP_LIB = @GMP_LIB@ GMP_OBJ = @GMP_OBJ@ LIBGCCJIT = @LIBGCCJIT_LIB@ +## dynlib.o comp.o if native compiler is enabled, else empty +COMP_OBJ = @COMP_OBJ@ RUN_TEMACS = ./temacs @@ -416,7 +418,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \ alloc.o pdumper.o data.o doc.o editfns.o callint.o \ eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \ - syntax.o $(UNEXEC_OBJ) bytecode.o comp.o \ + syntax.o $(UNEXEC_OBJ) bytecode.o $(COMP_OBJ) \ process.o gnutls.o callproc.o \ region-cache.o sound.o timefns.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \ -- cgit v1.2.3 From 06ad74581385cd1930a073b2fda314230b254608 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 8 Sep 2019 10:11:36 +0200 Subject: rename HAVE_LIBGCCJIT -> HAVE_NATIVE_COMP --- configure.ac | 8 ++++---- src/comp.c | 4 ++-- src/emacs.c | 2 +- src/lread.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index a36a2f32428..0cfd80bb2e8 100644 --- a/configure.ac +++ b/configure.ac @@ -3672,15 +3672,15 @@ fi AC_SUBST(LIBZ) ### Emacs Lisp native compiler support -HAVE_LIBGCCJIT=no +HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then - AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_LIBGCCJIT=yes, , -lgccjit) - if test "${HAVE_LIBGCCJIT}" = "yes"; then + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit) + if test "${HAVE_NATIVE_COMP}" = "yes"; then LIBGCCJIT_LIB="-lgccjit -ldl" COMP_OBJ="dynlib.o comp.o" - AC_DEFINE(HAVE_LIBGCCJIT, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) fi diff --git a/src/comp.c b/src/comp.c index 00e15601998..2b6f8bf0536 100644 --- a/src/comp.c +++ b/src/comp.c @@ -20,7 +20,7 @@ along with GNU Emacs. If not, see . */ #include -#ifdef HAVE_LIBGCCJIT +#ifdef HAVE_NATIVE_COMP #include #include @@ -3283,4 +3283,4 @@ syms_of_comp (void) comp_speed = DEFAULT_SPEED; } -#endif /* HAVE_LIBGCCJIT */ +#endif /* HAVE_NATIVE_COMP */ diff --git a/src/emacs.c b/src/emacs.c index c59a70988b7..90ab7ac1e8e 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1598,7 +1598,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem init_json (); #endif -#ifdef HAVE_LIBGCCJIT +#ifdef HAVE_NATIVE_COMP if (!initialized) syms_of_comp (); #endif diff --git a/src/lread.c b/src/lread.c index b10743f980c..f1b17edd011 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1281,7 +1281,7 @@ Return t if the file exists and loads successfully. */) bool is_module = false; #endif -#ifdef HAVE_LIBGCCJIT +#ifdef HAVE_NATIVE_COMP bool is_native_elisp = suffix_p (found, NATIVE_ELISP_SUFFIX); #else bool is_native_elisp = false; @@ -1486,7 +1486,7 @@ Return t if the file exists and loads successfully. */) } else if (is_native_elisp) { -#ifdef HAVE_LIBGCCJIT +#ifdef HAVE_NATIVE_COMP specbind (Qcurrent_load_list, Qnil); LOADHIST_ATTACH (found); Fnative_elisp_load (found); @@ -4896,7 +4896,7 @@ to the specified file name if a suffix is allowed or required. */); Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes); #endif #endif -#ifdef HAVE_LIBGCCJIT +#ifdef HAVE_NATIVE_COMP Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), Vload_suffixes); #endif -- cgit v1.2.3 From 1d3c0d1716eb2025c1dd2e07195b55bb5781fdd3 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Thu, 24 Oct 2019 14:36:28 +0200 Subject: fix compilation when modules are enabled --- configure.ac | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0cfd80bb2e8..c86dac6a65b 100644 --- a/configure.ac +++ b/configure.ac @@ -3671,23 +3671,6 @@ if test "${HAVE_ZLIB}" = "yes"; then fi AC_SUBST(LIBZ) -### Emacs Lisp native compiler support -HAVE_NATIVE_COMP=no -LIBGCCJIT_LIB= -COMP_OBJ= -if test "${with_nativecomp}" != "no"; then - AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit) - if test "${HAVE_NATIVE_COMP}" = "yes"; then - LIBGCCJIT_LIB="-lgccjit -ldl" - COMP_OBJ="dynlib.o comp.o" - AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) - AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", - [System extension for native compiled elisp]) - fi -fi -AC_SUBST(LIBGCCJIT_LIB) -AC_SUBST(COMP_OBJ) - ### Dynamic modules support LIBMODULES= HAVE_MODULES=no @@ -3754,6 +3737,28 @@ module_env_snippet_28="$srcdir/src/module-env-28.h" emacs_major_version="${PACKAGE_VERSION%%.*}" AC_SUBST(emacs_major_version) +### Emacs Lisp native compiler support +HAVE_NATIVE_COMP=no +LIBGCCJIT_LIB= +COMP_OBJ= +if test "${with_nativecomp}" != "no"; then + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit) + if test "${HAVE_NATIVE_COMP}" = "yes"; then + LIBGCCJIT_LIB="-lgccjit -ldl" + if test "${HAVE_MODULES}" = yes; then + COMP_OBJ="comp.o" + else + COMP_OBJ="dynlib.o comp.o" + fi + AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", + [System extension for native compiled elisp]) + fi +fi +AC_SUBST(LIBGCCJIT_LIB) +AC_SUBST(COMP_OBJ) + + ### Use -lpng if available, unless '--with-png=no'. HAVE_PNG=no LIBPNG= -- cgit v1.2.3 From 06fc663f519eefb431912ebdae8711ed016e0703 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Tue, 12 Nov 2019 23:27:09 +0100 Subject: better configure check for libgccjit.h file instead of the shared lib in configure --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c86dac6a65b..c1e39773300 100644 --- a/configure.ac +++ b/configure.ac @@ -3742,7 +3742,7 @@ HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then - AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit) + AC_CHECK_HEADER([libgccjit.h], [HAVE_NATIVE_COMP=yes]) if test "${HAVE_NATIVE_COMP}" = "yes"; then LIBGCCJIT_LIB="-lgccjit -ldl" if test "${HAVE_MODULES}" = yes; then -- cgit v1.2.3 From 3d0a3a51b8f1635ec872fc3f0a54c2d58ba48b4e Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 17 Nov 2019 11:19:17 +0100 Subject: fix configure.ac --- configure.ac | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c1e39773300..03570bd6c90 100644 --- a/configure.ac +++ b/configure.ac @@ -3753,6 +3753,11 @@ if test "${with_nativecomp}" != "no"; then AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) + else + AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. +If you are sure you want Emacs compiled without elisp native compiler, pass + --without-nativecomp +to configure.]) fi fi AC_SUBST(LIBGCCJIT_LIB) @@ -5737,7 +5742,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D Does Emacs support the portable dumper? ${with_pdumper} Does Emacs support legacy unexec dumping? ${with_unexec} Which dumping strategy does Emacs use? ${with_dumping} - Does Emacs have native lisp compiler? ${with_nativecomp} + Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP} "]) if test -n "${EMACSDATA}"; then -- cgit v1.2.3 From 498468a2367524c7bd763826df5aad2b76345912 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Tue, 31 Dec 2019 00:37:47 +0100 Subject: make build system configurable again --- configure.ac | 2 +- lisp/Makefile.in | 40 ++++++++++++++++++++++------------------ src/Makefile.in | 1 - 3 files changed, 23 insertions(+), 20 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 03570bd6c90..2afa9572544 100644 --- a/configure.ac +++ b/configure.ac @@ -3760,10 +3760,10 @@ If you are sure you want Emacs compiled without elisp native compiler, pass to configure.]) fi fi +AC_SUBST(HAVE_NATIVE_COMP) AC_SUBST(LIBGCCJIT_LIB) AC_SUBST(COMP_OBJ) - ### Use -lpng if available, unless '--with-png=no'. HAVE_PNG=no LIBPNG= diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 5bcb85ff141..cfc6f494991 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -32,14 +32,15 @@ XARGS_LIMIT = @XARGS_LIMIT@ # 'make' verbosity. AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_V_ELN = $(am__v_ELN_@AM_V@) -am__v_ELN_ = $(am__v_ELN_@AM_DEFAULT_V@) -am__v_ELN_0 = @echo " ELC+ELN " $@; -am__v_ELN_1 = +HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@ AM_V_ELC = $(am__v_ELC_@AM_V@) am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) +ifeq ($(HAVE_NATIVE_COMP),yes) am__v_ELC_0 = @echo " ELC+ELN " $@; +else +am__v_ELC_0 = @echo " ELC " $@; +endif am__v_ELC_1 = AM_V_GEN = $(am__v_GEN_@AM_V@) @@ -103,9 +104,11 @@ COMPILE_FIRST = \ $(lisp)/emacs-lisp/macroexp.elc \ $(lisp)/emacs-lisp/cconv.elc \ $(lisp)/emacs-lisp/byte-opt.elc \ - $(lisp)/emacs-lisp/bytecomp.elc \ - $(lisp)/emacs-lisp/autoload.elc \ - $(lisp)/emacs-lisp/comp.elc + $(lisp)/emacs-lisp/bytecomp.elc +ifeq ($(HAVE_NATIVE_COMP),yes) +COMPILE_FIRST += $(lisp)/emacs-lisp/comp.elc +endif +COMPILE_FIRST += $(lisp)/emacs-lisp/autoload.elc # Files to compile early in compile-main. Works around bug#25556. MAIN_FIRST = ./emacs-lisp/eieio.el ./emacs-lisp/eieio-base.el \ @@ -280,19 +283,18 @@ TAGS: ${ETAGS} ${tagsfiles} # src/Makefile.in to rebuild a particular Lisp file, no questions asked. # Use byte-compile-refresh-preloaded to try and work around some of # the most common problems of not bootstrapping from a clean state. -# THEFILE = no-such-file -# .PHONY: $(THEFILE)c -# $(THEFILE)c: -# $(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \ -# -l bytecomp -f byte-compile-refresh-preloaded \ -# -f batch-byte-compile $(THEFILE) - THEFILE = no-such-file .PHONY: $(THEFILE)c $(THEFILE)c: - $(AM_V_ELN)$(emacs) $(BYTE_COMPILE_FLAGS) \ +ifeq ($(HAVE_NATIVE_COMP),yes) + $(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \ -l comp -f byte-compile-refresh-preloaded \ -f batch-byte-native-compile-for-bootstrap $(THEFILE) +else + $(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \ + -l bytecomp -f byte-compile-refresh-preloaded \ + -f batch-byte-compile $(THEFILE) +endif # Files MUST be compiled one by one. If we compile several files in a # row (i.e., in the same instance of Emacs) we can't make sure that @@ -305,12 +307,14 @@ $(THEFILE)c: # An old-fashioned suffix rule, which, according to the GNU Make manual, # cannot have prerequisites. +ifeq ($(HAVE_NATIVE_COMP),yes) .el.elc: $(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \ -l comp -f batch-byte-native-compile-for-bootstrap $< - -.el.eln: - $(AM_V_ELN)$(emacs) $(BYTE_COMPILE_FLAGS) -f batch-native-compile $< +else +.el.elc: + $(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) -f batch-byte-compile $< +endif .PHONY: compile-first compile-main compile compile-always diff --git a/src/Makefile.in b/src/Makefile.in index cc43cd9f319..6a151d18d02 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -513,7 +513,6 @@ lisp.mk: $(lispsource)/loadup.el sed -e 's/$$/.elc \\/' -e 's/\.el\.elc/.el/'; \ echo "" ) > $@ - -include lisp.mk shortlisp_filter = leim/leim-list.el site-load.elc site-init.elc shortlisp := $(filter-out ${shortlisp_filter},${shortlisp}) -- cgit v1.2.3 From 3ba1b52e277261286738b637e45a675b7d587f58 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Tue, 31 Dec 2019 03:10:13 +0100 Subject: check for libgccjit lib to be reachable in configure.ac --- configure.ac | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 2afa9572544..8c8b57c1079 100644 --- a/configure.ac +++ b/configure.ac @@ -3742,14 +3742,11 @@ HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then - AC_CHECK_HEADER([libgccjit.h], [HAVE_NATIVE_COMP=yes]) + AC_CHECK_HEADER(libgccjit.h, + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit)) if test "${HAVE_NATIVE_COMP}" = "yes"; then LIBGCCJIT_LIB="-lgccjit -ldl" - if test "${HAVE_MODULES}" = yes; then - COMP_OBJ="comp.o" - else - COMP_OBJ="dynlib.o comp.o" - fi + COMP_OBJ+=comp.o AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) -- cgit v1.2.3 From 11192b29adf4ee500f5056d1b02d35908f858b53 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 1 Jan 2020 21:13:13 +0100 Subject: make standard emacs compilable again --- configure.ac | 4 ++-- lisp/Makefile.in | 6 ++++++ src/comp.h | 4 ++-- src/lread.c | 5 +++-- src/pdumper.c | 2 ++ 5 files changed, 15 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 8c8b57c1079..247484a8501 100644 --- a/configure.ac +++ b/configure.ac @@ -3748,8 +3748,6 @@ if test "${with_nativecomp}" != "no"; then LIBGCCJIT_LIB="-lgccjit -ldl" COMP_OBJ+=comp.o AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) - AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", - [System extension for native compiled elisp]) else AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. If you are sure you want Emacs compiled without elisp native compiler, pass @@ -3757,6 +3755,8 @@ If you are sure you want Emacs compiled without elisp native compiler, pass to configure.]) fi fi +AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", + [System extension for native compiled elisp]) AC_SUBST(HAVE_NATIVE_COMP) AC_SUBST(LIBGCCJIT_LIB) AC_SUBST(COMP_OBJ) diff --git a/lisp/Makefile.in b/lisp/Makefile.in index cfc6f494991..5793b6474dc 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -332,7 +332,13 @@ compile-first: $(COMPILE_FIRST) .PHONY: compile-targets # TARGETS is set dynamically in the recursive call from 'compile-main'. +# Do not build comp.el unless necessary not to exceed max-specpdl-size and +# max-lisp-eval-depth in normal builds. +ifneq ($(HAVE_NATIVE_COMP),yes) +compile-targets: $(filter-out ./emacs-lisp/comp.elc,$(TARGETS)) +else compile-targets: $(TARGETS) +endif # Compile all the Elisp files that need it. Beware: it approximates # 'no-byte-compile', so watch out for false-positives! diff --git a/src/comp.h b/src/comp.h index 33b73548009..86fa54f5158 100644 --- a/src/comp.h +++ b/src/comp.h @@ -29,8 +29,6 @@ enum { #endif }; -#ifdef HAVE_NATIVE_COMP - #include struct Lisp_Native_Comp_Unit @@ -43,6 +41,8 @@ struct Lisp_Native_Comp_Unit dynlib_handle_ptr handle; }; +#ifdef HAVE_NATIVE_COMP + INLINE bool NATIVE_COMP_UNITP (Lisp_Object a) { diff --git a/src/lread.c b/src/lread.c index 1c5268d0dad..d6d13861417 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4464,8 +4464,9 @@ defsubr (union Aligned_Lisp_Subr *aname) XSETPVECTYPE (sname, PVEC_SUBR); XSETSUBR (tem, sname); set_symbol_function (sym, tem); - if (NATIVE_COMP_FLAG) - Vcomp_subr_list = Fcons (tem, Vcomp_subr_list); +#ifdef HAVE_NATIVE_COMP + Vcomp_subr_list = Fcons (tem, Vcomp_subr_list); +#endif } #ifdef NOTDEF /* Use fset in subr.el now! */ diff --git a/src/pdumper.c b/src/pdumper.c index 85809c9978f..ae8fe014e0e 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5296,6 +5296,7 @@ dump_do_dump_relocation (const uintptr_t dump_base, dump_write_word_to_dump (dump_base, reloc_offset, value); break; } +#ifdef HAVE_NATIVE_COMP case RELOC_NATIVE_COMP_UNIT: { struct Lisp_Native_Comp_Unit *comp_u = @@ -5323,6 +5324,7 @@ dump_do_dump_relocation (const uintptr_t dump_base, subr->function.a0 = func; break; } +#endif case RELOC_BIGNUM: { struct Lisp_Bignum *bignum = dump_ptr (dump_base, reloc_offset); -- cgit v1.2.3 From dd66ef5ad198fe914dd603a484e1459dff2af641 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 1 Jan 2020 11:16:59 +0100 Subject: set nativecomp configure option off by default --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 247484a8501..717b4564999 100644 --- a/configure.ac +++ b/configure.ac @@ -463,7 +463,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) -OPTION_DEFAULT_ON([nativecomp],[don't compile with emacs lisp native compiler support]) +OPTION_DEFAULT_OFF([nativecomp],[don't compile with emacs lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], -- cgit v1.2.3 From a59cc78fcb8df8acbf5139c2b4d2fada55627248 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Fri, 3 Jan 2020 02:49:01 +0100 Subject: Simplify configure.ac removing unnecessary empty parameters --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 717b4564999..9c8a6e3a9fc 100644 --- a/configure.ac +++ b/configure.ac @@ -3743,7 +3743,7 @@ LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then AC_CHECK_HEADER(libgccjit.h, - AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes, , -lgccjit)) + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes)) if test "${HAVE_NATIVE_COMP}" = "yes"; then LIBGCCJIT_LIB="-lgccjit -ldl" COMP_OBJ+=comp.o -- cgit v1.2.3 From ec5d95782d90c6b6b7f291a4a8214cc7f64dadd6 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Fri, 21 Feb 2020 10:24:32 +0100 Subject: Verify '--with-nativecomp' has also '--with-dumping=pdumper' --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c8e22ff5925..0b2f5b69d6b 100644 --- a/configure.ac +++ b/configure.ac @@ -3738,6 +3738,9 @@ If you are sure you want Emacs compiled without elisp native compiler, pass to configure.]) fi fi +if test "${HAVE_NATIVE_COMP}" = yes && test "${HAVE_PDUMPER}" = no; then + AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) +fi AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) AC_SUBST(HAVE_NATIVE_COMP) -- cgit v1.2.3 From 46a4ca4774e27f76c93277db187df31aa6e1cf2e Mon Sep 17 00:00:00 2001 From: Adam Porter Date: Sun, 15 Mar 2020 10:19:22 +0000 Subject: comp.el: Minor improvements Change: (comp-start-async-worker) Refactor slightly Change: (comp-start-async-worker) Inline (comp-to-file-p) Change: (comp-source-files) Rename from comp-src-pool Add: (comp-start-async-worker) Assertion Change: (comp-async-processes) Rename from comp-prc-pool Tidy: (native-compile) Rename variables, improve docstring, adjust log message, simplify filename code. Tidy: (batch-native-compile) Docstring Tidy: whitespace-cleanup Tidy: (comp-start-async-worker) Use () instead of nil Tidy: (comp-files-queue) Rename from comp-source-files Change: (native-compile-async) Improve paths support Tidy: Comment Save a line for one word. :) Change: (comp-log) Rewrite without macro, follow tail Change: (native-compile-async) Use end-of-string in filename regexps Change: (native-compile-async) Use cl-loop instead of dotimes Add/Change: (comp-log-to-buffer) And use in comp-log Comment: Tidy comment Fix: (configure.ac) Option description Fix: (comp-log) Argument Fix: (comp-start-async-worker) Variable name Change: Undo whitespace changes Some of them included incorrect indentation because the macros' (declare (indent)) forms were not loaded. The whitespace-cleanup should be run from Emacs 27+ with the file loaded. --- configure.ac | 2 +- lisp/emacs-lisp/comp.el | 249 +++++++++++++++++++++++++----------------------- 2 files changed, 133 insertions(+), 118 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0b2f5b69d6b..393a53d7633 100644 --- a/configure.ac +++ b/configure.ac @@ -463,7 +463,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) -OPTION_DEFAULT_OFF([nativecomp],[don't compile with emacs lisp native compiler support]) +OPTION_DEFAULT_OFF([nativecomp],[compile with Emacs Lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 0779373667d..2ce530ee592 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -356,34 +356,44 @@ Assume allocaiton class 'd-default as default." (puthash obj t (comp-data-container-idx (comp-alloc-class-to-container comp-curr-allocation-class)))) -(defmacro comp-within-log-buff (&rest body) - "Execute BODY while at the end the log-buffer. -BODY is evaluate only if `comp-verbose' is > 0." - (declare (debug (form body)) - (indent defun)) - `(when (> comp-verbose 0) - (with-current-buffer (get-buffer-create comp-log-buffer-name) - (setf buffer-read-only t) - (let ((inhibit-read-only t)) - (goto-char (point-max)) - ,@body)))) - -(defun comp-log (data verbosity) - "Log DATA given VERBOSITY." - (when (>= comp-verbose verbosity) +(cl-defun comp-log (data &optional (level 1)) + "Log DATA at LEVEL. +LEVEL is a number from 1-3; if it is less than `comp-verbose', do +nothing. If `noninteractive', log with `message'. Otherwise, +log with `comp-log-to-buffer'." + (when (>= comp-verbose level) (if noninteractive - (if (atom data) - (message "%s" data) - (mapc (lambda (x) - (message "%s"(prin1-to-string x))) - data)) - (comp-within-log-buff - (if (and data (atom data)) - (insert data) - (mapc (lambda (x) - (insert (prin1-to-string x) "\n")) - data) - (insert "\n")))))) + (cl-typecase data + (atom (message "%s" data)) + (t (dolist (elem data) + (message "%s" elem)))) + (comp-log-to-buffer data)))) + +(cl-defun comp-log-to-buffer (data) + "Log DATA to `comp-log-buffer-name'." + (let* ((log-buffer + (or (get-buffer comp-log-buffer-name) + (with-current-buffer (get-buffer-create comp-log-buffer-name) + (setf buffer-read-only t) + (current-buffer)))) + (log-window (get-buffer-window log-buffer)) + (inhibit-read-only t) + at-end-p) + (with-current-buffer log-buffer + (when (= (point) (point-max)) + (setf at-end-p t)) + (save-excursion + (goto-char (point-max)) + (cl-typecase data + (atom (princ data log-buffer)) + (t (dolist (elem data) + (princ elem log-buffer) + (insert "\n")))) + (insert "\n")) + (when (and at-end-p log-window) + ;; When log window's point is at the end, follow the tail. + (with-selected-window log-window + (goto-char (point-max))))))) (defun comp-log-func (func verbosity) "Log function FUNC. @@ -2052,105 +2062,108 @@ Prepare every function for final compilation and drive the C back-end." ;; Some entry point support code. -(defvar comp-src-pool () - "List containing the files to be compiled.") - -(defvar comp-prc-pool () - "List containing all async compilation processes.") - -(defun comp-to-file-p (file) - "Return t if FILE has to be compiled." - (let ((compiled-f (concat file "n"))) - (or comp-always-compile - (not (and (file-exists-p compiled-f) - (file-newer-than-file-p compiled-f file)))))) - -(cl-defun comp-start-async-worker () - "Run an async compile worker." - (let (f) - (while (setf f (pop comp-src-pool)) - (when (comp-to-file-p f) - (let* ((code `(progn - (require 'comp) - (setf comp-speed ,comp-speed - comp-debug ,comp-debug - comp-verbose ,comp-verbose - load-path ',load-path) - (message "Compiling %s started." ,f) - (native-compile ,f)))) - (push (make-process :name (concat "Compiling: " f) - :buffer (get-buffer-create comp-async-buffer-name) - :command (list (concat invocation-directory - invocation-name) - "--batch" - "--eval" - (prin1-to-string code)) - :sentinel (lambda (prc _event) - (run-hook-with-args - 'comp-async-cu-done-hook - f) - (accept-process-output prc) - (comp-start-async-worker))) - comp-prc-pool) - (cl-return-from comp-start-async-worker)))) - (when (cl-notany #'process-live-p comp-prc-pool) +(defvar comp-files-queue () + "List of Elisp files to be compiled.") + +(defvar comp-async-processes () + "List of running async compilation processes.") + +(defun comp-start-async-worker () + "Start compiling files from `comp-files-queue' asynchronously. +When compilation is finished, run `comp-async-all-done-hook' and +display a message." + (if comp-files-queue + (cl-loop + for source-file = (pop comp-files-queue) + while source-file + do (cl-assert (string-match-p (rx ".el" eos) source-file) nil + "`comp-files-queue' should be \".el\" files: %s" + source-file) + when (or comp-always-compile + (file-newer-than-file-p source-file (concat source-file "n"))) + do (let* ((expr `(progn + (require 'comp) + (setf comp-speed ,comp-speed + comp-debug ,comp-debug + comp-verbose ,comp-verbose + load-path ',load-path) + (message "Compiling %s..." ,source-file) + (native-compile ,source-file))) + (process (make-process + :name (concat "Compiling: " source-file) + :buffer (get-buffer-create comp-async-buffer-name) + :command (list + (expand-file-name invocation-name + invocation-directory) + "--batch" "--eval" (prin1-to-string expr)) + :sentinel (lambda (process _event) + (run-hook-with-args + 'comp-async-cu-done-hook + source-file) + (accept-process-output process) + (comp-start-async-worker))))) + (push process comp-async-processes))) + ;; No files left to compile. + (when (cl-notany #'process-live-p comp-async-processes) (let ((msg "Compilation finished.")) - (setf comp-prc-pool ()) + (setf comp-async-processes ()) (run-hooks 'comp-async-all-done-hook) (with-current-buffer (get-buffer-create comp-async-buffer-name) (save-excursion (goto-char (point-max)) (insert msg "\n"))) (message msg))))) + ;;; Compiler entry points. ;;;###autoload -(defun native-compile (input) - "Compile INPUT into native code. +(defun native-compile (function-or-file) + "Compile FUNCTION-OR-FILE into native code. This is the entry-point for the Emacs Lisp native compiler. -If INPUT is a symbol, native compile its function definition. -If INPUT is a string, use it as the file path to be native compiled. +FUNCTION-OR-FILE is a function symbol or a path to an Elisp file. Return the compilation unit file name." - (unless (or (symbolp input) - (stringp input)) + (unless (or (functionp function-or-file) + (stringp function-or-file)) (signal 'native-compiler-error - (list "not a symbol function or file" input))) - (let ((data input) - (comp-native-compiling t) - ;; Have the byte compiler signal an error when compilation - ;; fails. - (byte-compile-debug t) - (comp-ctxt (make-comp-ctxt - :output - (if (symbolp input) - (make-temp-file (concat (symbol-name input) "-")) - (let ((exp-file (expand-file-name input))) - (cl-assert comp-native-path-postfix) - (concat - (file-name-as-directory - (concat - (file-name-directory exp-file) - comp-native-path-postfix)) - (file-name-sans-extension - (file-name-nondirectory exp-file)))))))) + (list "Not a function symbol or file" function-or-file))) + (let* ((data function-or-file) + (comp-native-compiling t) + ;; Have byte compiler signal an error when compilation fails. + (byte-compile-debug t) + (comp-ctxt + (make-comp-ctxt + :output + (if (symbolp function-or-file) + (make-temp-file (concat (symbol-name function-or-file) "-")) + (let* ((expanded-filename (expand-file-name function-or-file)) + (output-dir (file-name-as-directory + (concat (file-name-directory expanded-filename) + comp-native-path-postfix))) + (output-filename + (file-name-sans-extension + (file-name-nondirectory expanded-filename)))) + (expand-file-name output-filename output-dir)))))) (comp-log "\n \n" 1) (condition-case err (mapc (lambda (pass) - (comp-log (format "Running pass %s:\n" pass) 2) + (comp-log (format "(%s) Running pass %s:\n" + function-or-file pass) + 2) (setf data (funcall pass data))) comp-passes) (native-compiler-error ;; Add source input. (let ((err-val (cdr err))) - (signal (car err) (if (consp err-val) - (cons input err-val) - (list input err-val)))))) + (signal (car err) (if (consp err-val) + (cons function-or-file err-val) + (list function-or-file err-val)))))) data)) ;;;###autoload (defun batch-native-compile () - "Ultra cheap impersonation of `batch-byte-compile'." + "Run `native-compile' on remaining command-line arguments. +Ultra cheap impersonation of `batch-byte-compile'." (mapc #'native-compile command-line-args-left)) ;;;###autoload @@ -2169,23 +2182,25 @@ Always generate elc files too and handle native compiler expected errors." (rename-file tempfile target-file t)))))) ;;;###autoload -(defun native-compile-async (input &optional jobs recursively) - "Compile INPUT asynchronously. -INPUT can be either a list of files a folder or a file. -JOBS specifies the number of jobs (commands) to run simultaneously (1 default). -Follow folders RECURSIVELY if non nil." - (let ((jobs (or jobs 1)) - (files (if (listp input) - input - (if (file-directory-p input) - (if recursively - (directory-files-recursively input "\\.el$") - (directory-files input t "\\.el$")) - (if (file-exists-p input) - (list input) - (signal 'native-compiler-error - "input not a file nor directory")))))) - (setf comp-src-pool (nconc files comp-src-pool)) +(cl-defun native-compile-async (paths &optional (jobs 1) recursively) + "Compile PATHS asynchronously. +PATHS is one path or a list of paths to files or directories. +JOBS specifies the number of jobs (commands) to run +simultaneously (1 default). If RECURSIVELY, recurse into +subdirectories of given directories." + (unless (listp paths) + (setf paths (list paths))) + (let (files) + (dolist (path paths) + (cond ((file-directory-p path) + (dolist (file (if recursively + (directory-files-recursively path (rx ".el" eos)) + (directory-files path t (rx ".el" eos)))) + (push file files))) + ((file-exists-p path) (push path files)) + (t (signal 'native-compiler-error + (list "Path not a file nor directory" path))))) + (setf comp-files-queue (nconc files comp-files-queue)) (cl-loop repeat jobs do (comp-start-async-worker)) (message "Compilation started."))) -- cgit v1.2.3 From 63af801ed34c8dc59fb13c9e058c49203a1ae55d Mon Sep 17 00:00:00 2001 From: Ashish SHUKLA Date: Fri, 3 Apr 2020 02:07:05 +0530 Subject: configure.ac: switch to POSIX sh behaviour --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 393a53d7633..e8f46010910 100644 --- a/configure.ac +++ b/configure.ac @@ -3729,7 +3729,7 @@ if test "${with_nativecomp}" != "no"; then AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes)) if test "${HAVE_NATIVE_COMP}" = "yes"; then LIBGCCJIT_LIB="-lgccjit -ldl" - COMP_OBJ+=comp.o + COMP_OBJ="comp.o" AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) else AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. -- cgit v1.2.3 From 766f4b96ee148adf8f4bbbf5fa4f1c47555d46de Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Mon, 4 May 2020 21:01:48 +0100 Subject: * configure.ac: Add a better libgccjit test plus some morw err message * configure.ac (libgccjit_smoke_test, libgccjit_not_found) (libgccjit_broken): New functions. --- configure.ac | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 9 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c4d19e0e287..af12f20500d 100644 --- a/configure.ac +++ b/configure.ac @@ -3729,22 +3729,70 @@ emacs_major_version="${PACKAGE_VERSION%%.*}" AC_SUBST(emacs_major_version) ### Emacs Lisp native compiler support + +AC_DEFUN([libgccjit_smoke_test], [ + AC_LANG_SOURCE( + [[#include + #include + #include + int + main (int argc, char **argv) + { + gcc_jit_context *ctxt; + gcc_jit_result *result; + ctxt = gcc_jit_context_acquire (); + if (!ctxt) + exit (1); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, "foo", 0, NULL, 0); + gcc_jit_block *block = gcc_jit_function_new_block (func, "foo"); + gcc_jit_block_end_with_return ( + block, + NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)); + result = gcc_jit_context_compile (ctxt); + if (!result) + exit (1); + typedef int (*fn_type) (void); + fn_type foo = + (fn_type)gcc_jit_result_get_code (result, "foo"); + if (!foo) + exit (1); + if (foo () != 1) + exit (1); + gcc_jit_context_release (ctxt); + gcc_jit_result_release (result); + return 0; + }]])]) + +AC_DEFUN([libgccjit_not_found], [ + AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. +If you are sure you want Emacs compiled without elisp native compiler, pass + --without-nativecomp +to configure.])]) + +AC_DEFUN([libgccjit_broken], [ + AC_MSG_ERROR([Installed libgccjit has failed passing the smoke test. +Please report the issue to your distribution. +Here instructions on how to compile from source: https://gcc.gnu.org/wiki/JIT.])]) + HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then - AC_CHECK_HEADER(libgccjit.h, - AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, HAVE_NATIVE_COMP=yes)) - if test "${HAVE_NATIVE_COMP}" = "yes"; then + emacs_save_LDFLAGS=$LDFLAGS + LDFLAGS="-lgccjit -ldl" + AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken], + [AC_LINK_IFELSE([libgccjit_smoke_test], [], [libgccjit_not_found])]) + LDFLAGS=$emacs_save_LDFLAGS + HAVE_NATIVE_COMP=yes LIBGCCJIT_LIB="-lgccjit -ldl" COMP_OBJ="comp.o" AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) - else - AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. -If you are sure you want Emacs compiled without elisp native compiler, pass - --without-nativecomp -to configure.]) - fi fi if test "${HAVE_NATIVE_COMP}" = yes && test "${HAVE_PDUMPER}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) -- cgit v1.2.3 From a261db171166246eaee523cd3b3687b39bce4dca Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Tue, 5 May 2020 08:47:51 +0100 Subject: * configure.ac: Better messaging when libgccjit fails smoke test * configure.ac: Fix libgccjit test LDFLAGS plus better messaging in case of its fail. --- configure.ac | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index af12f20500d..62fb274d3bb 100644 --- a/configure.ac +++ b/configure.ac @@ -3777,15 +3777,18 @@ to configure.])]) AC_DEFUN([libgccjit_broken], [ AC_MSG_ERROR([Installed libgccjit has failed passing the smoke test. +You can verify it yourself compiling: +. Please report the issue to your distribution. -Here instructions on how to compile from source: https://gcc.gnu.org/wiki/JIT.])]) +Here instructions on how to compile from source: +.])]) HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then emacs_save_LDFLAGS=$LDFLAGS - LDFLAGS="-lgccjit -ldl" + LDFLAGS="-lgccjit" AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken], [AC_LINK_IFELSE([libgccjit_smoke_test], [], [libgccjit_not_found])]) LDFLAGS=$emacs_save_LDFLAGS -- cgit v1.2.3 From 6d25de46f77909f3adb108786052995151082c56 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Tue, 5 May 2020 15:50:30 +0100 Subject: * configure.ac: Fix var usage + better messaging. --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 62fb274d3bb..23b94cf6ca1 100644 --- a/configure.ac +++ b/configure.ac @@ -3780,18 +3780,18 @@ AC_DEFUN([libgccjit_broken], [ You can verify it yourself compiling: . Please report the issue to your distribution. -Here instructions on how to compile from source: +Here instructions on how to compile and install libgccjit from source: .])]) HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= COMP_OBJ= if test "${with_nativecomp}" != "no"; then - emacs_save_LDFLAGS=$LDFLAGS - LDFLAGS="-lgccjit" + emacs_save_LIBS=$LIBS + LIBS="-lgccjit" AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken], [AC_LINK_IFELSE([libgccjit_smoke_test], [], [libgccjit_not_found])]) - LDFLAGS=$emacs_save_LDFLAGS + LIBS=$emacs_save_LIBS HAVE_NATIVE_COMP=yes LIBGCCJIT_LIB="-lgccjit -ldl" COMP_OBJ="comp.o" -- cgit v1.2.3 From 483cdf7a7942c91f6691953c9fe4618194dd175b Mon Sep 17 00:00:00 2001 From: Nicolás Bértolo Date: Mon, 11 May 2020 20:43:06 -0300 Subject: Load libgccjit dynamically in Windows. * configure.ac: don't add linker flags if compiling on Windows. Compile dynlib.c if modules or native compilation are enabled. Always compile comp.c * lisp/term/w32-win.el: Map 'gccjit to "libgccjit.dll" in `dynamic-library-alist`. * src/Makefile.in: Update comments. Update to handle changes in configure.ac. * src/comp.c: Add declarations of used libgccjit functions using DEF_DLL_FN. Add calls to load_gccjit_if_necessary() where necessary. Add `native-comp-available-p` * src/comp.h: Remove Fnative_elisp_load. Add syms_of_comp(). * src/emacs.c (main): Always call syms_of_comp() * src/w32.c (globals_of_w32): Clear Vlibrary_cache when starting because the libraries loaded when dumping will not be loaded when starting. * src/w32fns.c: Add Qgccjit symbol. --- configure.ac | 19 ++- lisp/term/w32-win.el | 3 +- src/Makefile.in | 9 +- src/comp.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/comp.h | 6 +- src/emacs.c | 2 - src/w32.c | 4 + src/w32fns.c | 1 + 8 files changed, 398 insertions(+), 20 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 23b94cf6ca1..ea0144f4048 100644 --- a/configure.ac +++ b/configure.ac @@ -3666,6 +3666,7 @@ AC_SUBST(LIBZ) LIBMODULES= HAVE_MODULES=no MODULES_OBJ= +NEED_DYNLIB=no case $opsys in cygwin|mingw32) MODULES_SUFFIX=".dll" ;; darwin) MODULES_SUFFIX=".dylib" ;; @@ -3701,7 +3702,8 @@ if test "${with_modules}" != "no"; then fi if test "${HAVE_MODULES}" = yes; then - MODULES_OBJ="dynlib.o emacs-module.o" + MODULES_OBJ="emacs-module.o" + NEED_DYNLIB=yes AC_DEFINE(HAVE_MODULES, 1, [Define to 1 if dynamic modules are enabled]) AC_DEFINE_UNQUOTED(MODULES_SUFFIX, "$MODULES_SUFFIX", [System extension for dynamic libraries]) @@ -3785,7 +3787,6 @@ Here instructions on how to compile and install libgccjit from source: HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= -COMP_OBJ= if test "${with_nativecomp}" != "no"; then emacs_save_LIBS=$LIBS LIBS="-lgccjit" @@ -3793,8 +3794,11 @@ if test "${with_nativecomp}" != "no"; then [AC_LINK_IFELSE([libgccjit_smoke_test], [], [libgccjit_not_found])]) LIBS=$emacs_save_LIBS HAVE_NATIVE_COMP=yes - LIBGCCJIT_LIB="-lgccjit -ldl" - COMP_OBJ="comp.o" + # mingw32 loads the library dynamically. + if test "${opsys}" != "mingw32"; then + LIBGCCJIT_LIB="-lgccjit -ldl" + fi + NEED_DYNLIB=yes AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) fi if test "${HAVE_NATIVE_COMP}" = yes && test "${HAVE_PDUMPER}" = no; then @@ -3804,7 +3808,12 @@ AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) AC_SUBST(HAVE_NATIVE_COMP) AC_SUBST(LIBGCCJIT_LIB) -AC_SUBST(COMP_OBJ) + +DYNLIB_OBJ= +if test "${NEED_DYNLIB}" = yes; then + DYNLIB_OBJ="dynlib.o" +fi +AC_SUBST(DYNLIB_OBJ) ### Use -lpng if available, unless '--with-png=no'. HAVE_PNG=no diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index 5901e0295e1..6b9716ca307 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -289,7 +289,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") '(libxml2 "libxml2-2.dll" "libxml2.dll") '(zlib "zlib1.dll" "libz-1.dll") '(lcms2 "liblcms2-2.dll") - '(json "libjansson-4.dll"))) + '(json "libjansson-4.dll") + '(gccjit "libgccjit.dll"))) ;;; multi-tty support (defvar w32-initialized nil diff --git a/src/Makefile.in b/src/Makefile.in index 63f909ae147..85709184da1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -241,7 +241,7 @@ LIBZ = @LIBZ@ ## system-specific libs for dynamic modules, else empty LIBMODULES = @LIBMODULES@ -## dynlib.o emacs-module.o if modules enabled, else empty +## emacs-module.o if modules enabled, else empty MODULES_OBJ = @MODULES_OBJ@ XRANDR_LIBS = @XRANDR_LIBS@ @@ -327,8 +327,9 @@ GMP_LIB = @GMP_LIB@ GMP_OBJ = @GMP_OBJ@ LIBGCCJIT = @LIBGCCJIT_LIB@ -## dynlib.o comp.o if native compiler is enabled, otherwise empty. -COMP_OBJ = @COMP_OBJ@ + +## dynlib.o if necessary, else empty +DYNLIB_OBJ = @DYNLIB_OBJ@ RUN_TEMACS = ./temacs @@ -418,7 +419,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \ alloc.o pdumper.o data.o doc.o editfns.o callint.o \ eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \ - syntax.o $(UNEXEC_OBJ) bytecode.o $(COMP_OBJ) \ + syntax.o $(UNEXEC_OBJ) bytecode.o comp.o $(DYNLIB_OBJ) \ process.o gnutls.o callproc.o \ region-cache.o sound.o timefns.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \ diff --git a/src/comp.c b/src/comp.c index 994bd7db934..d72fa927460 100644 --- a/src/comp.c +++ b/src/comp.c @@ -20,6 +20,8 @@ along with GNU Emacs. If not, see . */ #include +#include "lisp.h" + #ifdef HAVE_NATIVE_COMP #include @@ -28,7 +30,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include "lisp.h" #include "puresize.h" #include "window.h" #include "dynlib.h" @@ -36,6 +37,347 @@ along with GNU Emacs. If not, see . */ #include "blockinput.h" #include "sha512.h" + +/********************************/ +/* Dynamic loading of libgccjit */ +/********************************/ + +#ifdef WINDOWSNT +# include "w32common.h" + +#undef gcc_jit_block_add_assignment +#undef gcc_jit_block_add_comment +#undef gcc_jit_block_add_eval +#undef gcc_jit_block_end_with_conditional +#undef gcc_jit_block_end_with_jump +#undef gcc_jit_block_end_with_return +#undef gcc_jit_block_end_with_void_return +#undef gcc_jit_context_acquire +#undef gcc_jit_context_compile_to_file +#undef gcc_jit_context_dump_reproducer_to_file +#undef gcc_jit_context_dump_to_file +#undef gcc_jit_context_get_builtin_function +#undef gcc_jit_context_get_first_error +#undef gcc_jit_context_get_int_type +#undef gcc_jit_context_get_type +#undef gcc_jit_context_new_array_access +#undef gcc_jit_context_new_array_type +#undef gcc_jit_context_new_binary_op +#undef gcc_jit_context_new_call +#undef gcc_jit_context_new_call_through_ptr +#undef gcc_jit_context_new_comparison +#undef gcc_jit_context_new_field +#undef gcc_jit_context_new_function +#undef gcc_jit_context_new_function_ptr_type +#undef gcc_jit_context_new_global +#undef gcc_jit_context_new_opaque_struct +#undef gcc_jit_context_new_param +#undef gcc_jit_context_new_rvalue_from_int +#undef gcc_jit_context_new_rvalue_from_long +#undef gcc_jit_context_new_rvalue_from_ptr +#undef gcc_jit_context_new_struct_type +#undef gcc_jit_context_new_unary_op +#undef gcc_jit_context_new_union_type +#undef gcc_jit_context_release +#undef gcc_jit_context_set_bool_option +#undef gcc_jit_context_set_int_option +#undef gcc_jit_context_set_logfile +#undef gcc_jit_function_get_param +#undef gcc_jit_function_new_block +#undef gcc_jit_function_new_local +#undef gcc_jit_lvalue_access_field +#undef gcc_jit_lvalue_as_rvalue +#undef gcc_jit_lvalue_get_address +#undef gcc_jit_param_as_lvalue +#undef gcc_jit_param_as_rvalue +#undef gcc_jit_rvalue_access_field +#undef gcc_jit_rvalue_dereference +#undef gcc_jit_rvalue_dereference_field +#undef gcc_jit_rvalue_get_type +#undef gcc_jit_struct_as_type +#undef gcc_jit_struct_set_fields +#undef gcc_jit_type_get_pointer + +/* In alphabetical order */ +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_rvalue_from_int, + (gcc_jit_context *ctxt, gcc_jit_type *numeric_type, int value)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_lvalue_as_rvalue, + (gcc_jit_lvalue *lvalue)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_rvalue_access_field, + (gcc_jit_rvalue *struct_or_union, gcc_jit_location *loc, + gcc_jit_field *field)); +DEF_DLL_FN (void, gcc_jit_block_add_comment, + (gcc_jit_block *block, gcc_jit_location *loc, const char *text)); +DEF_DLL_FN (void, gcc_jit_context_release, (gcc_jit_context *ctxt)); +DEF_DLL_FN (const char *, gcc_jit_context_get_first_error, + (gcc_jit_context *ctxt)); +DEF_DLL_FN (gcc_jit_block *, gcc_jit_function_new_block, + (gcc_jit_function *func, const char *name)); +DEF_DLL_FN (gcc_jit_context *, gcc_jit_context_acquire, (void)); +DEF_DLL_FN (gcc_jit_field *, gcc_jit_context_new_field, + (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *type, + const char *name)); +DEF_DLL_FN (gcc_jit_function *, gcc_jit_context_get_builtin_function, + (gcc_jit_context *ctxt, const char *name)); +DEF_DLL_FN (gcc_jit_function *, gcc_jit_context_new_function, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + enum gcc_jit_function_kind kind, gcc_jit_type *return_type, + const char *name, int num_params, gcc_jit_param **params, + int is_variadic)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_context_new_array_access, + (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *ptr, + gcc_jit_rvalue *index)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_context_new_global, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + enum gcc_jit_global_kind kind, gcc_jit_type *type, + const char *name)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_function_new_local, + (gcc_jit_function *func, gcc_jit_location *loc, gcc_jit_type *type, + const char *name)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_lvalue_access_field, + (gcc_jit_lvalue *struct_or_union, gcc_jit_location *loc, + gcc_jit_field *field)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_param_as_lvalue, (gcc_jit_param *param)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_rvalue_dereference, + (gcc_jit_rvalue *rvalue, gcc_jit_location *loc)); +DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_rvalue_dereference_field, + (gcc_jit_rvalue *ptr, gcc_jit_location *loc, gcc_jit_field *field)); +DEF_DLL_FN (gcc_jit_param *, gcc_jit_context_new_param, + (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *type, + const char *name)); +DEF_DLL_FN (gcc_jit_param *, gcc_jit_function_get_param, + (gcc_jit_function *func, int index)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_binary_op, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + enum gcc_jit_binary_op op, gcc_jit_type *result_type, + gcc_jit_rvalue *a, gcc_jit_rvalue *b)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + gcc_jit_function *func, int numargs , gcc_jit_rvalue **args)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call_through_ptr, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + gcc_jit_rvalue *fn_ptr, int numargs, gcc_jit_rvalue **args)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_comparison, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + enum gcc_jit_comparison op, gcc_jit_rvalue *a, gcc_jit_rvalue *b)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_rvalue_from_long, + (gcc_jit_context *ctxt, gcc_jit_type *numeric_type, long value)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_rvalue_from_ptr, + (gcc_jit_context *ctxt, gcc_jit_type *pointer_type, void *value)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_unary_op, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + enum gcc_jit_unary_op op, gcc_jit_type *result_type, + gcc_jit_rvalue *rvalue)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_lvalue_get_address, + (gcc_jit_lvalue *lvalue, gcc_jit_location *loc)); +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_param_as_rvalue, (gcc_jit_param *param)); +DEF_DLL_FN (gcc_jit_struct *, gcc_jit_context_new_opaque_struct, + (gcc_jit_context *ctxt, gcc_jit_location *loc, const char *name)); +DEF_DLL_FN (gcc_jit_struct *, gcc_jit_context_new_struct_type, + (gcc_jit_context *ctxt, gcc_jit_location *loc, const char *name, + int num_fields, gcc_jit_field **fields)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_context_get_int_type, + (gcc_jit_context *ctxt, int num_bytes, int is_signed)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_context_get_type, + (gcc_jit_context *ctxt, enum gcc_jit_types type_)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_context_new_array_type, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + gcc_jit_type *element_type, int num_elements)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_context_new_function_ptr_type, + (gcc_jit_context *ctxt, gcc_jit_location *loc, + gcc_jit_type *return_type, int num_params, + gcc_jit_type **param_types, int is_variadic)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_context_new_union_type, + (gcc_jit_context *ctxt, gcc_jit_location *loc, const char *name, + int num_fields, gcc_jit_field **fields)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_rvalue_get_type, (gcc_jit_rvalue *rvalue)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_struct_as_type, + (gcc_jit_struct *struct_type)); +DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_pointer, (gcc_jit_type *type)); +DEF_DLL_FN (void, gcc_jit_block_add_assignment, + (gcc_jit_block *block, gcc_jit_location *loc, gcc_jit_lvalue *lvalue, + gcc_jit_rvalue *rvalue)); +DEF_DLL_FN (void, gcc_jit_block_add_eval, + (gcc_jit_block *block, gcc_jit_location *loc, + gcc_jit_rvalue *rvalue)); +DEF_DLL_FN (void, gcc_jit_block_end_with_conditional, + (gcc_jit_block *block, gcc_jit_location *loc, + gcc_jit_rvalue *boolval, gcc_jit_block *on_true, + gcc_jit_block *on_false)); +DEF_DLL_FN (void, gcc_jit_block_end_with_jump, + (gcc_jit_block *block, gcc_jit_location *loc, + gcc_jit_block *target)); +DEF_DLL_FN (void, gcc_jit_block_end_with_return, + (gcc_jit_block *block, gcc_jit_location *loc, + gcc_jit_rvalue *rvalue)); +DEF_DLL_FN (void, gcc_jit_block_end_with_void_return, + (gcc_jit_block *block, gcc_jit_location *loc)); +DEF_DLL_FN (void, gcc_jit_context_compile_to_file, + (gcc_jit_context *ctxt, enum gcc_jit_output_kind output_kind, + const char *output_path)); +DEF_DLL_FN (void, gcc_jit_context_dump_reproducer_to_file, + (gcc_jit_context *ctxt, const char *path)); +DEF_DLL_FN (void, gcc_jit_context_dump_to_file, + (gcc_jit_context *ctxt, const char *path, int update_locations)); +DEF_DLL_FN (void, gcc_jit_context_set_bool_option, + (gcc_jit_context *ctxt, enum gcc_jit_bool_option opt, int value)); +DEF_DLL_FN (void, gcc_jit_context_set_int_option, + (gcc_jit_context *ctxt, enum gcc_jit_int_option opt, int value)); +DEF_DLL_FN (void, gcc_jit_context_set_logfile, + (gcc_jit_context *ctxt, FILE *logfile, int flags, int verbosity)); +DEF_DLL_FN (void, gcc_jit_struct_set_fields, + (gcc_jit_struct *struct_type, gcc_jit_location *loc, int num_fields, + gcc_jit_field **fields)); + +static bool +init_gccjit_functions (void) +{ + HMODULE library; + + if (!(library = w32_delayed_load (Qgccjit))) + { + return false; + } + + /* In alphabetical order */ + LOAD_DLL_FN(library, gcc_jit_block_add_assignment); + LOAD_DLL_FN(library, gcc_jit_block_add_comment); + LOAD_DLL_FN(library, gcc_jit_block_add_eval); + LOAD_DLL_FN(library, gcc_jit_block_end_with_conditional); + LOAD_DLL_FN(library, gcc_jit_block_end_with_jump); + LOAD_DLL_FN(library, gcc_jit_block_end_with_return); + LOAD_DLL_FN(library, gcc_jit_block_end_with_void_return); + LOAD_DLL_FN(library, gcc_jit_context_acquire); + LOAD_DLL_FN(library, gcc_jit_context_compile_to_file); + LOAD_DLL_FN(library, gcc_jit_context_dump_reproducer_to_file); + LOAD_DLL_FN(library, gcc_jit_context_dump_to_file); + LOAD_DLL_FN(library, gcc_jit_context_get_builtin_function); + LOAD_DLL_FN(library, gcc_jit_context_get_first_error); + LOAD_DLL_FN(library, gcc_jit_context_get_int_type); + LOAD_DLL_FN(library, gcc_jit_context_get_type); + LOAD_DLL_FN(library, gcc_jit_context_new_array_access); + LOAD_DLL_FN(library, gcc_jit_context_new_array_type); + LOAD_DLL_FN(library, gcc_jit_context_new_binary_op); + LOAD_DLL_FN(library, gcc_jit_context_new_call); + LOAD_DLL_FN(library, gcc_jit_context_new_call_through_ptr); + LOAD_DLL_FN(library, gcc_jit_context_new_comparison); + LOAD_DLL_FN(library, gcc_jit_context_new_field); + LOAD_DLL_FN(library, gcc_jit_context_new_function); + LOAD_DLL_FN(library, gcc_jit_context_new_function_ptr_type); + LOAD_DLL_FN(library, gcc_jit_context_new_global); + LOAD_DLL_FN(library, gcc_jit_context_new_opaque_struct); + LOAD_DLL_FN(library, gcc_jit_context_new_param); + LOAD_DLL_FN(library, gcc_jit_context_new_rvalue_from_int); + LOAD_DLL_FN(library, gcc_jit_context_new_rvalue_from_long); + LOAD_DLL_FN(library, gcc_jit_context_new_rvalue_from_ptr); + LOAD_DLL_FN(library, gcc_jit_context_new_struct_type); + LOAD_DLL_FN(library, gcc_jit_context_new_unary_op); + LOAD_DLL_FN(library, gcc_jit_context_new_union_type); + LOAD_DLL_FN(library, gcc_jit_context_release); + LOAD_DLL_FN(library, gcc_jit_context_set_bool_option); + LOAD_DLL_FN(library, gcc_jit_context_set_int_option); + LOAD_DLL_FN(library, gcc_jit_context_set_logfile); + LOAD_DLL_FN(library, gcc_jit_function_get_param); + LOAD_DLL_FN(library, gcc_jit_function_new_block); + LOAD_DLL_FN(library, gcc_jit_function_new_local); + LOAD_DLL_FN(library, gcc_jit_lvalue_access_field); + LOAD_DLL_FN(library, gcc_jit_lvalue_as_rvalue); + LOAD_DLL_FN(library, gcc_jit_lvalue_get_address); + LOAD_DLL_FN(library, gcc_jit_param_as_lvalue); + LOAD_DLL_FN(library, gcc_jit_param_as_rvalue); + LOAD_DLL_FN(library, gcc_jit_rvalue_access_field); + LOAD_DLL_FN(library, gcc_jit_rvalue_dereference); + LOAD_DLL_FN(library, gcc_jit_rvalue_dereference_field); + LOAD_DLL_FN(library, gcc_jit_rvalue_get_type); + LOAD_DLL_FN(library, gcc_jit_struct_as_type); + LOAD_DLL_FN(library, gcc_jit_struct_set_fields); + LOAD_DLL_FN(library, gcc_jit_type_get_pointer); + + return true; +} + +/* In alphabetical order */ +#define gcc_jit_block_add_assignment fn_gcc_jit_block_add_assignment +#define gcc_jit_block_add_comment fn_gcc_jit_block_add_comment +#define gcc_jit_block_add_eval fn_gcc_jit_block_add_eval +#define gcc_jit_block_end_with_conditional fn_gcc_jit_block_end_with_conditional +#define gcc_jit_block_end_with_jump fn_gcc_jit_block_end_with_jump +#define gcc_jit_block_end_with_return fn_gcc_jit_block_end_with_return +#define gcc_jit_block_end_with_void_return fn_gcc_jit_block_end_with_void_return +#define gcc_jit_context_acquire fn_gcc_jit_context_acquire +#define gcc_jit_context_compile_to_file fn_gcc_jit_context_compile_to_file +#define gcc_jit_context_dump_reproducer_to_file fn_gcc_jit_context_dump_reproducer_to_file +#define gcc_jit_context_dump_to_file fn_gcc_jit_context_dump_to_file +#define gcc_jit_context_get_builtin_function fn_gcc_jit_context_get_builtin_function +#define gcc_jit_context_get_first_error fn_gcc_jit_context_get_first_error +#define gcc_jit_context_get_int_type fn_gcc_jit_context_get_int_type +#define gcc_jit_context_get_type fn_gcc_jit_context_get_type +#define gcc_jit_context_new_array_access fn_gcc_jit_context_new_array_access +#define gcc_jit_context_new_array_type fn_gcc_jit_context_new_array_type +#define gcc_jit_context_new_binary_op fn_gcc_jit_context_new_binary_op +#define gcc_jit_context_new_call fn_gcc_jit_context_new_call +#define gcc_jit_context_new_call_through_ptr fn_gcc_jit_context_new_call_through_ptr +#define gcc_jit_context_new_comparison fn_gcc_jit_context_new_comparison +#define gcc_jit_context_new_field fn_gcc_jit_context_new_field +#define gcc_jit_context_new_function fn_gcc_jit_context_new_function +#define gcc_jit_context_new_function_ptr_type fn_gcc_jit_context_new_function_ptr_type +#define gcc_jit_context_new_global fn_gcc_jit_context_new_global +#define gcc_jit_context_new_opaque_struct fn_gcc_jit_context_new_opaque_struct +#define gcc_jit_context_new_param fn_gcc_jit_context_new_param +#define gcc_jit_context_new_rvalue_from_int fn_gcc_jit_context_new_rvalue_from_int +#define gcc_jit_context_new_rvalue_from_long fn_gcc_jit_context_new_rvalue_from_long +#define gcc_jit_context_new_rvalue_from_ptr fn_gcc_jit_context_new_rvalue_from_ptr +#define gcc_jit_context_new_struct_type fn_gcc_jit_context_new_struct_type +#define gcc_jit_context_new_unary_op fn_gcc_jit_context_new_unary_op +#define gcc_jit_context_new_union_type fn_gcc_jit_context_new_union_type +#define gcc_jit_context_release fn_gcc_jit_context_release +#define gcc_jit_context_set_bool_option fn_gcc_jit_context_set_bool_option +#define gcc_jit_context_set_int_option fn_gcc_jit_context_set_int_option +#define gcc_jit_context_set_logfile fn_gcc_jit_context_set_logfile +#define gcc_jit_function_get_param fn_gcc_jit_function_get_param +#define gcc_jit_function_new_block fn_gcc_jit_function_new_block +#define gcc_jit_function_new_local fn_gcc_jit_function_new_local +#define gcc_jit_lvalue_access_field fn_gcc_jit_lvalue_access_field +#define gcc_jit_lvalue_as_rvalue fn_gcc_jit_lvalue_as_rvalue +#define gcc_jit_lvalue_get_address fn_gcc_jit_lvalue_get_address +#define gcc_jit_param_as_lvalue fn_gcc_jit_param_as_lvalue +#define gcc_jit_param_as_rvalue fn_gcc_jit_param_as_rvalue +#define gcc_jit_rvalue_access_field fn_gcc_jit_rvalue_access_field +#define gcc_jit_rvalue_dereference fn_gcc_jit_rvalue_dereference +#define gcc_jit_rvalue_dereference_field fn_gcc_jit_rvalue_dereference_field +#define gcc_jit_rvalue_get_type fn_gcc_jit_rvalue_get_type +#define gcc_jit_struct_as_type fn_gcc_jit_struct_as_type +#define gcc_jit_struct_set_fields fn_gcc_jit_struct_set_fields +#define gcc_jit_type_get_pointer fn_gcc_jit_type_get_pointer + +#endif + +static bool +load_gccjit_if_necessary (bool mandatory) +{ +#ifdef WINDOWSNT + static bool tried_to_initialize_once; + static bool gccjit_initialized; + + if (!tried_to_initialize_once) + { + tried_to_initialize_once = true; + Lisp_Object status; + gccjit_initialized = init_gccjit_functions (); + status = gccjit_initialized ? Qt : Qnil; + Vlibrary_cache = Fcons (Fcons (Qgccjit, status), Vlibrary_cache); + } + + if (mandatory && !gccjit_initialized) + xsignal1(Qnative_compiler_error, build_string("libgccjit not found")); + + return gccjit_initialized; +#else + return true; +#endif +} + + /* C symbols emitted for the load relocation mechanism. */ #define CURRENT_THREAD_RELOC_SYM "current_thread_reloc" #define PURE_RELOC_SYM "pure_reloc" @@ -3295,6 +3637,8 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt, doc: /* Initialize the native compiler context. Return t on success. */) (void) { + load_gccjit_if_necessary(true); + if (comp.ctxt) { xsignal1 (Qnative_ice, @@ -3441,6 +3785,8 @@ DEFUN ("comp--release-ctxt", Fcomp__release_ctxt, Scomp__release_ctxt, doc: /* Release the native compiler context. */) (void) { + load_gccjit_if_necessary(true); + if (comp.ctxt) gcc_jit_context_release (comp.ctxt); @@ -3457,6 +3803,8 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, doc: /* Compile as native code the current context to file. */) (Lisp_Object base_name) { + load_gccjit_if_necessary(true); + CHECK_STRING (base_name); gcc_jit_context_set_int_option (comp.ctxt, @@ -3626,6 +3974,9 @@ maybe_defer_native_compilation (Lisp_Object function_name, fflush (f); } #endif + if (!load_gccjit_if_necessary(false)) + return; + if (!comp_deferred_compilation || noninteractive || !NILP (Vpurify_flag) @@ -3975,10 +4326,26 @@ DEFUN ("native-elisp-load", Fnative_elisp_load, Snative_elisp_load, 1, 2, 0, return Qt; } +#endif /* HAVE_NATIVE_COMP */ + +DEFUN ("native-comp-available-p", Fnative_comp_available_p, + Snative_comp_available_p, 0, 0, 0, + doc: /* Returns t if native compilation of Lisp files is available in +this instance of Emacs. */) + (void) +{ +#ifdef HAVE_NATIVE_COMP + return load_gccjit_if_necessary(false) ? Qt : Qnil; +#else + return Qnil; +#endif +} + void syms_of_comp (void) { +#ifdef HAVE_NATIVE_COMP /* Compiler control customizes. */ DEFVAR_BOOL ("comp-deferred-compilation", comp_deferred_compilation, doc: /* If t compile asyncronously every .elc file loaded. */); @@ -4122,6 +4489,7 @@ syms_of_comp (void) doc: /* Hash table symbol-name -> function-value. For internal use during */); Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq); -} +#endif -#endif /* HAVE_NATIVE_COMP */ + defsubr (&Snative_comp_available_p); +} diff --git a/src/comp.h b/src/comp.h index b03a8055142..36e7cdf4413 100644 --- a/src/comp.h +++ b/src/comp.h @@ -90,11 +90,7 @@ maybe_defer_native_compilation (Lisp_Object function_name, Lisp_Object definition) {} -static inline Lisp_Object -Fnative_elisp_load (Lisp_Object file, Lisp_Object late_load) -{ - eassume (false); -} +extern void syms_of_comp (void); #endif diff --git a/src/emacs.c b/src/emacs.c index 2c908257422..e75cb588349 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1606,10 +1606,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem init_json (); #endif -#ifdef HAVE_NATIVE_COMP if (!initialized) syms_of_comp (); -#endif no_loadup = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args); diff --git a/src/w32.c b/src/w32.c index 0f69e652a57..d01a45029d8 100644 --- a/src/w32.c +++ b/src/w32.c @@ -10586,6 +10586,10 @@ globals_of_w32 (void) #endif w32_crypto_hprov = (HCRYPTPROV)0; + + /* We need to forget about libraries that were loaded during the + dumping process (e.g. libgccjit) */ + Vlibrary_cache = Qnil; } /* For make-serial-process */ diff --git a/src/w32fns.c b/src/w32fns.c index e595b0285a7..eeb73489dd5 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -10462,6 +10462,7 @@ syms_of_w32fns (void) DEFSYM (Qzlib, "zlib"); DEFSYM (Qlcms2, "lcms2"); DEFSYM (Qjson, "json"); + DEFSYM (Qgccjit, "gccjit"); Fput (Qundefined_color, Qerror_conditions, pure_list (Qundefined_color, Qerror)); -- cgit v1.2.3 From 79ed90380547128b9919d407901a886fed0306b7 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 26 Jul 2020 09:38:14 +0200 Subject: * Add NATIVE_COMP to `system-configuration-features' * configure.ac (emacs_config_features): Add NATIVE_COMP --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 2277f36e491..cb059303255 100644 --- a/configure.ac +++ b/configure.ac @@ -5725,7 +5725,7 @@ emacs_config_features= for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO IMAGEMAGICK SOUND GPM DBUS \ GCONF GSETTINGS GLIB NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT \ LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT OLDXMENU X11 XDBE XIM \ - NS MODULES THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER UNEXEC LCMS2 GMP; do + NS MODULES NATIVE_COMP THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER UNEXEC LCMS2 GMP; do case $opt in PDUMPER) val=${with_pdumper} ;; -- cgit v1.2.3 From 5f5d664c734414597c1c7d9981b1ceb9ff69c5b1 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sat, 22 Aug 2020 11:11:21 +0200 Subject: Rework eln hash filename strategy Generate eln filename hashing also the source file content in the form: /absolute/path/filename.el + content -> eln-cache/filename-path_hash-content_hash.eln * src/lread.c (maybe_swap_for_eln): Always call Fcomp_el_to_eln_filename on an existing source file. * src/comp.c (md5.h, sysstdio.h, zlib.h): New include. (comp_hash_string): Use md5 instead of sha512. (MD5_BLOCKSIZE): New macro. (accumulate_and_process_md5, final_process_md5, md5_gz_stream) (comp_hash_source_file): New functions. (Fcomp_el_to_eln_filename): Rework for hasing using also source file content. * src/lread.c (maybe_swap_for_eln): Rename el_name -> src_name as this can be also a have .el.gz extention. --- configure.ac | 9 ++-- lib/Makefile.in | 6 +++ src/comp.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/lread.c | 13 +++-- 4 files changed, 167 insertions(+), 22 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0582b2f61c5..cdc18eab19e 100644 --- a/configure.ac +++ b/configure.ac @@ -3787,6 +3787,12 @@ Here instructions on how to compile and install libgccjit from source: HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= if test "${with_nativecomp}" != "no"; then + if test "${HAVE_PDUMPER}" = no; then + AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) + fi + if test "${HAVE_ZLIB}" = no; then + AC_MSG_ERROR(['--with-nativecomp' requires zlib]) + fi emacs_save_LIBS=$LIBS LIBS="-lgccjit" AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken], @@ -3800,9 +3806,6 @@ if test "${with_nativecomp}" != "no"; then NEED_DYNLIB=yes AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) fi -if test "${HAVE_NATIVE_COMP}" = yes && test "${HAVE_PDUMPER}" = no; then - AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) -fi AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) AC_SUBST(HAVE_NATIVE_COMP) diff --git a/lib/Makefile.in b/lib/Makefile.in index 06d8e56421b..8d97d3bcfbb 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -50,12 +50,18 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = +HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@ + ALL_CFLAGS= \ $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) $(DEPFLAGS) \ $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) $(PROFILING_CFLAGS) $(CFLAGS) \ -I. -I../src -I$(srcdir) -I$(srcdir)/../src \ $(if $(patsubst e-%,,$(notdir $<)),,-Demacs) +ifeq ($(HAVE_NATIVE_COMP),yes) +ALL_CFLAGS += -DGL_COMPILE_CRYPTO_STREAM +endif + SYSTEM_TYPE = @SYSTEM_TYPE@ ifeq ($(SYSTEM_TYPE),windows-nt) include $(srcdir)/../nt/gnulib-cfg.mk diff --git a/src/comp.c b/src/comp.c index ff73245b8de..5f1257f6be1 100644 --- a/src/comp.c +++ b/src/comp.c @@ -36,7 +36,9 @@ along with GNU Emacs. If not, see . */ #include "dynlib.h" #include "buffer.h" #include "blockinput.h" -#include "sha512.h" +#include "md5.h" +#include "sysstdio.h" +#include "zlib.h" /********************************/ @@ -394,8 +396,6 @@ load_gccjit_if_necessary (bool mandatory) } -#define ELN_FILENAME_HASH_LEN 64 - /* C symbols emitted for the load relocation mechanism. */ #define CURRENT_THREAD_RELOC_SYM "current_thread_reloc" #define PURE_RELOC_SYM "pure_reloc" @@ -640,9 +640,123 @@ format_string (const char *format, ...) static Lisp_Object comp_hash_string (Lisp_Object string) { - Lisp_Object digest = make_uninit_string (SHA512_DIGEST_SIZE * 2); - sha512_buffer (SSDATA (string), SCHARS (string), SSDATA (digest)); - hexbuf_digest (SSDATA (digest), SDATA (digest), SHA512_DIGEST_SIZE); + Lisp_Object digest = make_uninit_string (MD5_DIGEST_SIZE * 2); + md5_buffer (SSDATA (string), SCHARS (string), SSDATA (digest)); + hexbuf_digest (SSDATA (digest), SDATA (digest), MD5_DIGEST_SIZE); + + return digest; +} + +#define MD5_BLOCKSIZE 32768 /* From md5.c */ + +static char acc_buff[2 * MD5_BLOCKSIZE]; +static size_t acc_size; + +static void +accumulate_and_process_md5 (void *data, size_t len, struct md5_ctx *ctxt) +{ + eassert (len <= MD5_BLOCKSIZE); + /* We may optimize this saving some of these memcpy/move using + directly the outer buffers but so far I'll not bother. */ + memcpy (acc_buff + acc_size, data, len); + acc_size += len; + if (acc_size >= MD5_BLOCKSIZE) + { + acc_size -= MD5_BLOCKSIZE; + md5_process_block (acc_buff, MD5_BLOCKSIZE, ctxt); + memmove (acc_buff, acc_buff + MD5_BLOCKSIZE, acc_size); + } +} + +static void +final_process_md5 (struct md5_ctx *ctxt) +{ + if (acc_size) + { + md5_process_bytes (acc_buff, acc_size, ctxt); + acc_size = 0; + } +} + +static int +md5_gz_stream (FILE *source, void *resblock) +{ + z_stream stream; + unsigned char in[MD5_BLOCKSIZE]; + unsigned char out[MD5_BLOCKSIZE]; + + eassert (!acc_size); + + struct md5_ctx ctx; + md5_init_ctx (&ctx); + + /* allocate inflate state */ + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = 0; + stream.next_in = Z_NULL; + int res = inflateInit2 (&stream, MAX_WBITS + 32); + if (res != Z_OK) + return -1; + + do { + stream.avail_in = fread (in, 1, MD5_BLOCKSIZE, source); + if (ferror (source)) { + inflateEnd (&stream); + return -1; + } + if (stream.avail_in == 0) + break; + stream.next_in = in; + + do { + stream.avail_out = MD5_BLOCKSIZE; + stream.next_out = out; + res = inflate (&stream, Z_NO_FLUSH); + + if (res != Z_OK && res != Z_STREAM_END) + return -1; + + accumulate_and_process_md5 (out, MD5_BLOCKSIZE - stream.avail_out, &ctx); + } while (!stream.avail_out); + + } while (res != Z_STREAM_END); + + final_process_md5 (&ctx); + inflateEnd (&stream); + + if (res != Z_STREAM_END) + return -1; + + md5_finish_ctx (&ctx, resblock); + + return 0; +} +#undef MD5_BLOCKSIZE + +static Lisp_Object +comp_hash_source_file (Lisp_Object filename) +{ + /* Can't use Finsert_file_contents + Fbuffer_hash as this is called + by Fcomp_el_to_eln_filename too early during bootstrap. */ + bool is_gz = suffix_p (filename, ".gz"); + FILE *f = emacs_fopen (SSDATA (filename), is_gz ? "rb" : "r"); + + if (!f) + report_file_error ("Opening source file", filename); + + Lisp_Object digest = make_uninit_string (MD5_DIGEST_SIZE * 2); + + int res = is_gz + ? md5_gz_stream (f, SSDATA (digest)) + : md5_stream (f, SSDATA (digest)); + fclose (f); + + if (res) + xsignal2 (Qfile_notify_error, build_string ("hashing failed"), filename); + + hexbuf_digest (SSDATA (digest), SSDATA (digest), MD5_DIGEST_SIZE); return digest; } @@ -3872,21 +3986,36 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) { CHECK_STRING (filename); + filename = Fexpand_file_name (filename, Qnil); + + if (NILP (Ffile_exists_p (filename))) + xsignal1 (Qfile_missing, filename); + + Lisp_Object content_hash = comp_hash_source_file (filename); + if (suffix_p (filename, ".gz")) filename = Fsubstring (filename, Qnil, make_fixnum (-3)); - filename = Fexpand_file_name (filename, Qnil); /* We create eln filenames with an hash in order to look-up these starting from the source filename, IOW have a relation - /absolute/path/filename.el -> eln-cache/filename-hash.eln. + + /absolute/path/filename.el + content -> + eln-cache/filename-path_hash-content_hash.eln. + + 'dlopen' can return the same handle if two shared with the same + filename are loaded in two different times (even if the first was + deleted!). To prevent this scenario the source file content is + included in the hashing algorithm. + + As at any point in time no more then one file can exist with the + same filename, should be possibile to clean up all + filename-path_hash-* except the most recent one (or the new one + being recompiled). As installing .eln files compiled during the build changes their absolute path we need an hashing mechanism that is not sensitive to that. For this we replace if match PATH_DUMPLOADSEARCH or - PATH_LOADSEARCH with '//' before generating the hash. - - Another approach would be to hash using the source file content - but this may have a measurable performance impact. */ + PATH_LOADSEARCH with '//' before generating the hash. */ if (NILP (loadsearch_re_list)) { @@ -3909,12 +4038,12 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) break; } } - - Lisp_Object hash = Fsubstring (comp_hash_string (filename), Qnil, - make_fixnum (ELN_FILENAME_HASH_LEN)); + Lisp_Object separator = build_string ("-"); + Lisp_Object path_hash = comp_hash_string (filename); filename = concat2 (Ffile_name_nondirectory (Fsubstring (filename, Qnil, make_fixnum (-3))), - build_string ("-")); + separator); + Lisp_Object hash = concat3 (path_hash, separator, content_hash); filename = concat3 (filename, hash, build_string (NATIVE_ELISP_SUFFIX)); if (NILP (base_dir)) base_dir = XCAR (Vcomp_eln_load_path); diff --git a/src/lread.c b/src/lread.c index 521da4e1d81..3d0de495605 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1623,10 +1623,17 @@ maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime) Lisp_Object eln_path_tail = Vcomp_eln_load_path; FOR_EACH_TAIL_SAFE (eln_path_tail) { - Lisp_Object el_name = + Lisp_Object src_name = Fsubstring (*filename, Qnil, make_fixnum (-1)); + if (NILP (Ffile_exists_p (src_name))) + { + src_name = concat2 (src_name, build_string (".gz")); + if (NILP (Ffile_exists_p (src_name))) + /* Can't find the corresponding source file. */ + return; + } Lisp_Object eln_name = - Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail)); + Fcomp_el_to_eln_filename (src_name, XCAR (eln_path_tail)); int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0); if (eln_fd > 0) @@ -1643,7 +1650,7 @@ maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime) *fd = eln_fd; /* Store the eln -> el relation. */ Fputhash (Ffile_name_nondirectory (eln_name), - el_name, Vcomp_eln_to_el_h); + src_name, Vcomp_eln_to_el_h); return; } else -- cgit v1.2.3 From 187a0333bf0d1c5dd08ec76c9265e5a6077f8e74 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 4 Oct 2020 09:12:49 +0200 Subject: * configure.ac: Better HAVE_NATIVE_COMP description --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 990933afc93..3d24751c934 100644 --- a/configure.ac +++ b/configure.ac @@ -3809,7 +3809,7 @@ if test "${with_nativecomp}" != "no"; then LIBGCCJIT_LIB="-lgccjit -ldl" fi NEED_DYNLIB=yes - AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if you have the libgccjit library (-lgccjit).]) + AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if native compiler is available.]) fi AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) -- cgit v1.2.3 From afb765ab3cab7b6582d0def543b23603cd076445 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 4 Oct 2020 09:16:24 +0200 Subject: Make filename hashing compatible with self contained builds (bug#43532) * Makefile.in (lispdirrel): Add replace template. (epaths-force): Form correctly 'PATH_REL_LOADSEARCH' into epath.h * configure.ac (lispdirrel): Define variable (relative path of the lisp files from the installation directory). * src/comp.c (Fcomp_el_to_eln_filename): Update algorithm not to rely on 'PATH_DUMPLOADSEARCH' but on 'PATH_REL_LOADSEARCH'. * src/epaths.in (PATH_REL_LOADSEARCH): Add macro template. --- Makefile.in | 5 +++++ configure.ac | 7 +++++-- src/comp.c | 22 +++++----------------- src/epaths.in | 4 ++++ 4 files changed, 19 insertions(+), 19 deletions(-) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index 2b47762b7bc..027dca0bd70 100644 --- a/Makefile.in +++ b/Makefile.in @@ -223,6 +223,10 @@ iconsrcdir=$(srcdir)/etc/images/icons # These variables hold the values Emacs will actually use. They are # based on the values of the standard Make variables above. +# Where lisp files are installed in a distributed with Emacs (relative +# path to the installation directory). +lispdirrel=@lispdirrel@ + # Where to install the lisp files distributed with Emacs. # This includes the Emacs version, so that the lisp files for different # versions of Emacs will install themselves in separate directories. @@ -368,6 +372,7 @@ epaths-force: @(gamedir='${gamedir}'; \ sed < ${srcdir}/src/epaths.in > epaths.h.$$$$ \ -e 's;\(#.*PATH_LOADSEARCH\).*$$;\1 "${standardlisppath}";' \ + -e 's;\(#.*PATH_REL_LOADSEARCH\).*$$;\1 "${lispdirrel}";' \ -e 's;\(#.*PATH_SITELOADSEARCH\).*$$;\1 "${locallisppath}";' \ -e 's;\(#.*PATH_DUMPLOADSEARCH\).*$$;\1 "${buildlisppath}";' \ -e '/^#define PATH_[^ ]*SEARCH /s/\([":]\):*/\1/g' \ diff --git a/configure.ac b/configure.ac index 3d24751c934..ead27d3dea9 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,8 @@ dnl It is important that variables on the RHS not be expanded here, dnl hence the single quotes. This is per the GNU coding standards, see dnl (autoconf) Installation Directory Variables dnl See also epaths.h below. -lispdir='${datadir}/emacs/${version}/lisp' +lispdirrel='${version}/lisp' +lispdir='${datadir}/emacs/'${lispdirrel} standardlisppath='${lispdir}' locallisppath='${datadir}/emacs/${version}/site-lisp:'\ '${datadir}/emacs/site-lisp' @@ -1908,7 +1909,8 @@ if test "${with_ns}" != no; then NS_IMPL_COCOA=yes ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir}/Contents/MacOS - ns_appresdir=${ns_appdir}/Contents/Resources + lispdirrel=Contents/Resources + ns_appresdir=${ns_appdir}/{lispdirrel} ns_appsrc=Cocoa/Emacs.base ns_fontfile=macfont.o elif flags=$( (gnustep-config --objc-flags) 2>/dev/null); then @@ -5325,6 +5327,7 @@ AC_SUBST(sharedstatedir) AC_SUBST(libexecdir) AC_SUBST(mandir) AC_SUBST(infodir) +AC_SUBST(lispdirrel) AC_SUBST(lispdir) AC_SUBST(standardlisppath) AC_SUBST(locallisppath) diff --git a/src/comp.c b/src/comp.c index 058ce7e96ac..5663c9e5624 100644 --- a/src/comp.c +++ b/src/comp.c @@ -4050,27 +4050,15 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) As installing .eln files compiled during the build changes their absolute path we need an hashing mechanism that is not sensitive to that. For this we replace if match PATH_DUMPLOADSEARCH or - PATH_LOADSEARCH with '//' before generating the hash. */ + *PATH_REL_LOADSEARCH with '//' before computing the hash. */ if (NILP (loadsearch_re_list)) { - Lisp_Object sys_re; -#ifdef __APPLE__ - /* On MacOS we relax the match on PATH_LOADSEARCH making - everything before ".app/" a wildcard. This to obtain a - self-contained Emacs.app (bug#43532). */ - char *c; - if ((c = strstr (PATH_LOADSEARCH, ".app/"))) - sys_re = - concat2 (build_string ("\\`[[:ascii:]]+"), - Fregexp_quote (build_string (c))); - else - sys_re = Fregexp_quote (build_string (PATH_LOADSEARCH)); -#else - sys_re = Fregexp_quote (build_string (PATH_LOADSEARCH)); -#endif + Lisp_Object sys_re = + concat2 (build_string ("\\`[[:ascii:]]+"), + Fregexp_quote (build_string ("/" PATH_REL_LOADSEARCH "/"))); loadsearch_re_list = - list2 (sys_re, Fregexp_quote (build_string (PATH_DUMPLOADSEARCH))); + list2 (sys_re, Fregexp_quote (build_string (PATH_DUMPLOADSEARCH "/"))); } Lisp_Object lds_re_tail = loadsearch_re_list; diff --git a/src/epaths.in b/src/epaths.in index 3cadd160ecf..5b6c650b0da 100644 --- a/src/epaths.in +++ b/src/epaths.in @@ -27,6 +27,10 @@ along with GNU Emacs. If not, see . */ */ #define PATH_LOADSEARCH "/usr/local/share/emacs/lisp" +/* Like PATH_LOADSEARCH, but contains the relative path from the + installation directory. +*/ +#define PATH_REL_LOADSEARCH "" /* Like PATH_LOADSEARCH, but contains the non-standard pieces. These are the site-lisp directories. Configure sets this to -- cgit v1.2.3 From 915214ac9a97025c01ec0bf1375d3630b3f6adf0 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 4 Oct 2020 22:48:37 +0200 Subject: * configure.ac : Fix typo for MacOS nativecomp introduced by afb765ab3c --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 5aceac6d951..be53578239b 100644 --- a/configure.ac +++ b/configure.ac @@ -1910,7 +1910,7 @@ if test "${with_ns}" != no; then ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir}/Contents/MacOS lispdirrel=Contents/Resources - ns_appresdir=${ns_appdir}/{lispdirrel} + ns_appresdir=${ns_appdir}/${lispdirrel} ns_appsrc=Cocoa/Emacs.base ns_fontfile=macfont.o elif flags=$( (gnustep-config --objc-flags) 2>/dev/null); then -- cgit v1.2.3 From 323200044f0c3f716f8f78a6f5e39349fe039117 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Mon, 5 Oct 2020 08:42:12 +0200 Subject: * configure.ac (lispdirrel): Fix value for MacOS build. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index be53578239b..b7b0c268c84 100644 --- a/configure.ac +++ b/configure.ac @@ -1906,11 +1906,11 @@ if test "${with_ns}" != no; then # so avoid NS_IMPL_COCOA if macuvs.h is absent. # Even a headless Emacs can build macuvs.h, so this should let you bootstrap. if test "${opsys}" = darwin && test -f "$srcdir/src/macuvs.h"; then + lispdirrel=Contents/Resources/lisp NS_IMPL_COCOA=yes ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir}/Contents/MacOS - lispdirrel=Contents/Resources - ns_appresdir=${ns_appdir}/${lispdirrel} + ns_appresdir=${ns_appdir}/Contents/Resources ns_appsrc=Cocoa/Emacs.base ns_fontfile=macfont.o elif flags=$( (gnustep-config --objc-flags) 2>/dev/null); then -- cgit v1.2.3 From bd2725796578c67075711adc4c1be7c2bf684214 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 7 Oct 2020 08:40:00 +0200 Subject: * Better libgccjit related error messaging during configure * configure.ac: Distinguish the case when libgccjit is missing, its headers are missing, or libgccjit is broken. Message the user based on that. --- configure.ac | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index b7b0c268c84..100fbba06c9 100644 --- a/configure.ac +++ b/configure.ac @@ -3779,15 +3779,25 @@ AC_DEFUN([libgccjit_smoke_test], [ AC_DEFUN([libgccjit_not_found], [ AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. +Please try installing libgccjit or similar package. If you are sure you want Emacs compiled without elisp native compiler, pass --without-nativecomp to configure.])]) +AC_DEFUN([libgccjit_dev_not_found], [ + AC_MSG_ERROR([elisp native compiler requested but libgccjit header files were +not found. +Please try installing libgccjit-dev or similar package. +If you are sure you want Emacs compiled without elisp native compiler, pass +--without-nativecomp +to configure.])]) + AC_DEFUN([libgccjit_broken], [ AC_MSG_ERROR([Installed libgccjit has failed passing the smoke test. You can verify it yourself compiling: . -Please report the issue to your distribution. +Please report the issue to your distribution if libgccjit was installed through +that. Here instructions on how to compile and install libgccjit from source: .])]) @@ -3800,10 +3810,13 @@ if test "${with_nativecomp}" != "no"; then if test "${HAVE_ZLIB}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires zlib]) fi + # Check if libgccjit is available. + AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, [], [libgccjit_not_found]) + AC_CHECK_HEADERS(libgccjit.h, [], [libgccjit_dev_not_found]) emacs_save_LIBS=$LIBS LIBS="-lgccjit" - AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken], - [AC_LINK_IFELSE([libgccjit_smoke_test], [], [libgccjit_not_found])]) + # Check if libgccjit really works. + AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken]) LIBS=$emacs_save_LIBS HAVE_NATIVE_COMP=yes # mingw32 loads the library dynamically. -- cgit v1.2.3 From 79b9a262ffab37296a39c2d69cdabae153db10a7 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Tue, 12 Jan 2021 21:27:11 +0100 Subject: * configure.ac: Fix native-comp OpenBSD build. --- configure.ac | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 1f9fd330a35..2a4a373371c 100644 --- a/configure.ac +++ b/configure.ac @@ -3825,10 +3825,15 @@ if test "${with_nativecomp}" != "no"; then AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken]) LIBS=$emacs_save_LIBS HAVE_NATIVE_COMP=yes - # mingw32 loads the library dynamically. - if test "${opsys}" != "mingw32"; then - LIBGCCJIT_LIB="-lgccjit -ldl" - fi + case "${opsys}" in + # mingw32 loads the library dynamically. + mingw32) ;; + # OpenBSD doesn't have libdl, all the functions are in libc + openbsd) + LIBGCCJIT_LIB="-lgccjit" ;; + *) + LIBGCCJIT_LIB="-lgccjit -ldl" ;; + esac NEED_DYNLIB=yes AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if native compiler is available.]) fi -- cgit v1.2.3 From db237850abc240e2c3e765e9cc7e15ee5681dcaf Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Fri, 12 Feb 2021 11:43:02 +0100 Subject: Remove Motif support * configure.ac: Remove support for configuring --with-x-toolkit=motif * etc/NEWS: Mention removal of Motif support. --- configure.ac | 9 ++++----- etc/NEWS | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 08f3c0cd857..12cf36303b3 100644 --- a/configure.ac +++ b/configure.ac @@ -409,19 +409,18 @@ dnl This should be the last --with option, because --with-x is dnl added later on when we find the file name of X, and it's best to dnl keep them together visually. AC_ARG_WITH([x-toolkit],[AS_HELP_STRING([--with-x-toolkit=KIT], - [use an X toolkit (KIT one of: yes or gtk, gtk2, gtk3, lucid or athena, motif, no)])], + [use an X toolkit (KIT one of: yes or gtk, gtk2, gtk3, lucid or athena, no)])], [ case "${withval}" in y | ye | yes ) val=gtk ;; n | no ) val=no ;; l | lu | luc | luci | lucid ) val=lucid ;; a | at | ath | athe | athen | athena ) val=athena ;; - m | mo | mot | moti | motif ) val=motif ;; g | gt | gtk ) val=gtk ;; gtk2 ) val=gtk2 ;; gtk3 ) val=gtk3 ;; * ) AC_MSG_ERROR(['--with-x-toolkit=$withval' is invalid; -this option's value should be 'yes', 'no', 'lucid', 'athena', 'motif', 'gtk', +this option's value should be 'yes', 'no', 'lucid', 'athena', 'gtk', 'gtk2' or 'gtk3'. 'yes' and 'gtk' are synonyms. 'athena' and 'lucid' are synonyms.]) ;; @@ -460,7 +459,7 @@ OPTION_DEFAULT_ON([harfbuzz],[don't use HarfBuzz for text shaping]) OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support]) OPTION_DEFAULT_ON([m17n-flt],[don't use m17n-flt for text shaping]) -OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Motif/Xaw3d/GTK toolkit scroll bars]) +OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Xaw3d/GTK toolkit scroll bars]) OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d]) OPTION_DEFAULT_ON([xim],[at runtime, default X11 XIM to off]) OPTION_DEFAULT_ON([xdbe],[don't use X11 double buffering support]) @@ -2252,7 +2251,7 @@ if test "$window_system" = none && test "X$with_x" != "Xno"; then then AC_MSG_ERROR([You seem to be running X, but no X development libraries were found. You should install the relevant development files for X -and for the toolkit you want, such as Gtk+ or Motif. Also make +and for the toolkit you want, such as Gtk+. Also make sure you have development files for image handling, i.e. tiff, gif, jpeg, png and xpm. If you are sure you want Emacs compiled without X window support, pass diff --git a/etc/NEWS b/etc/NEWS index 2f15f078a75..9a9c75f0f8c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -24,6 +24,9 @@ applies, and please also update docstrings as needed. * Installation Changes in Emacs 28.1 +-- +** Support for building with Motif has been removed. + ** Cairo graphics library is now used by default if found. '--with-cairo' is now the default, if the appropriate development files are found by 'configure'. Note that building with Cairo means using -- cgit v1.2.3 From 45e964755bafec934b34f5c7c65e861fbe4c8aa6 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 16 Feb 2021 20:34:26 -0800 Subject: Remove TIME_WITH_SYS_TIME, unused for a long time * configure.ac (AC_HEADER_TIME): Remove. (Bug#46578) --- admin/CPP-DEFINES | 1 - configure.ac | 1 - 2 files changed, 2 deletions(-) (limited to 'configure.ac') diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES index a40b4302723..cb69b2c36c2 100644 --- a/admin/CPP-DEFINES +++ b/admin/CPP-DEFINES @@ -378,7 +378,6 @@ SYSTEM_MALLOC TAB3 TABDLY TERM -TIME_WITH_SYS_TIME TIOCSIGSEND TM_IN_SYS_TIME UNIX98_PTYS diff --git a/configure.ac b/configure.ac index 12cf36303b3..5fd0e76b823 100644 --- a/configure.ac +++ b/configure.ac @@ -1768,7 +1768,6 @@ fi dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define 'bool'. AC_CHECK_HEADERS(term.h, , , -) -AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS_ONCE(sys/socket.h) -- cgit v1.2.3 From 5f078928bbe85c11d5240d178b3801cd2e23198e Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 16 Feb 2021 20:54:46 -0800 Subject: * configure.ac: Replace obsolete AC_TRY_LINK with AC_LINK_IFELSE. --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 5fd0e76b823..9a294bc796f 100644 --- a/configure.ac +++ b/configure.ac @@ -4715,10 +4715,10 @@ if test "$USE_X_TOOLKIT" != "none"; then else OTHERLIBS="-lXt -$LIBXMU" fi - AC_TRY_LINK( - [#include - #include ], - [_XEditResCheckMessages (0, 0, 0, 0);], + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include + #include ]], + [[_XEditResCheckMessages (0, 0, 0, 0);]])], [AC_DEFINE([X_TOOLKIT_EDITRES], 1, [Define to 1 if we should use XEditRes.])]) LIBS=$OLDLIBS -- cgit v1.2.3 From 26fcd8289057805f506a24c6ae7277c653463208 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 16 Feb 2021 21:25:18 -0800 Subject: * configure.ac: Replace obsolete AC_CHECK_HEADER usage. (Bug#46578) --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 9a294bc796f..11a06a39bee 100644 --- a/configure.ac +++ b/configure.ac @@ -1767,7 +1767,8 @@ fi dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define 'bool'. -AC_CHECK_HEADERS(term.h, , , -) +AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include ]],[[]])], + AC_DEFINE(HAVE_TERM_H, 1, [Define to 1 if you have the header file.])) AC_HEADER_SYS_WAIT AC_CHECK_HEADERS_ONCE(sys/socket.h) -- cgit v1.2.3 From f6c5f0dd5c8167b6f8f724f42632a4b8808efe7a Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Mon, 22 Feb 2021 14:39:04 +0100 Subject: * configure.ac: Rename configure nativecomp flags into --with-native-comp. Configure now with '--with-native-comp'! --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index fe0dc921dce..1771171f669 100644 --- a/configure.ac +++ b/configure.ac @@ -484,7 +484,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) -OPTION_DEFAULT_OFF([nativecomp],[compile with Emacs Lisp native compiler support]) +OPTION_DEFAULT_OFF([native-comp],[compile with Emacs Lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -3786,7 +3786,7 @@ AC_DEFUN([libgccjit_not_found], [ AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. Please try installing libgccjit or similar package. If you are sure you want Emacs compiled without elisp native compiler, pass - --without-nativecomp + --without-native-comp to configure.])]) AC_DEFUN([libgccjit_dev_not_found], [ @@ -3808,7 +3808,7 @@ Here instructions on how to compile and install libgccjit from source: HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= -if test "${with_nativecomp}" != "no"; then +if test "${with_native_comp}" != "no"; then if test "${HAVE_PDUMPER}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) fi -- cgit v1.2.3 From cadb902aa8136d9eff8bb0df39daed840c00e1b6 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Mon, 22 Feb 2021 21:01:44 +0100 Subject: Revert "* configure.ac: Rename configure nativecomp flags..." This reverts commit f6c5f0dd5c8167b6f8f724f42632a4b8808efe7a. Reason for this is that I overlooked few other suggestions and this change has to be discussed before a final decision is taken. --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 1771171f669..fe0dc921dce 100644 --- a/configure.ac +++ b/configure.ac @@ -484,7 +484,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) -OPTION_DEFAULT_OFF([native-comp],[compile with Emacs Lisp native compiler support]) +OPTION_DEFAULT_OFF([nativecomp],[compile with Emacs Lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -3786,7 +3786,7 @@ AC_DEFUN([libgccjit_not_found], [ AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. Please try installing libgccjit or similar package. If you are sure you want Emacs compiled without elisp native compiler, pass - --without-native-comp + --without-nativecomp to configure.])]) AC_DEFUN([libgccjit_dev_not_found], [ @@ -3808,7 +3808,7 @@ Here instructions on how to compile and install libgccjit from source: HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= -if test "${with_native_comp}" != "no"; then +if test "${with_nativecomp}" != "no"; then if test "${HAVE_PDUMPER}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) fi -- cgit v1.2.3 From 42fc752a14b23be95f02b598930f13a96883d3a0 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Fri, 26 Feb 2021 20:11:31 +0100 Subject: * Change native compiler configure flag into '--with-native-compilation' * configure.ac: Rename configure nativecomp flags into --with-native-compilation. --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index fe0dc921dce..3dff9ea2e2d 100644 --- a/configure.ac +++ b/configure.ac @@ -484,7 +484,7 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) -OPTION_DEFAULT_OFF([nativecomp],[compile with Emacs Lisp native compiler support]) +OPTION_DEFAULT_OFF([native-compilation],[compile with Emacs Lisp native compiler support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])], @@ -3786,7 +3786,7 @@ AC_DEFUN([libgccjit_not_found], [ AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. Please try installing libgccjit or similar package. If you are sure you want Emacs compiled without elisp native compiler, pass - --without-nativecomp + --without-native-compilation to configure.])]) AC_DEFUN([libgccjit_dev_not_found], [ @@ -3808,7 +3808,7 @@ Here instructions on how to compile and install libgccjit from source: HAVE_NATIVE_COMP=no LIBGCCJIT_LIB= -if test "${with_nativecomp}" != "no"; then +if test "${with_native_compilation}" != "no"; then if test "${HAVE_PDUMPER}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) fi -- cgit v1.2.3 From c3cf99f53714ce1227ab508c9e359910a963659e Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 6 Mar 2021 10:38:07 -0800 Subject: Remove the --without-makeinfo configure option (bug#46837) * configure.ac (--without-makeinfo): Remove option. (HAVE_MAKEINFO): Remove output variable. * Makefile.in (HAVE_MAKEINFO): Remove. (info_misc): Remove HAVE_MAKEINFO check. (info-real): Remove target. (info): Simplify. ; * etc/NEWS: Mention this. --- Makefile.in | 31 +++---------------------------- configure.ac | 34 +++++++++++++--------------------- etc/NEWS | 6 ++++++ 3 files changed, 22 insertions(+), 49 deletions(-) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index 856c29a453e..85d063d8f6b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -166,9 +166,6 @@ infodir=@infodir@ # Info files not in the doc/misc directory (we get those via make echo-info). INFO_NONMISC=emacs.info eintr.info elisp.info -# If no makeinfo was found and configured --without-makeinfo, "no"; else "yes". -HAVE_MAKEINFO=@HAVE_MAKEINFO@ - # Directory for local state files for all programs. localstatedir=@localstatedir@ @@ -650,9 +647,6 @@ install-etcdoc: src install-arch-indep ## If info/dir is missing, but we have install-info, we should let ## that handle it. If info/dir is present and we do not have install-info, ## we should check for missing entries and add them by hand. -## -## FIXME: -## If HAVE_MAKEINFO = no and there are no info files, do not install info/dir. install-info: info umask 022; ${MKDIR_P} "$(DESTDIR)${infodir}" -unset CDPATH; \ @@ -667,7 +661,6 @@ install-info: info info_misc=`$(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ cd ${srcdir}/info ; \ for elt in ${INFO_NONMISC} $${info_misc}; do \ - test "$(HAVE_MAKEINFO)" = "no" && test ! -f $$elt && continue; \ for f in `ls $$elt $$elt-[1-9] $$elt-[1-9][0-9] 2>/dev/null`; do \ (cd "$${thisdir}"; \ ${INSTALL_DATA} ${srcdir}/info/$$f "$(DESTDIR)${infodir}/$$f"); \ @@ -987,13 +980,13 @@ $(DOCS): $(MAKE) -C doc/$(subst -, ,$@) .PHONY: $(DOCS) docs pdf ps -.PHONY: info dvi dist html info-real info-dir check-info +.PHONY: info dvi dist html info-dir check-info ## TODO add etc/refcards. docs: $(DOCS) dvi: $(DVIS) html: $(HTMLS) -info-real: $(INFOS) +info: $(INFOS) info-dir pdf: $(PDFS) ps: $(PSS) @@ -1027,7 +1020,7 @@ info_dir_deps = \ ## installation location by the install-info rule, but we also ## need one in the source directory for people running uninstalled. ## FIXME it would be faster to use the install-info program if we have it, -## but then we would need to depend on info-real, which would +## but then we would need to depend on ${INFOS}, which would ## slow down parallelization. ${srcdir}/info/dir: ${info_dir_deps} $(AM_V_at)${MKDIR_P} ${srcdir}/info @@ -1082,24 +1075,6 @@ uninstall-html: $(UNINSTALL_HTML) uninstall-pdf: $(UNINSTALL_PDF) uninstall-ps: $(UNINSTALL_PS) - -# Note that man/Makefile knows how to put the info files in $(srcdir), -# so we can do ok running make in the build dir. -# This used to have a clause that exited with an error if MAKEINFO = no. -# But it is inappropriate to do so without checking if makeinfo is -# actually needed - it is not if the info files are up-to-date. (Bug#3982) -# Only the doc/*/Makefiles can decide that, so we let those rules run -# and give a standard error if makeinfo is needed but missing. -# While it would be nice to give a more detailed error message, that -# would require changing every rule in doc/ that builds an info file, -# and it's not worth it. This case is only relevant if you download a -# release, then change the .texi files. -ifneq ($(HAVE_MAKEINFO),no) -info: info-real info-dir -else -info: -endif - ## build-aux/make-info-dir expects only certain dircategories. check-info: info cd info ; \ diff --git a/configure.ac b/configure.ac index 11a06a39bee..385a126dd39 100644 --- a/configure.ac +++ b/configure.ac @@ -506,11 +506,6 @@ otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.]) OPTION_DEFAULT_OFF([xwidgets], [enable use of xwidgets in Emacs buffers (requires gtk3 or macOS Cocoa)]) -## For the times when you want to build Emacs but don't have -## a suitable makeinfo, and can live without the manuals. -dnl https://lists.gnu.org/r/emacs-devel/2008-04/msg01844.html -OPTION_DEFAULT_ON([makeinfo],[don't require makeinfo for building manuals]) - ## Makefile.in needs the cache file name. AC_SUBST(cache_file) @@ -1344,14 +1339,13 @@ if test -n "$BREW"; then fi ## Require makeinfo >= 4.13 (last of the 4.x series) to build the manuals. -if test "${MAKEINFO:=makeinfo}" != "no"; then - case `($MAKEINFO --version) 2>/dev/null` in - *' (GNU texinfo) '4.1[[3-9]]* | \ - *' (GNU texinfo) '[[5-9]]* | \ - *' (GNU texinfo) '[[1-9][0-9]]* ) ;; - *) MAKEINFO=no;; - esac -fi +: ${MAKEINFO:=makeinfo} +case `($MAKEINFO --version) 2>/dev/null` in + *' (GNU texinfo) '4.1[[3-9]]* | \ + *' (GNU texinfo) '[[5-9]]* | \ + *' (GNU texinfo) '[[1-9][0-9]]* ) ;; + *) MAKEINFO=no;; +esac ## Makeinfo is unusual. For a released Emacs, the manuals are ## pre-built, and not deleted by the normal clean rules. makeinfo is @@ -1362,21 +1356,19 @@ fi ## should test for it as it does for any other build requirement. ## We use the presence of $srcdir/info/emacs to distinguish a release, ## with pre-built manuals, from a repository checkout. -HAVE_MAKEINFO=yes - if test "$MAKEINFO" = "no"; then MAKEINFO=makeinfo - if test "x${with_makeinfo}" = "xno"; then - HAVE_MAKEINFO=no - elif test ! -e "$srcdir/info/emacs" && test ! -e "$srcdir/info/emacs.info"; then + if test ! -e "$srcdir/info/emacs" && test ! -e "$srcdir/info/emacs.info"; then AC_MSG_ERROR( [You do not seem to have makeinfo >= 4.13, and your source tree does not seem to have pre-built manuals in the 'info' directory. -Either install a suitable version of makeinfo, or re-run configure -with the '--without-makeinfo' option to build without the manuals.] ) +Please install a suitable version of makeinfo.] ) + else + AC_MSG_WARN( [You do not seem to have makeinfo >= 4.13. +You will not be able to rebuild the manuals if you delete them or change +their sources.] ) fi fi AC_SUBST([MAKEINFO]) -AC_SUBST(HAVE_MAKEINFO) if test $opsys = mingw32; then DOCMISC_W32=efaq-w32 diff --git a/etc/NEWS b/etc/NEWS index 2e0628b45ec..d2b84d733db 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -66,6 +66,12 @@ shaping, so 'configure' now recommends that combination. ** The ftx font backend driver has been removed. It was declared obsolete in Emacs 27.1. +--- +** The configure option '--without-makeinfo' has been removed. +This was only ever relevant when building from a repository checkout. +Please install makeinfo, or if all else fails run 'make lisp' instead +of 'make [all]'. + --- ** Support for building with '-fcheck-pointer-bounds' has been removed. GCC has withdrawn the '-fcheck-pointer-bounds' option and support for -- cgit v1.2.3 From d632622b5aac5ff776e1b5048f29aeaf3ceaf553 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 6 Mar 2021 16:28:46 -0800 Subject: Simplify silent-rules build machinery * src/verbose.mk.in: New file. * configure.ac (AM_V, AM_DEFAULT_V): Remove output variables. (src/verbose.mk): New output file. * Makefile.in, admin/charsets/Makefile.in: * admin/grammars/Makefile.in, admin/unidata/Makefile.in: * doc/emacs/Makefile.in, doc/lispintro/Makefile.in: * doc/lispref/Makefile.in, doc/misc/Makefile.in, leim/Makefile.in: * lib-src/Makefile.in, lib/Makefile.in, lisp/Makefile.in: * lwlib/Makefile.in, nt/Makefile.in, oldXMenu/Makefile.in: * src/Makefile.in, src/verbose.mk.in, test/Makefile.in: Include src/verbose.mk rather than repeatedly defining AM_V_at etc. --- .gitignore | 1 + Makefile.in | 14 ++------------ admin/charsets/Makefile.in | 12 ++---------- admin/grammars/Makefile.in | 13 +------------ admin/unidata/Makefile.in | 18 +----------------- configure.ac | 8 +------- doc/emacs/Makefile.in | 10 +++------- doc/lispintro/Makefile.in | 9 ++------- doc/lispref/Makefile.in | 9 ++------- doc/misc/Makefile.in | 10 +++------- leim/Makefile.in | 14 ++------------ lib-src/Makefile.in | 29 ++--------------------------- lib/Makefile.in | 21 +-------------------- lisp/Makefile.in | 20 ++------------------ lwlib/Makefile.in | 19 ++----------------- nt/Makefile.in | 19 ++----------------- oldXMenu/Makefile.in | 19 ++----------------- src/Makefile.in | 36 +++--------------------------------- src/verbose.mk.in | 42 ++++++++++++++++++++++++++++++++++++++++++ test/Makefile.in | 26 ++------------------------ 20 files changed, 78 insertions(+), 271 deletions(-) create mode 100644 src/verbose.mk.in (limited to 'configure.ac') diff --git a/.gitignore b/.gitignore index ba8a65547f3..b653ef215b9 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,7 @@ lib/unistd.h src/buildobj.h src/globals.h src/lisp.mk +src/verbose.mk # Lisp-level sources built by 'make'. *cus-load.el diff --git a/Makefile.in b/Makefile.in index 46373190a6f..6acf9791ab9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,18 +95,8 @@ configuration=@configuration@ ### The nt/ subdirectory gets built only for MinGW NTDIR=@NTDIR@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/admin/charsets/Makefile.in b/admin/charsets/Makefile.in index 0fd130d346e..1fe029984b8 100644 --- a/admin/charsets/Makefile.in +++ b/admin/charsets/Makefile.in @@ -31,6 +31,7 @@ AWK = @AWK@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ charsetdir = ${top_srcdir}/etc/charsets lispintdir = ${top_srcdir}/lisp/international @@ -38,16 +39,7 @@ mapfiledir = ${srcdir}/mapfiles GLIBC_CHARMAPS = ${srcdir}/glibc -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Note: We can not prepend "ISO-" to these map files because of file # name limits on DOS. diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in index 98c9c623abc..aa09d9edf94 100644 --- a/admin/grammars/Makefile.in +++ b/admin/grammars/Makefile.in @@ -28,18 +28,7 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH diff --git a/admin/unidata/Makefile.in b/admin/unidata/Makefile.in index f31e1bb09fd..183569fb9b6 100644 --- a/admin/unidata/Makefile.in +++ b/admin/unidata/Makefile.in @@ -36,23 +36,7 @@ emacs = "${EMACS}" -batch --no-site-file --no-site-lisp lparen = ( unifiles = $(addprefix ${unidir}/,$(sort $(shell sed -n 's/^[ \t][ \t]*${lparen}"\(uni-[^"]*\)"$$/\1/p' ${srcdir}/unidata-gen.el))) -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk .PHONY: all diff --git a/configure.ac b/configure.ac index 385a126dd39..1802c1baa12 100644 --- a/configure.ac +++ b/configure.ac @@ -1184,9 +1184,6 @@ AC_DEFUN([AM_CONDITIONAL], dnl Prefer silent make output. For verbose output, use dnl 'configure --disable-silent-rules' or 'make V=1' . -dnl This code is adapted from Automake. -dnl Although it can be simplified now that GNU Make is assumed, -dnl the simplification hasn't been done yet. AC_ARG_ENABLE([silent-rules], [AS_HELP_STRING( [--disable-silent-rules], @@ -1196,11 +1193,8 @@ if test "$enable_silent_rules" = no; then else AM_DEFAULT_VERBOSITY=0 fi -AM_V='$(V)' -AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -AC_SUBST([AM_V]) -AC_SUBST([AM_DEFAULT_V]) AC_SUBST([AM_DEFAULT_VERBOSITY]) +AC_CONFIG_FILES([src/verbose.mk]) dnl Some other nice autoconf tests. AC_PROG_INSTALL diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in index 2a3f53f740d..4585b2e0ddc 100644 --- a/doc/emacs/Makefile.in +++ b/doc/emacs/Makefile.in @@ -28,6 +28,8 @@ srcdir=@srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ + version = @version@ ## Where the output files go. @@ -73,13 +75,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(TEXINPUTS)" \ MAKEINFO="$(MAKEINFO) $(MAKEINFO_OPTS)" diff --git a/doc/lispintro/Makefile.in b/doc/lispintro/Makefile.in index d8b909c9c10..45b4fe7e3b7 100644 --- a/doc/lispintro/Makefile.in +++ b/doc/lispintro/Makefile.in @@ -20,6 +20,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ +top_builddir = @top_builddir@ buildinfodir = $(srcdir)/../../info # Directory with the (customized) texinfo.tex file. @@ -55,13 +56,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = \ $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(emacsdir):$(TEXINPUTS)" \ diff --git a/doc/lispref/Makefile.in b/doc/lispref/Makefile.in index 271f06edddc..876303593ce 100644 --- a/doc/lispref/Makefile.in +++ b/doc/lispref/Makefile.in @@ -24,6 +24,7 @@ SHELL = @SHELL@ # Standard configure variables. srcdir = @srcdir@ +top_builddir = @top_builddir@ buildinfodir = $(srcdir)/../../info # Directory with the (customized) texinfo.tex file. @@ -59,13 +60,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = \ $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(emacsdir):$(TEXINPUTS)" \ diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 87d87bf2005..5130650fefe 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -23,6 +23,8 @@ SHELL = @SHELL@ # of the source tree. This is set by configure's '--srcdir' option. srcdir=@srcdir@ +top_builddir = @top_builddir@ + ## Where the output files go. ## Note that all the Info targets build the Info files in srcdir. ## There is no provision for Info files to exist in the build directory. @@ -112,13 +114,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = $(AM_V_GEN)TEXINPUTS="$(srcdir):$(emacsdir):$(TEXINPUTS)" \ MAKEINFO="$(MAKEINFO) $(MAKEINFO_OPTS)" diff --git a/leim/Makefile.in b/leim/Makefile.in index f3e530a11de..c2f9cf5ab5f 100644 --- a/leim/Makefile.in +++ b/leim/Makefile.in @@ -25,24 +25,14 @@ SHELL = @SHELL@ # Here are the things that we expect ../configure to edit. srcdir=@srcdir@ +top_builddir = @top_builddir@ # Where the generated files go. leimdir = ${srcdir}/../lisp/leim EXEEXT = @EXEEXT@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 0a6dd826c10..05eb524d19b 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -44,33 +44,8 @@ WERROR_CFLAGS = @WERROR_CFLAGS@ # Program name transformation. TRANSFORM = @program_transform_name@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_RC = $(am__v_RC_@AM_V@) -am__v_RC_ = $(am__v_RC_@AM_DEFAULT_V@) -am__v_RC_0 = @echo " RC " $@; -am__v_RC_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/lib/Makefile.in b/lib/Makefile.in index 91a6b5ff3f1..043ace29fd7 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -29,26 +29,7 @@ top_srcdir = @top_srcdir@ all: .PHONY: all -# 'make' verbosity. -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk ALL_CFLAGS= \ $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) $(DEPFLAGS) \ diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 72f7f1676b7..8ea28415585 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -21,6 +21,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ lisp = $(srcdir) VPATH = $(srcdir) EXEEXT = @EXEEXT@ @@ -29,24 +30,7 @@ EXEEXT = @EXEEXT@ # limitation. XARGS_LIMIT = @XARGS_LIMIT@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - +-include ${top_builddir}/src/verbose.mk FIND_DELETE = @FIND_DELETE@ diff --git a/lwlib/Makefile.in b/lwlib/Makefile.in index 28c16acbabc..fb0ae0e1c21 100644 --- a/lwlib/Makefile.in +++ b/lwlib/Makefile.in @@ -26,6 +26,7 @@ all: liblw.a .PHONY: all srcdir=@srcdir@ +top_builddir=@top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH=@srcdir@ @@ -56,23 +57,7 @@ TOOLKIT_OBJS = $(@X_TOOLKIT_TYPE@_OBJS) OBJS = lwlib.o $(TOOLKIT_OBJS) lwlib-utils.o -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk AUTO_DEPEND = @AUTO_DEPEND@ DEPDIR = deps diff --git a/nt/Makefile.in b/nt/Makefile.in index aa3a76280ef..0d448903ba5 100644 --- a/nt/Makefile.in +++ b/nt/Makefile.in @@ -41,23 +41,8 @@ WERROR_CFLAGS = @WERROR_CFLAGS@ # Program name transformation. TRANSFORM = @program_transform_name@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_RC = $(am__v_RC_@AM_V@) -am__v_RC_ = $(am__v_RC_@AM_DEFAULT_V@) -am__v_RC_0 = @echo " RC " $@; -am__v_RC_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/oldXMenu/Makefile.in b/oldXMenu/Makefile.in index 7ae355b568d..39fd155735a 100644 --- a/oldXMenu/Makefile.in +++ b/oldXMenu/Makefile.in @@ -43,6 +43,7 @@ ### Code: srcdir=@srcdir@ +top_builddir = @top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH=@srcdir@ @@ -93,23 +94,7 @@ OBJS = Activate.o \ all: libXMenu11.a .PHONY: all -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk AUTO_DEPEND = @AUTO_DEPEND@ DEPDIR = deps diff --git a/src/Makefile.in b/src/Makefile.in index a5ea5498a49..f3c545dba9a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -29,6 +29,7 @@ SHELL = @SHELL@ # We use $(srcdir) explicitly in dependencies so as not to depend on VPATH. srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH = $(srcdir) @@ -340,33 +341,7 @@ HAVE_PDUMPER = @HAVE_PDUMPER@ ## invalidates the signature, we must re-sign to fix it. DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@) -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - -AM_V_NO_PD = $(am__v_NO_PD_@AM_V@) -am__v_NO_PD_ = $(am__v_NO_PD_@AM_DEFAULT_V@) -am__v_NO_PD_0 = --no-print-directory -am__v_NO_PD_1 = +-include ${top_builddir}/src/verbose.mk bootstrap_exe = ../src/bootstrap-emacs$(EXEEXT) ifeq ($(DUMPING),pdumper) @@ -621,11 +596,6 @@ buildobj.h: Makefile GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m) -AM_V_GLOBALS = $(am__v_GLOBALS_@AM_V@) -am__v_GLOBALS_ = $(am__v_GLOBALS_@AM_DEFAULT_V@) -am__v_GLOBALS_0 = @echo " GEN " globals.h; -am__v_GLOBALS_1 = - gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES) $(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(obj) > globals.tmp $(AM_V_at)$(top_srcdir)/build-aux/move-if-change globals.tmp globals.h @@ -724,7 +694,7 @@ bootstrap-clean: clean fi distclean: bootstrap-clean - rm -f Makefile lisp.mk + rm -f Makefile lisp.mk verbose.mk rm -fr $(DEPDIR) maintainer-clean: distclean diff --git a/src/verbose.mk.in b/src/verbose.mk.in new file mode 100644 index 00000000000..e55fd63fc3c --- /dev/null +++ b/src/verbose.mk.in @@ -0,0 +1,42 @@ +### verbose.mk --- Makefile fragment for GNU Emacs + +## Copyright (C) 2021 Free Software Foundation, Inc. + +## 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 . + +# 'make' verbosity. +V = @AM_DEFAULT_VERBOSITY@ +ifeq (${V},1) +AM_V_AR = +AM_V_at = +AM_V_CC = +AM_V_CCLD = +AM_V_ELC = +AM_V_GEN = +AM_V_GLOBALS = +AM_V_NO_PD = +AM_V_RC = +else +AM_V_AR = @echo " AR " $@; +AM_V_at = @ +AM_V_CC = @echo " CC " $@; +AM_V_CCLD = @echo " CCLD " $@; +AM_V_ELC = @echo " ELC " $@; +AM_V_GEN = @echo " GEN " $@; +AM_V_GLOBALS = @echo " GEN " globals.h; +AM_V_NO_PD = --no-print-directory +AM_V_RC = @echo " RC " $@; +endif diff --git a/test/Makefile.in b/test/Makefile.in index 48bbe8712b4..ba354289e28 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -32,6 +32,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ abs_top_srcdir=@abs_top_srcdir@ +top_builddir = @top_builddir@ VPATH = $(srcdir) FIND_DELETE = @FIND_DELETE@ @@ -46,30 +47,7 @@ SO = @MODULES_SUFFIX@ SEPCHAR = @SEPCHAR@ - -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - +-include ${top_builddir}/src/verbose.mk # Load any GNU ELPA dependencies that are present, for optional tests. GNU_ELPA_DIRECTORY ?= $(srcdir)/../../elpa -- cgit v1.2.3 From 2c3340909abd4f88be6ab814247a6dcd5da0a899 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Fri, 19 Mar 2021 08:58:32 +0100 Subject: Warn the user if we can't find pkg-config * configure.ac (WITH_IFAVAILABLE): Warn the user if we can't find a usable pkg-config (bug#47159). --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 1802c1baa12..2c62a9fe6f7 100644 --- a/configure.ac +++ b/configure.ac @@ -3897,6 +3897,11 @@ case $with_json,$HAVE_JSON in WITH_IFAVAILABLE="$WITH_IFAVAILABLE --with-json=ifavailable";; esac if test "X${MISSING}" != X; then + # If we have a missing library, and we don't have pkg-config installed, + # the missing pkg-config may be the reason. Give the user a hint. + if test "X${PKG_CONFIG}" = X; then + AC_MSG_WARN([Unable to locate a usable pkg-config]) + fi AC_MSG_ERROR([The following required libraries were not found: $MISSING Maybe some development libraries/packages are missing? -- cgit v1.2.3 From c35a515a2f7045f004299f601f6d1927ea16cd47 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Fri, 2 Apr 2021 18:06:59 +0100 Subject: Fix install with NS app bundle * configure.ac: Set up CFLAGS and LDFLAGS to find a Homebrew installation of libgccjit. * Makefile.in (ELN_DESTDIR): Set to the app bundle resource dir when required. (install-eln): macOS install doesn't support the -D flag, so make the directories separately. --- Makefile.in | 6 ++++-- configure.ac | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index e318db746d6..efe89b9b93e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -323,10 +323,11 @@ COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}" ifeq (${ns_self_contained},no) BIN_DESTDIR='$(DESTDIR)${bindir}/' +ELN_DESTDIR = $(DESTDIR)${libdir}/emacs/${version}/ else BIN_DESTDIR='${ns_appbindir}/' +ELN_DESTDIR = ${ns_appresdir}/ endif -ELN_DESTDIR = $(DESTDIR)${libdir}/emacs/${version}/ all: ${SUBDIR} info @@ -752,7 +753,8 @@ install-etc: ### Install native compiled Lisp files. install-eln: ifeq ($(HAVE_NATIVE_COMP),yes) - find native-lisp -type f -exec ${INSTALL_DATA} -D "{}" "$(ELN_DESTDIR){}" \; + find native-lisp -type d -exec $(MKDIR_P) "$(ELN_DESTDIR){}" \; ; \ + find native-lisp -type f -exec ${INSTALL_DATA} "{}" "$(ELN_DESTDIR){}" \; endif ### Build Emacs and install it, stripping binaries while installing them. diff --git a/configure.ac b/configure.ac index 4284c997141..698e8affb51 100644 --- a/configure.ac +++ b/configure.ac @@ -3801,6 +3801,16 @@ if test "${with_native_compilation}" != "no"; then if test "${HAVE_ZLIB}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires zlib]) fi + + # Ensure libgccjit installed by Homebrew can be found. + if test -n "$BREW"; then + BREW_LIBGCCJIT_PREFIX=`$BREW --prefix --installed libgccjit 2>/dev/null` + if test "$BREW_LIBGCCJIT_PREFIX"; then + CFLAGS="$CFLAGS -I${BREW_LIBGCCJIT_PREFIX}/include" + LDFLAGS="$LDFLAGS -L${BREW_LIBGCCJIT_PREFIX}/lib/gcc/10 -I${BREW_LIBGCCJIT_PREFIX}/include" + fi + fi + # Check if libgccjit is available. AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, [], [libgccjit_not_found]) AC_CHECK_HEADERS(libgccjit.h, [], [libgccjit_dev_not_found]) -- cgit v1.2.3 From 8ed46b7646de7166aa8bbd3b5d29a4947316c900 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 7 Apr 2021 19:02:56 +0100 Subject: Remove hardcoded gcc version * configure.ac: Use 'find' to find the brew installed libgccjit libs instead of a hardcoded path. --- configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 698e8affb51..3892eaed64b 100644 --- a/configure.ac +++ b/configure.ac @@ -3806,8 +3806,10 @@ if test "${with_native_compilation}" != "no"; then if test -n "$BREW"; then BREW_LIBGCCJIT_PREFIX=`$BREW --prefix --installed libgccjit 2>/dev/null` if test "$BREW_LIBGCCJIT_PREFIX"; then + brew_libdir=`find ${BREW_LIBGCCJIT_PREFIX}/ -name \*.so \ + | sed -e '1!d;s|/[[^/]]*\.so$||'` CFLAGS="$CFLAGS -I${BREW_LIBGCCJIT_PREFIX}/include" - LDFLAGS="$LDFLAGS -L${BREW_LIBGCCJIT_PREFIX}/lib/gcc/10 -I${BREW_LIBGCCJIT_PREFIX}/include" + LDFLAGS="$LDFLAGS -L${brew_libdir} -I${BREW_LIBGCCJIT_PREFIX}/include" fi fi -- cgit v1.2.3 From be8328acf9aa464f848e682e63e417a18529af9e Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Mon, 14 Dec 2020 21:25:11 +0100 Subject: Add support for --seccomp command-line option. When passing this option on GNU/Linux, Emacs installs a Secure Computing kernel system call filter. See Bug#45198. * configure.ac: Check for seccomp header. * src/emacs.c (usage_message): Document --seccomp option. (emacs_seccomp): New wrapper for 'seccomp' syscall. (load_seccomp, maybe_load_seccomp): New helper functions. (main): Potentially load seccomp filters during startup. (standard_args): Add --seccomp option. * lisp/startup.el (command-line): Detect and ignore --seccomp option. * test/src/emacs-tests.el (emacs-tests/seccomp/absent-file) (emacs-tests/seccomp/empty-file) (emacs-tests/seccomp/file-too-large) (emacs-tests/seccomp/invalid-file-size): New unit tests. (emacs-tests--with-temp-file): New helper macro. * etc/NEWS: Document new --seccomp option. --- configure.ac | 5 +- etc/NEWS | 10 +++ lisp/startup.el | 5 +- src/emacs.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++- test/src/emacs-tests.el | 131 +++++++++++++++++++++++++++++++++++++ 5 files changed, 314 insertions(+), 4 deletions(-) create mode 100644 test/src/emacs-tests.el (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 2c62a9fe6f7..684788a4d33 100644 --- a/configure.ac +++ b/configure.ac @@ -4179,6 +4179,8 @@ fi AC_SUBST([BLESSMAIL_TARGET]) AC_SUBST([LIBS_MAIL]) +AC_CHECK_HEADERS([linux/seccomp.h], [HAVE_SECCOMP=yes]) + OLD_LIBS=$LIBS LIBS="$LIB_PTHREAD $LIB_MATH $LIBS" AC_CHECK_FUNCS(accept4 fchdir gethostname \ @@ -5672,7 +5674,8 @@ optsep= emacs_config_features= for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \ HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \ - M17N_FLT MODULES NOTIFY NS OLDXMENU PDUMPER PNG RSVG SOUND THREADS TIFF \ + M17N_FLT MODULES NOTIFY NS OLDXMENU PDUMPER PNG RSVG SECCOMP SOUND \ + THREADS TIFF \ TOOLKIT_SCROLL_BARS UNEXEC X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \ ZLIB; do diff --git a/etc/NEWS b/etc/NEWS index 9ae37404823..0956084fc1a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -90,6 +90,16 @@ lacks the terminfo database, you can instruct Emacs to support 24-bit true color by setting 'COLORTERM=truecolor' in the environment. This is useful on systems such as FreeBSD which ships only with "etc/termcap". +** On GNU/Linux systems, Emacs now supports loading a Secure Computing +filter. To use this, you can pass a --seccomp=FILE command-line +option to Emacs. FILE must name a binary file containing an array of +'struct sock_filter' structures. Emacs will then install that list of +Secure Computing filters into its own process early during the startup +process. You can use this functionality to put an Emacs process in a +sandbox to avoid security issues when executing untrusted code. See +the manual page for 'seccomp' for details about Secure Computing +filters. + * Changes in Emacs 28.1 diff --git a/lisp/startup.el b/lisp/startup.el index b173d619733..4d4c65e6c41 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1097,7 +1097,7 @@ please check its value") ("--no-x-resources") ("--debug-init") ("--user") ("--iconic") ("--icon-type") ("--quick") ("--no-blinking-cursor") ("--basic-display") - ("--dump-file") ("--temacs"))) + ("--dump-file") ("--temacs") ("--seccomp"))) (argi (pop args)) (orig-argi argi) argval) @@ -1149,7 +1149,8 @@ please check its value") (push '(visibility . icon) initial-frame-alist)) ((member argi '("-nbc" "-no-blinking-cursor")) (setq no-blinking-cursor t)) - ((member argi '("-dump-file" "-temacs")) ; Handled in C + ((member argi '("-dump-file" "-temacs" "-seccomp")) + ;; Handled in C (or argval (pop args)) (setq argval nil)) ;; Push the popped arg back on the list of arguments. diff --git a/src/emacs.c b/src/emacs.c index fd08667f3fd..b956e9ca34b 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -61,6 +61,13 @@ along with GNU Emacs. If not, see . */ # include #endif +#ifdef HAVE_LINUX_SECCOMP_H +# include +# include +# include +# include +#endif + #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ @@ -240,6 +247,11 @@ Initialization options:\n\ "\ --dump-file FILE read dumped state from FILE\n\ ", +#endif +#ifdef HAVE_LINUX_SECCOMP_H + "\ +--sandbox=FILE read Seccomp BPF filter from FILE\n\ +" #endif "\ --no-build-details do not add build details such as time stamps\n\ @@ -938,6 +950,149 @@ load_pdump (int argc, char **argv) } #endif /* HAVE_PDUMPER */ +#ifdef HAVE_LINUX_SECCOMP_H + +/* Wrapper function for the `seccomp' system call on GNU/Linux. This + system call usually doesn't have a wrapper function. See the + manual page of `seccomp' for the signature. */ + +static int +emacs_seccomp (unsigned int operation, unsigned int flags, void *args) +{ +#ifdef SYS_seccomp + return syscall (SYS_seccomp, operation, flags, args); +#else + errno = ENOSYS; + return -1; +#endif +} + +/* Attempt to load Secure Computing filters from FILE. Return false + if that doesn't work for some reason. */ + +static bool +load_seccomp (const char *file) +{ + bool success = false; + void *buffer = NULL; + int fd + = emacs_open_noquit (file, O_RDONLY | O_CLOEXEC | O_BINARY, 0); + if (fd < 0) + { + emacs_perror ("open"); + goto out; + } + struct stat stat; + if (fstat (fd, &stat) != 0) + { + emacs_perror ("fstat"); + goto out; + } + if (! S_ISREG (stat.st_mode)) + { + fprintf (stderr, "seccomp file %s is not regular\n", file); + goto out; + } + enum + { + /* See MAX_RW_COUNT in sysdep.c. */ +#ifdef MAX_RW_COUNT + max_read_size = MAX_RW_COUNT +#else + max_read_size = INT_MAX >> 18 << 18 +#endif + }; + struct sock_fprog program; + if (stat.st_size <= 0 || SIZE_MAX <= stat.st_size + || PTRDIFF_MAX <= stat.st_size || max_read_size < stat.st_size + || stat.st_size % sizeof *program.filter != 0) + { + fprintf (stderr, "seccomp filter %s has invalid size %ld\n", + file, (long) stat.st_size); + goto out; + } + size_t size = stat.st_size; + size_t count = size / sizeof *program.filter; + eassert (0 < count && count < SIZE_MAX); + if (USHRT_MAX < count) + { + fprintf (stderr, "seccomp filter %s is too big\n", file); + goto out; + } + /* Try reading one more byte to detect file size changes. */ + buffer = malloc (size + 1); + if (buffer == NULL) + { + emacs_perror ("malloc"); + goto out; + } + ptrdiff_t read = emacs_read (fd, buffer, size + 1); + if (read < 0) + { + emacs_perror ("read"); + goto out; + } + if (read != count) + { + fprintf (stderr, + "seccomp filter %s changed size while reading\n", + file); + goto out; + } + if (emacs_close (fd) < 0) + emacs_perror ("close"); /* not a fatal error */ + fd = -1; + program.len = count; + program.filter = buffer; + + /* See man page of `seccomp' why this is necessary. Note that we + intentionally don't check the return value: a parent process + might have made this call before, in which case it would fail; + or, if enabling privilege-restricting mode fails, the `seccomp' + syscall will fail anyway. */ + prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + /* Install the filter. Make sure that potential other threads can't + escape it. */ + if (emacs_seccomp (SECCOMP_SET_MODE_FILTER, + SECCOMP_FILTER_FLAG_TSYNC, &program) + != 0) + { + emacs_perror ("seccomp"); + goto out; + } + success = true; + + out: + if (fd < 0) + emacs_close (fd); + free (buffer); + return success; +} + +/* Load Secure Computing filter from file specified with the --seccomp + option. Exit if that fails. */ + +static void +maybe_load_seccomp (int argc, char **argv) +{ + int skip_args = 0; + char *file = NULL; + while (skip_args < argc - 1) + { + if (argmatch (argv, argc, "-seccomp", "--seccomp", 9, &file, + &skip_args) + || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args)) + break; + ++skip_args; + } + if (file == NULL) + return; + if (! load_seccomp (file)) + fatal ("cannot enable seccomp filter from %s", file); +} + +#endif /* HAVE_LINUX_SECCOMP_H */ + int main (int argc, char **argv) { @@ -945,6 +1100,13 @@ main (int argc, char **argv) for pointers. */ void *stack_bottom_variable; + /* First, check whether we should apply a seccomp filter. This + should come at the very beginning to allow the filter to protect + the initialization phase. */ +#ifdef HAVE_LINUX_SECCOMP_H + maybe_load_seccomp (argc, argv); +#endif + bool no_loadup = false; char *junk = 0; char *dname_arg = 0; @@ -2133,12 +2295,15 @@ static const struct standard_args standard_args[] = { "-color", "--color", 5, 0}, { "-no-splash", "--no-splash", 3, 0 }, { "-no-desktop", "--no-desktop", 3, 0 }, - /* The following two must be just above the file-name args, to get + /* The following three must be just above the file-name args, to get them out of our way, but without mixing them with file names. */ { "-temacs", "--temacs", 1, 1 }, #ifdef HAVE_PDUMPER { "-dump-file", "--dump-file", 1, 1 }, #endif +#ifdef HAVE_LINUX_SECCOMP_H + { "-seccomp", "--seccomp", 1, 1 }, +#endif #ifdef HAVE_NS { "-NSAutoLaunch", 0, 5, 1 }, { "-NXAutoLaunch", 0, 5, 1 }, diff --git a/test/src/emacs-tests.el b/test/src/emacs-tests.el new file mode 100644 index 00000000000..7618a9c6752 --- /dev/null +++ b/test/src/emacs-tests.el @@ -0,0 +1,131 @@ +;;; emacs-tests.el --- unit tests for emacs.c -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Free Software Foundation, Inc. + +;; 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 . + +;;; Commentary: + +;; Unit tests for src/emacs.c. + +;;; Code: + +(require 'cl-lib) +(require 'ert) +(require 'rx) + +(ert-deftest emacs-tests/seccomp/absent-file () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (process-environment nil)) + (skip-unless (file-executable-p emacs)) + (should-not (file-exists-p "/does-not-exist.bpf")) + (should-not + (eql (call-process emacs nil nil nil + "--quick" "--batch" + "--seccomp=/does-not-exist.bpf") + 0)))) + +(cl-defmacro emacs-tests--with-temp-file + (var (prefix &optional suffix text) &rest body) + "Evaluate BODY while a new temporary file exists. +Bind VAR to the name of the file. Pass PREFIX, SUFFIX, and TEXT +to `make-temp-file', which see." + (declare (indent 2) (debug (symbolp (form form form) body))) + (cl-check-type var symbol) + ;; Use an uninterned symbol so that the code still works if BODY + ;; changes VAR. + (let ((filename (make-symbol "filename"))) + `(let ((,filename (make-temp-file ,prefix nil ,suffix ,text))) + (unwind-protect + (let ((,var ,filename)) + ,@body) + (delete-file ,filename))))) + +(ert-deftest emacs-tests/seccomp/empty-file () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (process-environment nil)) + (skip-unless (file-executable-p emacs)) + (emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf") + ;; The --seccomp option is processed early, without filename + ;; handlers. Therefore remote or quoted filenames wouldn't + ;; work. + (should-not (file-remote-p filter)) + (cl-callf file-name-unquote filter) + ;; According to the Seccomp man page, a filter must have at + ;; least one element, so Emacs should reject an empty file. + (should-not + (eql (call-process emacs nil nil nil + "--quick" "--batch" + (concat "--seccomp=" filter)) + 0))))) + +(ert-deftest emacs-tests/seccomp/file-too-large () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (process-environment nil) + ;; This value should be correct on all supported systems. + (ushort-max #xFFFF) + ;; Either 8 or 16, but 16 should be large enough in all cases. + (filter-size 16)) + (skip-unless (file-executable-p emacs)) + (emacs-tests--with-temp-file + filter ("seccomp-too-large-" ".bpf" + (make-string (* (1+ ushort-max) filter-size) ?a)) + ;; The --seccomp option is processed early, without filename + ;; handlers. Therefore remote or quoted filenames wouldn't + ;; work. + (should-not (file-remote-p filter)) + (cl-callf file-name-unquote filter) + ;; The filter count must fit into an `unsigned short'. A bigger + ;; file should be rejected. + (should-not + (eql (call-process emacs nil nil nil + "--quick" "--batch" + (concat "--seccomp=" filter)) + 0))))) + +(ert-deftest emacs-tests/seccomp/invalid-file-size () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (process-environment nil)) + (skip-unless (file-executable-p emacs)) + (emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf" + "123456") + ;; The --seccomp option is processed early, without filename + ;; handlers. Therefore remote or quoted filenames wouldn't + ;; work. + (should-not (file-remote-p filter)) + (cl-callf file-name-unquote filter) + ;; The Seccomp filter file must have a file size that's a + ;; multiple of the size of struct sock_filter, which is 8 or 16, + ;; but never 6. + (should-not + (eql (call-process emacs nil nil nil + "--quick" "--batch" + (concat "--seccomp=" filter)) + 0))))) + +;;; emacs-tests.el ends here -- cgit v1.2.3 From 1060289f51ee1bf269bb45940892eb272d35af97 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Thu, 17 Dec 2020 11:20:55 +0100 Subject: Add a helper binary to create a basic Secure Computing filter. The binary uses the 'seccomp' helper library. The library isn't needed to load the generated Secure Computing filter. * configure.ac: Check for 'seccomp' header and library. * lib-src/seccomp-filter.c: New helper binary to generate a generic Secure Computing filter for GNU/Linux. * lib-src/Makefile.in (DONT_INSTALL): Add 'seccomp-filter' helper binary if possible. (all): Add Secure Computing filter file if possible. (seccomp-filter$(EXEEXT)): Compile helper binary. (seccomp-filter.bpf seccomp-filter.pfc): Generate filter files. * test/src/emacs-tests.el (emacs-tests/seccomp/allows-stdout) (emacs-tests/seccomp/forbids-subprocess): New unit tests. * test/Makefile.in (src/emacs-tests.log): Add dependency on the helper binary. --- .gitignore | 5 + configure.ac | 5 + lib-src/Makefile.in | 19 ++ lib-src/seccomp-filter.c | 321 ++++++++++++++++++++++++++++ test/Makefile.in | 2 + test/src/emacs-resources/seccomp-filter.bpf | 1 + test/src/emacs-tests.el | 49 +++++ 7 files changed, 402 insertions(+) create mode 100644 lib-src/seccomp-filter.c create mode 120000 test/src/emacs-resources/seccomp-filter.bpf (limited to 'configure.ac') diff --git a/.gitignore b/.gitignore index b653ef215b9..ecf768dc4d6 100644 --- a/.gitignore +++ b/.gitignore @@ -188,6 +188,7 @@ lib-src/make-docfile lib-src/make-fingerprint lib-src/movemail lib-src/profile +lib-src/seccomp-filter lib-src/test-distrib lib-src/update-game-score nextstep/Cocoa/Emacs.base/Contents/Info.plist @@ -301,3 +302,7 @@ nt/emacs.rc nt/emacsclient.rc src/gdb.ini /var/ + +# Seccomp filter files. +lib-src/seccomp-filter.bpf +lib-src/seccomp-filter.pfc diff --git a/configure.ac b/configure.ac index 684788a4d33..0c4772a2b96 100644 --- a/configure.ac +++ b/configure.ac @@ -4181,6 +4181,11 @@ AC_SUBST([LIBS_MAIL]) AC_CHECK_HEADERS([linux/seccomp.h], [HAVE_SECCOMP=yes]) +LIBSECCOMP= +AC_CHECK_HEADER([seccomp.h], + [AC_CHECK_LIB([seccomp], [seccomp_init], [LIBSECCOMP=-lseccomp])]) +AC_SUBST([LIBSECCOMP]) + OLD_LIBS=$LIBS LIBS="$LIB_PTHREAD $LIB_MATH $LIBS" AC_CHECK_FUNCS(accept4 fchdir gethostname \ diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 05eb524d19b..1942882004e 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -189,6 +189,12 @@ LIB_WSOCK32=@LIB_WSOCK32@ ## Extra libraries for etags LIBS_ETAGS = $(LIB_CLOCK_GETTIME) $(LIB_GETRANDOM) +LIBSECCOMP=@LIBSECCOMP@ + +ifneq ($(LIBSECCOMP),) +DONT_INSTALL += seccomp-filter$(EXEEXT) +endif + ## Extra libraries to use when linking movemail. LIBS_MOVE = $(LIBS_MAIL) $(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) \ $(COM_ERRLIB) $(LIBHESIOD) $(LIBRESOLV) $(LIB_WSOCK32) $(LIBS_ETAGS) @@ -218,6 +224,10 @@ config_h = ../src/config.h $(srcdir)/../src/conf_post.h all: ${EXE_FILES} ${SCRIPTS} +ifneq ($(LIBSECCOMP),) +all: seccomp-filter.bpf +endif + .PHONY: all need-blessmail maybe-blessmail LOADLIBES = ../lib/libgnu.a $(LIBS_SYSTEM) @@ -400,4 +410,13 @@ update-game-score${EXEEXT}: ${srcdir}/update-game-score.c $(NTLIB) $(config_h) emacsclient.res: ../nt/emacsclient.rc $(NTINC)/../icons/emacs.ico $(AM_V_RC)$(WINDRES) -O coff --include-dir=$(NTINC)/.. -o $@ $< +ifneq ($(LIBSECCOMP),) +seccomp-filter$(EXEEXT): $(srcdir)/seccomp-filter.c $(config_h) + $(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $< $(LIBSECCOMP) -o $@ + +seccomp-filter.bpf seccomp-filter.pfc: seccomp-filter$(EXEEXT) + $(AM_V_GEN)./seccomp-filter$(EXEEXT) \ + seccomp-filter.bpf seccomp-filter.pfc +endif + ## Makefile ends here. diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c new file mode 100644 index 00000000000..9918fb025ef --- /dev/null +++ b/lib-src/seccomp-filter.c @@ -0,0 +1,321 @@ +/* Generate a Secure Computing filter definition file. + +Copyright (C) 2020 Free Software Foundation, Inc. + +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 +. */ + +/* This program creates a small Secure Computing filter usable for a +typical minimal Emacs sandbox. See the man page for `seccomp' for +details about Secure Computing filters. This program requires the +`libseccomp' library. However, the resulting filter file requires +only a Linux kernel supporting the Secure Computing extension. + +Usage: + + seccomp-filter out.bpf out.pfc + +This writes the raw `struct sock_filter' array to out.bpf and a +human-readable representation to out.pfc. */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "verify.h" + +static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void +fail (int error, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + if (error == 0) + vfprintf (stderr, format, ap); + else + { + char buffer[1000]; + vsnprintf (buffer, sizeof buffer, format, ap); + errno = error; + perror (buffer); + } + va_end (ap); + fflush (NULL); + exit (EXIT_FAILURE); +} + +/* This binary is trivial, so we use a single global filter context + object that we release using `atexit'. */ + +static scmp_filter_ctx ctx; + +static void +release_context (void) +{ + seccomp_release (ctx); +} + +/* Wrapper functions and macros for libseccomp functions. We exit + immediately upon any error to avoid error checking noise. */ + +static void +set_attribute (enum scmp_filter_attr attr, uint32_t value) +{ + int status = seccomp_attr_set (ctx, attr, value); + if (status < 0) + fail (-status, "seccomp_attr_set (ctx, %u, %u)", attr, value); +} + +/* Like `seccomp_rule_add (ACTION, SYSCALL, ...)', except that you + don't have to specify the number of comparator arguments, and any + failure will exit the process. */ + +#define RULE(action, syscall, ...) \ + do \ + { \ + const struct scmp_arg_cmp arg_array[] = {__VA_ARGS__}; \ + enum { arg_cnt = sizeof arg_array / sizeof *arg_array }; \ + int status = seccomp_rule_add_array (ctx, (action), (syscall), \ + arg_cnt, arg_array); \ + if (status < 0) \ + fail (-status, "seccomp_rule_add_array (%s, %s, %d, {%s})", \ + #action, #syscall, arg_cnt, #__VA_ARGS__); \ + } \ + while (false) + +static void +export_filter (const char *file, + int (*function) (const scmp_filter_ctx, int), + const char *name) +{ + int fd = TEMP_FAILURE_RETRY ( + open (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, + 0644)); + if (fd < 0) + fail (errno, "open %s", file); + int status = function (ctx, fd); + if (status < 0) + fail (-status, "%s", name); + if (close (fd) != 0) + fail (errno, "close"); +} + +#define EXPORT_FILTER(file, function) \ + export_filter ((file), (function), #function) + +int +main (int argc, char **argv) +{ + if (argc != 3) + fail (0, "usage: %s out.bpf out.pfc", argv[0]); + + /* Any unhandled syscall should abort the Emacs process. */ + ctx = seccomp_init (SCMP_ACT_KILL_PROCESS); + if (ctx == NULL) + fail (0, "seccomp_init"); + atexit (release_context); + + /* We want to abort immediately if the architecture is unknown. */ + set_attribute (SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_KILL_PROCESS); + set_attribute (SCMP_FLTATR_CTL_NNP, 1); + set_attribute (SCMP_FLTATR_CTL_TSYNC, 1); + set_attribute (SCMP_FLTATR_CTL_LOG, 0); + + verify (CHAR_BIT == 8); + verify (sizeof (int) == 4 && INT_MIN == INT32_MIN + && INT_MAX == INT32_MAX); + verify (sizeof (void *) == 8); + verify ((uintptr_t) NULL == 0); + + /* Allow a clean exit. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit_group)); + + /* Allow `mmap' and friends. This is necessary for dynamic loading, + reading the portable dump file, and thread creation. We don't + allow pages to be both writable and executable. */ + verify (MAP_PRIVATE != 0); + verify (MAP_SHARED != 0); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap), + SCMP_A2_32 (SCMP_CMP_MASKED_EQ, + ~(PROT_NONE | PROT_READ | PROT_WRITE)), + /* Only support known flags. MAP_DENYWRITE is ignored, but + some versions of the dynamic loader still use it. Also + allow allocating thread stacks. */ + SCMP_A3_32 (SCMP_CMP_MASKED_EQ, + ~(MAP_PRIVATE | MAP_FILE | MAP_ANONYMOUS + | MAP_FIXED | MAP_DENYWRITE | MAP_STACK + | MAP_NORESERVE), + 0)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap), + SCMP_A2_32 (SCMP_CMP_MASKED_EQ, + ~(PROT_NONE | PROT_READ | PROT_EXEC)), + /* Only support known flags. MAP_DENYWRITE is ignored, but + some versions of the dynamic loader still use it. */ + SCMP_A3_32 (SCMP_CMP_MASKED_EQ, + ~(MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED + | MAP_DENYWRITE), + 0)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (munmap)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (mprotect), + /* Don't allow making pages executable. */ + SCMP_A2_32 (SCMP_CMP_MASKED_EQ, + ~(PROT_NONE | PROT_READ | PROT_WRITE), 0)); + + /* Futexes are used everywhere. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex), + SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE)); + + /* Allow basic dynamic memory management. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (brk)); + + /* Allow some status inquiries. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (uname)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getuid)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (geteuid)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpid)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp)); + + /* Allow operations on open file descriptors. File descriptors are + capabilities, and operating on them shouldn't cause security + issues. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (read)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (write)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (close)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (lseek)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup2)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstat)); + + /* Allow read operations on the filesystem. If necessary, these + should be further restricted using mount namespaces. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (access)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat64)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat64)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstatat64)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (newfstatat)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlink)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlinkat)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getcwd)); + + /* Allow opening files, assuming they are only opened for + reading. */ + verify (O_WRONLY != 0); + verify (O_RDWR != 0); + verify (O_CREAT != 0); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (open), + SCMP_A1_32 (SCMP_CMP_MASKED_EQ, + ~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH + | O_DIRECTORY), + 0)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (openat), + SCMP_A2_32 (SCMP_CMP_MASKED_EQ, + ~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH + | O_DIRECTORY), + 0)); + + /* Allow `tcgetpgrp'. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (ioctl), + SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO), + SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP)); + + /* Allow reading (but not setting) file flags. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl), + SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl64), + SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); + + /* Allow reading random numbers from the kernel. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrandom)); + + /* Changing the umask is uncritical. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (umask)); + + /* Allow creation of pipes. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe2)); + + /* Allow reading (but not changing) resource limits. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrlimit)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (prlimit64), + SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */, + SCMP_A2_64 (SCMP_CMP_EQ, 0) /* new_limit == NULL */); + + /* Block changing resource limits, but don't crash. */ + RULE (SCMP_ACT_ERRNO (EPERM), SCMP_SYS (prlimit64), + SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */, + SCMP_A2_64 (SCMP_CMP_NE, 0) /* new_limit != NULL */); + + /* Emacs installs signal handlers, which is harmless. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaction)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigaction)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigprocmask)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigprocmask)); + + /* Allow timer support. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (timer_create)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (timerfd_create)); + + /* Allow thread creation. See the NOTES section in the manual page + for the `clone' function. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone), + SCMP_A0_64 (SCMP_CMP_MASKED_EQ, + /* Flags needed to create threads. See + create_thread in libc. */ + ~(CLONE_VM | CLONE_FS | CLONE_FILES + | CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_THREAD + | CLONE_SETTLS | CLONE_PARENT_SETTID + | CLONE_CHILD_CLEARTID), + 0)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list)); + + /* Allow setting the process name for new threads. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl), + SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NAME)); + + /* Allow some event handling functions used by glib. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (wait4)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (poll)); + + /* Don't allow creating sockets (network access would be extremely + dangerous), but also don't crash. */ + RULE (SCMP_ACT_ERRNO (EACCES), SCMP_SYS (socket)); + + EXPORT_FILTER (argv[1], seccomp_export_bpf); + EXPORT_FILTER (argv[2], seccomp_export_pfc); +} diff --git a/test/Makefile.in b/test/Makefile.in index ba354289e28..91a8ea141c3 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -276,6 +276,8 @@ $(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c endif +src/emacs-tests.log: ../lib-src/seccomp-filter.c + ## Check that there is no 'automated' subdirectory, which would ## indicate an incomplete merge from an older version of Emacs where ## the tests were arranged differently. diff --git a/test/src/emacs-resources/seccomp-filter.bpf b/test/src/emacs-resources/seccomp-filter.bpf new file mode 120000 index 00000000000..b3d603d0aeb --- /dev/null +++ b/test/src/emacs-resources/seccomp-filter.bpf @@ -0,0 +1 @@ +../../../lib-src/seccomp-filter.bpf \ No newline at end of file diff --git a/test/src/emacs-tests.el b/test/src/emacs-tests.el index 7618a9c6752..89d811f8b4e 100644 --- a/test/src/emacs-tests.el +++ b/test/src/emacs-tests.el @@ -25,7 +25,9 @@ (require 'cl-lib) (require 'ert) +(require 'ert-x) (require 'rx) +(require 'subr-x) (ert-deftest emacs-tests/seccomp/absent-file () (skip-unless (string-match-p (rx bow "SECCOMP" eow) @@ -128,4 +130,51 @@ to `make-temp-file', which see." (concat "--seccomp=" filter)) 0))))) +(ert-deftest emacs-tests/seccomp/allows-stdout () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (filter (ert-resource-file "seccomp-filter.bpf")) + (process-environment nil)) + (skip-unless (file-executable-p emacs)) + (skip-unless (file-readable-p filter)) + ;; The --seccomp option is processed early, without filename + ;; handlers. Therefore remote or quoted filenames wouldn't work. + (should-not (file-remote-p filter)) + (cl-callf file-name-unquote filter) + (with-temp-buffer + (let ((status (call-process + emacs nil t nil + "--quick" "--batch" + (concat "--seccomp=" filter) + (format "--eval=%S" '(message "Hi"))))) + (ert-info ((format "Process output: %s" (buffer-string))) + (should (eql status 0))) + (should (equal (string-trim (buffer-string)) "Hi")))))) + +(ert-deftest emacs-tests/seccomp/forbids-subprocess () + (skip-unless (string-match-p (rx bow "SECCOMP" eow) + system-configuration-features)) + (let ((emacs + (expand-file-name invocation-name invocation-directory)) + (filter (ert-resource-file "seccomp-filter.bpf")) + (process-environment nil)) + (skip-unless (file-executable-p emacs)) + (skip-unless (file-readable-p filter)) + ;; The --seccomp option is processed early, without filename + ;; handlers. Therefore remote or quoted filenames wouldn't work. + (should-not (file-remote-p filter)) + (cl-callf file-name-unquote filter) + (with-temp-buffer + (let ((status + (call-process + emacs nil t nil + "--quick" "--batch" + (concat "--seccomp=" filter) + (format "--eval=%S" `(call-process ,emacs nil nil nil + "--version"))))) + (ert-info ((format "Process output: %s" (buffer-string))) + (should-not (eql status 0))))))) + ;;; emacs-tests.el ends here -- cgit v1.2.3 From 25937821bc445235d984c4db8cb18dfbacd6a4ff Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 11 Apr 2021 12:00:35 +0200 Subject: Also check for needed seccomp macros. It looks like these are not available on some versions of GNU/Linux, breaking the build. * configure.ac: Also check for needed seccomp macros. * src/emacs.c (SECCOMP_USABLE): New macro. (usage_message, main, standard_args): Use it. --- configure.ac | 10 +++++++++- src/emacs.c | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0c4772a2b96..be623c96548 100644 --- a/configure.ac +++ b/configure.ac @@ -4179,7 +4179,15 @@ fi AC_SUBST([BLESSMAIL_TARGET]) AC_SUBST([LIBS_MAIL]) -AC_CHECK_HEADERS([linux/seccomp.h], [HAVE_SECCOMP=yes]) +HAVE_SECCOMP=no +AC_CHECK_HEADERS( + [linux/seccomp.h], + [AC_CHECK_DECLS( + [SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC], + [HAVE_SECCOMP=yes], [], + [[ + #include + ]])]) LIBSECCOMP= AC_CHECK_HEADER([seccomp.h], diff --git a/src/emacs.c b/src/emacs.c index 9d7b21cc76a..bd01d7bb461 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -61,7 +61,15 @@ along with GNU Emacs. If not, see . */ # include #endif -#ifdef HAVE_LINUX_SECCOMP_H +#if defined HAVE_LINUX_SECCOMP_H \ + && HAVE_DECL_SECCOMP_SET_MODE_FILTER \ + && HAVE_DECL_SECCOMP_FILTER_FLAG_TSYNC +# define SECCOMP_USABLE 1 +#else +# define SECCOMP_USABLE 0 +#endif + +#if SECCOMP_USABLE # include # include # include @@ -248,7 +256,7 @@ Initialization options:\n\ --dump-file FILE read dumped state from FILE\n\ ", #endif -#ifdef HAVE_LINUX_SECCOMP_H +#if SECCOMP_USABLE "\ --sandbox=FILE read Seccomp BPF filter from FILE\n\ " @@ -950,7 +958,7 @@ load_pdump (int argc, char **argv) } #endif /* HAVE_PDUMPER */ -#ifdef HAVE_LINUX_SECCOMP_H +#if SECCOMP_USABLE /* Wrapper function for the `seccomp' system call on GNU/Linux. This system call usually doesn't have a wrapper function. See the @@ -1123,7 +1131,7 @@ maybe_load_seccomp (int argc, char **argv) fatal ("cannot enable seccomp filter from %s", file); } -#endif /* HAVE_LINUX_SECCOMP_H */ +#endif /* SECCOMP_USABLE */ int main (int argc, char **argv) @@ -1135,7 +1143,7 @@ main (int argc, char **argv) /* First, check whether we should apply a seccomp filter. This should come at the very beginning to allow the filter to protect the initialization phase. */ -#ifdef HAVE_LINUX_SECCOMP_H +#if SECCOMP_USABLE maybe_load_seccomp (argc, argv); #endif @@ -2333,7 +2341,7 @@ static const struct standard_args standard_args[] = #ifdef HAVE_PDUMPER { "-dump-file", "--dump-file", 1, 1 }, #endif -#ifdef HAVE_LINUX_SECCOMP_H +#if SECCOMP_USABLE { "-seccomp", "--seccomp", 1, 1 }, #endif #ifdef HAVE_NS -- cgit v1.2.3 From 0334fa0532e63f22486b5142fa399decf54b18c0 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 11 Apr 2021 12:26:13 +0200 Subject: Add another check for the required header . * configure.ac: Also check for . * src/emacs.c (SECCOMP_USABLE): Also check for . --- configure.ac | 2 +- src/emacs.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index be623c96548..cb4a9ab2876 100644 --- a/configure.ac +++ b/configure.ac @@ -4181,7 +4181,7 @@ AC_SUBST([LIBS_MAIL]) HAVE_SECCOMP=no AC_CHECK_HEADERS( - [linux/seccomp.h], + [linux/seccomp.h linux/filter.h], [AC_CHECK_DECLS( [SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC], [HAVE_SECCOMP=yes], [], diff --git a/src/emacs.c b/src/emacs.c index bd01d7bb461..694d975ec3d 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -61,8 +61,8 @@ along with GNU Emacs. If not, see . */ # include #endif -#if defined HAVE_LINUX_SECCOMP_H \ - && HAVE_DECL_SECCOMP_SET_MODE_FILTER \ +#if defined HAVE_LINUX_SECCOMP_H && defined HAVE_LINUX_FILTER_H \ + && HAVE_DECL_SECCOMP_SET_MODE_FILTER \ && HAVE_DECL_SECCOMP_FILTER_FLAG_TSYNC # define SECCOMP_USABLE 1 #else -- cgit v1.2.3 From 725fc96b706c57ef8ceca5e7d82b175d9a72e845 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 11 Apr 2021 16:50:29 +0200 Subject: Use pkg-config to check for libseccomp. We need at list version 2.4.0 of libseccomp for seccomp-filter.c to build cleanly. * configure.ac: Use pkg-config to check for libseccomp. * lib-src/Makefile.in (HAVE_LIBSECCOMP, LIBSECCOMP_LIBS) (LIBSECCOMP_CFLAGS): New variables. (SECCOMP_FILTER, seccomp-filter$(EXEEXT)): Use them. --- configure.ac | 8 ++++---- lib-src/Makefile.in | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index cb4a9ab2876..681c25b052c 100644 --- a/configure.ac +++ b/configure.ac @@ -4189,10 +4189,10 @@ AC_CHECK_HEADERS( #include ]])]) -LIBSECCOMP= -AC_CHECK_HEADER([seccomp.h], - [AC_CHECK_LIB([seccomp], [seccomp_init], [LIBSECCOMP=-lseccomp])]) -AC_SUBST([LIBSECCOMP]) +EMACS_CHECK_MODULES([LIBSECCOMP], [libseccomp >= 2.4.0]) +AC_SUBST([HAVE_LIBSECCOMP]) +AC_SUBST([LIBSECCOMP_LIBS]) +AC_SUBST([LIBSECCOMP_CFLAGS]) OLD_LIBS=$LIBS LIBS="$LIB_PTHREAD $LIB_MATH $LIBS" diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 5870286cd5c..b4143b33554 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -189,10 +189,12 @@ LIB_WSOCK32=@LIB_WSOCK32@ ## Extra libraries for etags LIBS_ETAGS = $(LIB_CLOCK_GETTIME) $(LIB_GETRANDOM) -LIBSECCOMP=@LIBSECCOMP@ +HAVE_LIBSECCOMP=@HAVE_LIBSECCOMP@ +LIBSECCOMP_LIBS=@LIBSECCOMP_LIBS@ +LIBSECCOMP_CFLAGS=@LIBSECCOMP_CFLAGS@ # Currently, we can only generate seccomp filter files for x86-64. -ifneq ($(LIBSECCOMP),) +ifeq ($(HAVE_LIBSECCOMP),yes) ifeq ($(shell uname -m),x86_64) SECCOMP_FILTER=1 endif @@ -419,7 +421,8 @@ emacsclient.res: ../nt/emacsclient.rc $(NTINC)/../icons/emacs.ico ifeq ($(SECCOMP_FILTER),1) seccomp-filter$(EXEEXT): $(srcdir)/seccomp-filter.c $(config_h) - $(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $< $(LIBSECCOMP) -o $@ + $(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $(LIBSECCOMP_CFLAGS) $< \ + $(LIBSECCOMP_LIBS) -o $@ seccomp-filter.bpf seccomp-filter.pfc: seccomp-filter$(EXEEXT) $(AM_V_GEN)./seccomp-filter$(EXEEXT) \ -- cgit v1.2.3 From 751e801f90339480ea43fc2237fc45c8eb39bd6f Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 11 Apr 2021 17:23:22 +0200 Subject: Fix check for timer_getoverrun * configure.ac (timer_getoverrun): Move check after gnulib checks and use $LIB_TIMER_TIME during check. --- configure.ac | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 681c25b052c..169ffc55341 100644 --- a/configure.ac +++ b/configure.ac @@ -4201,7 +4201,7 @@ getrusage get_current_dir_name \ lrand48 random rint trunc \ select getpagesize setlocale newlocale \ getrlimit setrlimit shutdown \ -pthread_sigmask strsignal setitimer timer_getoverrun \ +pthread_sigmask strsignal setitimer \ sendto recvfrom getsockname getifaddrs freeifaddrs \ gai_strerror sync \ getpwent endpwent getgrent endgrent \ @@ -5498,6 +5498,12 @@ gl_INIT CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS +# timer_getoverrun needs the same libarary as timer_settime +OLD_LIBS=$LIBS +LIBS="$LIB_TIMER_TIME $LIBS" +AC_CHECK_FUNCS(timer_getoverrun) +LIBS=$OLD_LIBS + if test "${opsys}" = "mingw32"; then CPPFLAGS="$CPPFLAGS -DUSE_CRT_DLL=1 -I \${abs_top_srcdir}/nt/inc" # Remove unneeded switches from the value of CC that goes to Makefiles -- cgit v1.2.3 From 17d20bb3cbb233ed0d94c3f1f9f3db768f526223 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Mon, 12 Apr 2021 09:15:59 +0200 Subject: Generate Seccomp filters only if we have the necessary constants. If we're missing SECCOMP_SET_MODE_FILTER, the seccomp-filter build fails. Reuse the existing HAVE_SECCOMP configuration variable, which checks for these macros. * configure.ac (HAVE_SECCOMP): Substitute in Makefile.in. * lib-src/Makefile.in (HAVE_SECCOMP): New variable. (SECCOMP_FILTER): Define only if HAVE_SECCOMP. --- configure.ac | 1 + lib-src/Makefile.in | 3 +++ 2 files changed, 4 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 169ffc55341..d3647bdc2a2 100644 --- a/configure.ac +++ b/configure.ac @@ -4188,6 +4188,7 @@ AC_CHECK_HEADERS( [[ #include ]])]) +AC_SUBST([HAVE_SECCOMP]) EMACS_CHECK_MODULES([LIBSECCOMP], [libseccomp >= 2.4.0]) AC_SUBST([HAVE_LIBSECCOMP]) diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 091f4fb0199..923d0cf5e72 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -189,11 +189,13 @@ LIB_WSOCK32=@LIB_WSOCK32@ ## Extra libraries for etags LIBS_ETAGS = $(LIB_CLOCK_GETTIME) $(LIB_GETRANDOM) +HAVE_SECCOMP=@HAVE_SECCOMP@ HAVE_LIBSECCOMP=@HAVE_LIBSECCOMP@ LIBSECCOMP_LIBS=@LIBSECCOMP_LIBS@ LIBSECCOMP_CFLAGS=@LIBSECCOMP_CFLAGS@ # Currently, we can only generate seccomp filter files for x86-64. +ifeq ($(HAVE_SECCOMP),yes) ifeq ($(HAVE_LIBSECCOMP),yes) ifeq ($(shell uname -m),x86_64) # We require SECCOMP_RET_KILL_PROCESS, which is only available in @@ -205,6 +207,7 @@ SECCOMP_FILTER=1 endif endif endif +endif ifeq ($(SECCOMP_FILTER),1) DONT_INSTALL += seccomp-filter$(EXEEXT) -- cgit v1.2.3 From bfaa6df492c85d7de007cf69316cbdeea653d703 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 14 Apr 2021 20:00:04 +0200 Subject: * configure.ac: Fix native-comp FreeBSD build. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index a47871fbd89..0e91a49488c 100644 --- a/configure.ac +++ b/configure.ac @@ -3826,7 +3826,7 @@ if test "${with_native_compilation}" != "no"; then # mingw32 loads the library dynamically. mingw32) ;; # OpenBSD doesn't have libdl, all the functions are in libc - openbsd) + freebsd|openbsd) LIBGCCJIT_LIB="-lgccjit" ;; *) LIBGCCJIT_LIB="-lgccjit -ldl" ;; -- cgit v1.2.3 From 686259e65aa7121683c0c65e45ce48adb08ddb58 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 14 Apr 2021 23:58:23 +0200 Subject: * configure.ac: Revert prev commit and fix native-comp NetBSD build. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0e91a49488c..3298032311f 100644 --- a/configure.ac +++ b/configure.ac @@ -3826,7 +3826,7 @@ if test "${with_native_compilation}" != "no"; then # mingw32 loads the library dynamically. mingw32) ;; # OpenBSD doesn't have libdl, all the functions are in libc - freebsd|openbsd) + netbsd|openbsd) LIBGCCJIT_LIB="-lgccjit" ;; *) LIBGCCJIT_LIB="-lgccjit -ldl" ;; -- cgit v1.2.3 From 61828e55a823640870637c471bc7d62ed1e001a6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 22 Apr 2021 20:23:23 +0300 Subject: Fix MS-Windows link switches for unexec * configure.ac (LD_SWITCH_SYSTEM_TEMACS) [mingw32]: Disable ASLR when linking for unexec. Reported by Nikolay Kudryavtsev . --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index d3647bdc2a2..7179fbe415f 100644 --- a/configure.ac +++ b/configure.ac @@ -5560,6 +5560,10 @@ case "$opsys" in x86_64-*-*) LD_SWITCH_SYSTEM_TEMACS="-Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x400000000 -Wl,-entry,__start -Wl,-Map,./temacs.map" ;; *) LD_SWITCH_SYSTEM_TEMACS="-Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x01000000 -Wl,-entry,__start -Wl,-Map,./temacs.map" ;; esac + ## If they want unexec, disable Windows ASLR for the Emacs binary + if test "$with_dumping" = "unexec"; then + LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase -Wl,-disable-high-entropy-va -Wl,-default-image-base-low" + fi ;; *) LD_SWITCH_SYSTEM_TEMACS= ;; -- cgit v1.2.3 From 9904aaebf7cf04fe8544417158250575a4be9d18 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 22 Apr 2021 22:11:08 +0300 Subject: ; * configure.ac (LD_SWITCH_SYSTEM_TEMACS) [mingw32]: Fix last change. --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 7179fbe415f..a1629d73ab9 100644 --- a/configure.ac +++ b/configure.ac @@ -5562,7 +5562,10 @@ case "$opsys" in esac ## If they want unexec, disable Windows ASLR for the Emacs binary if test "$with_dumping" = "unexec"; then - LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase -Wl,-disable-high-entropy-va -Wl,-default-image-base-low" + case "$canonical" in + x86_64-*-*) LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase -Wl,-disable-high-entropy-va -Wl,-default-image-base-low" ;; + *) LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase" ;; + esac fi ;; -- cgit v1.2.3 From 5e1a8d5654d97d2631ad67ebb88be4d2eec7d408 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 19 May 2021 17:42:50 +0300 Subject: Fix the unexec build on GNU/Linux The unexec build on GNU/Linux must use HYBRID_MALLOC (gmalloc.c) and sheap.c. This was inadvertently disabled because a configure-time test for 'sbrk' was moved as side effect of an unrelated change. * configure.ac: Test for 'sbrk' before using the result in the decision about SYSTEM_MALLOC and HYBRID_MALLOC. (HYBRID_MALLOC): Prevent Gnulib from redirecting 'free' to its replacement 'rpl_free'. * lib/Makefile.in (not_emacs_OBJECTS): Add mallooc/%.o and free.o. --- configure.ac | 8 +++++++- lib/Makefile.in | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 3df4359fa72..d35ac6dbd37 100644 --- a/configure.ac +++ b/configure.ac @@ -2273,6 +2273,9 @@ doug_lea_malloc=$emacs_cv_var_doug_lea_malloc hybrid_malloc= system_malloc=yes +dnl This must be before the test of $ac_cv_func_sbrk below. +AC_CHECK_FUNCS_ONCE([sbrk]) + test $with_unexec = yes && case "$opsys" in ## darwin ld insists on the use of malloc routines in the System framework. @@ -2306,6 +2309,9 @@ elif test "$hybrid_malloc" = yes; then GNU_MALLOC_reason=" (only before dumping)" GMALLOC_OBJ=gmalloc.o VMLIMIT_OBJ= + # FIXME: This is to prevent Gnulib from redirecting 'free' to its + # replacement, instead of 'hybrid_free' in gmalloc.c. + gl_cv_func_free_preserves_errno=yes else test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o VMLIMIT_OBJ=vm-limit.o @@ -4677,7 +4683,7 @@ AC_CHECK_HEADERS(valgrind/valgrind.h) AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include ]]) -AC_CHECK_FUNCS_ONCE([__lsan_ignore_object sbrk]) +AC_CHECK_FUNCS_ONCE([__lsan_ignore_object]) AC_FUNC_FORK diff --git a/lib/Makefile.in b/lib/Makefile.in index 6c7a4430999..ec92f92fb3e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -69,7 +69,9 @@ Makefile: ../config.status $(srcdir)/Makefile.in # Object modules that need not be built for Emacs. # Emacs does not need e-regex.o (it has its own regex-emacs.c), # and building it would just waste time. -not_emacs_OBJECTS = regex.o +# Emacs also doesn't need the dynarray-related files in malloc/ and +# the replacement 'free'. +not_emacs_OBJECTS = regex.o malloc/%.o free.o libgnu_a_OBJECTS = fingerprint.o $(gl_LIBOBJS) \ $(patsubst %.c,%.o,$(filter %.c,$(libgnu_a_SOURCES))) -- cgit v1.2.3 From b2eed2ae568b53ac910f4a3b8458eedf8d8c67ec Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 20 May 2021 11:26:00 +0300 Subject: Clean up the fix for unexec build on GNU/Linux * src/conf_post.h [HYBRID_MALLOC || DARWIN_OS && HAVE_UNEXEC]: Include here, before redirecting 'malloc' and friends to their hybrid_* and unexec_* equivalents. #undef malloc and friends before redefining. Provide prototypes for the replacements. Suggested by Paul Eggert . * src/gmalloc.c [HYBRID_MALLOC]: Remove declarations of 'malloc' and friends, as they are now redundant: we include in conf_post.h before redefining 'malloc' etc., and that provides prototypes from system headers. * configure.ac (HYBRID_MALLOC): Remove kludge to avoid replacement of 'free' by Gnulib. (Bug#36649) --- configure.ac | 3 --- src/conf_post.h | 31 ++++++++++++++++++++++++++++++- src/gmalloc.c | 10 ---------- 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index d35ac6dbd37..d99e5395d35 100644 --- a/configure.ac +++ b/configure.ac @@ -2309,9 +2309,6 @@ elif test "$hybrid_malloc" = yes; then GNU_MALLOC_reason=" (only before dumping)" GMALLOC_OBJ=gmalloc.o VMLIMIT_OBJ= - # FIXME: This is to prevent Gnulib from redirecting 'free' to its - # replacement, instead of 'hybrid_free' in gmalloc.c. - gl_cv_func_free_preserves_errno=yes else test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o VMLIMIT_OBJ=vm-limit.o diff --git a/src/conf_post.h b/src/conf_post.h index 176ab28b21a..8558dc466cc 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -99,10 +99,28 @@ typedef bool bool_bf; # define ADDRESS_SANITIZER false #endif +#ifdef emacs +/* We include stdlib.h here, because Gnulib's stdlib.h might redirect + 'free' to its replacement, and we want to avoid that in unexec + builds. Inclduing it here will render its inclusion after config.h + a no-op. */ +# if (defined DARWIN_OS && defined HAVE_UNEXEC) || defined HYBRID_MALLOC +# include +# endif +#endif + #if defined DARWIN_OS && defined emacs && defined HAVE_UNEXEC +# undef malloc # define malloc unexec_malloc +# undef realloc # define realloc unexec_realloc +# undef free # define free unexec_free + +extern void *unexec_malloc (size_t); +extern void *unexec_realloc (void *, size_t); +extern void unexec_free (void *); + #endif /* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use @@ -111,12 +129,23 @@ typedef bool bool_bf; accomplish this. */ #ifdef HYBRID_MALLOC #ifdef emacs +#undef malloc #define malloc hybrid_malloc +#undef realloc #define realloc hybrid_realloc +#undef aligned_alloc #define aligned_alloc hybrid_aligned_alloc +#undef calloc #define calloc hybrid_calloc +#undef free #define free hybrid_free -#endif + +extern void *hybrid_malloc (size_t); +extern void *hybrid_calloc (size_t, size_t); +extern void hybrid_free (void *); +extern void *hybrid_aligned_alloc (size_t, size_t); +extern void *hybrid_realloc (void *, size_t); +#endif /* emacs */ #endif /* HYBRID_MALLOC */ /* We have to go this route, rather than the old hpux9 approach of diff --git a/src/gmalloc.c b/src/gmalloc.c index 66008ea69b2..dedd25fa22f 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c @@ -1690,16 +1690,6 @@ valloc (size_t size) #undef free #ifdef HYBRID_MALLOC -/* Declare system malloc and friends. */ -extern void *malloc (size_t size); -extern void *realloc (void *ptr, size_t size); -extern void *calloc (size_t nmemb, size_t size); -extern void free (void *ptr); -#ifdef HAVE_ALIGNED_ALLOC -extern void *aligned_alloc (size_t alignment, size_t size); -#elif defined HAVE_POSIX_MEMALIGN -extern int posix_memalign (void **memptr, size_t alignment, size_t size); -#endif /* Assuming PTR was allocated via the hybrid malloc, return true if PTR was allocated via gmalloc, not the system malloc. Also, return -- cgit v1.2.3 From 6a152f898dfbc4cd7ece41adf4dc89422262c843 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 3 Jun 2021 09:55:00 +0300 Subject: * configure.ac: Improve error messages about libgccjit. --- configure.ac | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index d99e5395d35..8830e4bed8f 100644 --- a/configure.ac +++ b/configure.ac @@ -3772,27 +3772,26 @@ AC_DEFUN([libgccjit_smoke_test], [ }]])]) AC_DEFUN([libgccjit_not_found], [ - AC_MSG_ERROR([elisp native compiler requested but libgccjit not found. -Please try installing libgccjit or similar package. -If you are sure you want Emacs compiled without elisp native compiler, pass - --without-native-compilation -to configure.])]) + AC_MSG_ERROR([ELisp native compiler was requested, but libgccjit was not found. +Please try installing libgccjit or a similar package. +If you are sure you want Emacs be compiled without ELisp native compiler, +pass the --without-native-compilation option to configure.])]) AC_DEFUN([libgccjit_dev_not_found], [ - AC_MSG_ERROR([elisp native compiler requested but libgccjit header files were + AC_MSG_ERROR([ELisp native compiler was requested, but libgccjit header files were not found. -Please try installing libgccjit-dev or similar package. -If you are sure you want Emacs compiled without elisp native compiler, pass ---without-nativecomp -to configure.])]) +Please try installing libgccjit-dev or a similar package. +If you are sure you want Emacs be compiled without ELisp native compiler, +pass the --without-nativecomp option to configure.])]) AC_DEFUN([libgccjit_broken], [ - AC_MSG_ERROR([Installed libgccjit has failed passing the smoke test. -You can verify it yourself compiling: + AC_MSG_ERROR([The installed libgccjit did not pass the smoke test. +You can verify it yourself by compiling: . Please report the issue to your distribution if libgccjit was installed through that. -Here instructions on how to compile and install libgccjit from source: +You can find the instructions on how to compile and install libgccjit from +source on this site: .])]) HAVE_NATIVE_COMP=no -- cgit v1.2.3 From ed19ffc346282e6d4dc63bcc90dd4d25910c6b6c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 3 Jun 2021 10:46:54 +0300 Subject: * configure.ac: Clarify "smoke test" error message. (Bug#48804) --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 8830e4bed8f..fc00d980acc 100644 --- a/configure.ac +++ b/configure.ac @@ -3785,9 +3785,11 @@ If you are sure you want Emacs be compiled without ELisp native compiler, pass the --without-nativecomp option to configure.])]) AC_DEFUN([libgccjit_broken], [ - AC_MSG_ERROR([The installed libgccjit did not pass the smoke test. -You can verify it yourself by compiling: + AC_MSG_ERROR([The installed libgccjit failed to compile and run a test program using +the libgccjit library; see config.log for the details of the failure. +The test program can be found here: . +You can try compiling it yourself to investigate the issues. Please report the issue to your distribution if libgccjit was installed through that. You can find the instructions on how to compile and install libgccjit from -- cgit v1.2.3 From 3272cfa8d498dee9c449b1782cbe1a40ba85ba20 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 3 Jun 2021 10:49:09 +0300 Subject: ; Fix last change. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index fc00d980acc..c828f8d7828 100644 --- a/configure.ac +++ b/configure.ac @@ -3790,8 +3790,8 @@ the libgccjit library; see config.log for the details of the failure. The test program can be found here: . You can try compiling it yourself to investigate the issues. -Please report the issue to your distribution if libgccjit was installed through -that. +Please report the issue to your distribution if libgccjit was installed +through that. You can find the instructions on how to compile and install libgccjit from source on this site: .])]) -- cgit v1.2.3 From 57ec4aadc65389f6df5a173cfbff0a551b3ee25d Mon Sep 17 00:00:00 2001 From: Peter Oliver Date: Tue, 22 Jun 2021 15:17:28 +0200 Subject: Advertise support for Startup Notification when built with GTK * etc/emacsclient.desktop, etc/emacsclient.desktop: Specify StartupNotify=true. * configure.ac (USE_STARTUP_NOTIFICATION): New variable, yes iff HAVE_GTK. * Makefile.in (install-etc): Remove StartupNotify=true from etc/*.desktop unless USE_STARTUP_NOTIFICATION (bug#48783). --- Makefile.in | 7 +++++++ configure.ac | 5 +++++ etc/NEWS | 6 ++++++ etc/emacs.desktop | 1 + etc/emacsclient.desktop | 1 + 5 files changed, 20 insertions(+) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index 474441fa93c..b7502880230 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,6 +100,8 @@ FIND_DELETE = @FIND_DELETE@ HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@ +USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@ + # ==================== Where To Install Things ==================== # Location to install Emacs.app under GNUstep / macOS. @@ -706,11 +708,15 @@ install-man: ## Note: emacs22 does not have all the resolutions. EMACS_ICON=emacs +ifeq (${USE_STARTUP_NOTIFICATION},no) +USE_STARTUP_NOTIFICATION_SED_CMD=-e "/^StartupNotify=true$$/d" +endif install-etc: umask 022; ${MKDIR_P} "$(DESTDIR)${desktopdir}" tmp=etc/emacs.tmpdesktop; rm -f $${tmp}; \ sed -e "/^Exec=emacs/ s/emacs/${EMACS_NAME}/" \ -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \ + $(USE_STARTUP_NOTIFICATION_SED_CMD) \ ${srcdir}/etc/emacs.desktop > $${tmp}; \ ${INSTALL_DATA} $${tmp} "$(DESTDIR)${desktopdir}/${EMACS_NAME}.desktop"; \ rm -f $${tmp} @@ -718,6 +724,7 @@ install-etc: client_name=`echo emacsclient | sed '$(TRANSFORM)'`${EXEEXT}; \ sed -e "/^Exec=emacsclient/ s|emacsclient|${bindir}/$${client_name}|" \ -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \ + $(USE_STARTUP_NOTIFICATION_SED_CMD) \ ${srcdir}/etc/emacsclient.desktop > $${tmp}; \ ${INSTALL_DATA} $${tmp} "$(DESTDIR)${desktopdir}/$${client_name}.desktop"; \ rm -f $${tmp} diff --git a/configure.ac b/configure.ac index c828f8d7828..830f33844b6 100644 --- a/configure.ac +++ b/configure.ac @@ -2892,6 +2892,11 @@ fi AC_SUBST(SETTINGS_CFLAGS) AC_SUBST(SETTINGS_LIBS) +USE_STARTUP_NOTIFICATION=no +if test "${HAVE_GTK}" = "yes"; then + USE_STARTUP_NOTIFICATION=yes +fi +AC_SUBST(USE_STARTUP_NOTIFICATION) dnl SELinux is available for GNU/Linux only. HAVE_LIBSELINUX=no diff --git a/etc/NEWS b/etc/NEWS index 3c7d5ca10be..40c7c931624 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -91,6 +91,12 @@ proper pty support that Emacs needs. * Startup Changes in Emacs 28.1 +--- +** In GTK builds, Emacs now supports startup notification. +This means that Emacs won't steal keyboard focus upon startup +(when started via the Desktop) if the user is typing into another +application. + ** Emacs can support 24-bit color TTY without terminfo database. If your text-mode terminal supports 24-bit true color, but your system lacks the terminfo database, you can instruct Emacs to support 24-bit diff --git a/etc/emacs.desktop b/etc/emacs.desktop index 2e6496e58c9..81c53c6121d 100644 --- a/etc/emacs.desktop +++ b/etc/emacs.desktop @@ -8,5 +8,6 @@ Icon=emacs Type=Application Terminal=false Categories=Development;TextEditor; +StartupNotify=true StartupWMClass=Emacs Keywords=Text;Editor; diff --git a/etc/emacsclient.desktop b/etc/emacsclient.desktop index 3feb83c7290..2c1edb4b66a 100644 --- a/etc/emacsclient.desktop +++ b/etc/emacsclient.desktop @@ -8,5 +8,6 @@ Icon=emacs Type=Application Terminal=false Categories=Development;TextEditor; +StartupNotify=true StartupWMClass=Emacsd Keywords=Text;Editor; -- cgit v1.2.3 From 5dd2d50f3d5e65b85c87da86e2e8a6d087fe5767 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 16 Jun 2021 21:28:10 +0100 Subject: Fix NS native compilation builds * Makefile.in (ns_applibexecdir): (ns_applibdir): (ns_appdir): New variables. (.PHONY): Include new rule. (epaths-force-ns-self-contained): Remove the app bundle directory from all paths. * configure.ac (NS_SELF_CONTAINED): Set the default site-lisp directory instead of hard-coding it in the ObjC code, and use the new epaths generating make rule. * src/callproc.c (init_callproc_1): (init_callproc): Remove all the NS specific code as the special cases are now handled by decode_env_path. * src/emacs.c (load_pdump): (decode_env_path): Use ns_relocate to find the correct directory after relocation. * src/lread.c (load_path_default): Remove all the NS specific code as the special cases are now handled by decode_env_path. * src/nsterm.h: Update function definitions. * src/nsterm.m (ns_etc_directory): (ns_exec_path): (ns_load_path): Remove functions that are no longer needed. (ns_relocate): New function to calculate paths within the NS app bundle. * nextstep/Makefile.in (ns_applibexecdir): New variable, and update anything relying on the libexec location. --- Makefile.in | 18 +++++++- configure.ac | 19 +++++--- nextstep/Makefile.in | 12 ++--- src/Makefile.in | 2 +- src/callproc.c | 36 ++------------- src/emacs.c | 16 ++++++- src/lread.c | 7 +-- src/nsterm.h | 4 +- src/nsterm.m | 125 +++++++++------------------------------------------ 9 files changed, 80 insertions(+), 159 deletions(-) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index b7502880230..420cb544a4d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -106,8 +106,11 @@ USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@ # Location to install Emacs.app under GNUstep / macOS. # Later values may use these. +ns_appdir=@ns_appdir@ ns_appbindir=@ns_appbindir@ +ns_applibexecdir=@ns_applibexecdir@ ns_appresdir=@ns_appresdir@ +ns_applibdir=@ns_applibdir@ # Either yes or no depending on whether this is a relocatable Emacs.app. ns_self_contained=@ns_self_contained@ @@ -330,12 +333,12 @@ BIN_DESTDIR='$(DESTDIR)${bindir}/' ELN_DESTDIR = $(DESTDIR)${libdir}/emacs/${version}/ else BIN_DESTDIR='${ns_appbindir}/' -ELN_DESTDIR = ${ns_appresdir}/ +ELN_DESTDIR = ${ns_applibdir}/emacs/${version}/ endif all: ${SUBDIR} info -.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver +.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 epaths-force-ns-self-contained etc-emacsver # If configure were to just generate emacsver.tex from emacsver.tex.in # in the normal way, the timestamp of emacsver.tex would always be @@ -404,6 +407,17 @@ epaths-force-w32: -e "/^.*#/s|@SRC@|$${w32srcdir}|g") && \ ${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h +# A NextStep style app bundle is relocatable, so instead of +# hard-coding paths try to generate them at run-time. +# +# The paths are mostly the same, and the bundle paths are different +# between macOS and GNUstep, so just replace any references to the app +# bundle root itself with the relative path. +epaths-force-ns-self-contained: epaths-force + @(sed < ${srcdir}/src/epaths.h > epaths.h.$$$$ \ + -e 's;${ns_appdir}/;;') && \ + ${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h + lib-src src: $(NTDIR) lib src: lib-src diff --git a/configure.ac b/configure.ac index 830f33844b6..92527056b95 100644 --- a/configure.ac +++ b/configure.ac @@ -1891,10 +1891,11 @@ if test "${with_ns}" != no; then # so avoid NS_IMPL_COCOA if macuvs.h is absent. # Even a headless Emacs can build macuvs.h, so this should let you bootstrap. if test "${opsys}" = darwin && test -f "$srcdir/src/macuvs.h"; then - lispdirrel=Contents/Resources/lisp NS_IMPL_COCOA=yes ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir}/Contents/MacOS + ns_applibexecdir=${ns_appdir}/Contents/MacOS/libexec + ns_applibdir=${ns_appdir}/Contents/MacOS/lib ns_appresdir=${ns_appdir}/Contents/Resources ns_appsrc=Cocoa/Emacs.base ns_fontfile=macfont.o @@ -1952,6 +1953,8 @@ fail; if test $NS_IMPL_GNUSTEP = yes; then ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir} + ns_applibexecdir=${ns_appdir}/libexec + ns_applibdir=${ns_appdir}/lib ns_appresdir=${ns_appdir}/Resources ns_appsrc=GNUstep/Emacs.base ns_fontfile=nsfont.o @@ -2008,12 +2011,13 @@ if test "${HAVE_NS}" = yes; then window_system=nextstep # set up packaging dirs if test "${EN_NS_SELF_CONTAINED}" = yes; then + AC_DEFINE(NS_SELF_CONTAINED, 1, [Build an NS bundled app]) ns_self_contained=yes prefix=${ns_appresdir} exec_prefix=${ns_appbindir} dnl This one isn't really used, only archlibdir is. - libexecdir="\${ns_appbindir}/libexec" - archlibdir="\${ns_appbindir}/libexec" + libexecdir="\${ns_applibexecdir}" + archlibdir="\${ns_applibexecdir}" etcdocdir="\${ns_appresdir}/etc" etcdir="\${ns_appresdir}/etc" dnl FIXME maybe set datarootdir instead. @@ -2021,7 +2025,7 @@ if test "${HAVE_NS}" = yes; then infodir="\${ns_appresdir}/info" mandir="\${ns_appresdir}/man" lispdir="\${ns_appresdir}/lisp" - test "$locallisppathset" = no && locallisppath="" + test "$locallisppathset" = no && locallisppath="\${ns_appresdir}/site-lisp" INSTALL_ARCH_INDEP_EXTRA= fi @@ -5414,6 +5418,8 @@ AC_SUBST(CFLAGS) AC_SUBST(X_TOOLKIT_TYPE) AC_SUBST(ns_appdir) AC_SUBST(ns_appbindir) +AC_SUBST(ns_applibexecdir) +AC_SUBST(ns_applibdir) AC_SUBST(ns_appresdir) AC_SUBST(ns_appsrc) AC_SUBST(GNU_OBJC_CFLAGS) @@ -6014,10 +6020,13 @@ dnl the use of force in the 'epaths-force' rule in Makefile.in. AC_CONFIG_COMMANDS([src/epaths.h], [ if test "${opsys}" = "mingw32"; then ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-w32 +elif test "$EN_NS_SELF_CONTAINED" = "yes"; then + ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-ns-self-contained else ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force fi || AC_MSG_ERROR(['src/epaths.h' could not be made.]) -], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys"]) +], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" + EN_NS_SELF_CONTAINED="$EN_NS_SELF_CONTAINED"]) dnl NB we have to cheat and use the ac_... version because abs_top_srcdir dnl is not yet set, sigh. Or we could use ../$srcdir/src/.gdbinit, diff --git a/nextstep/Makefile.in b/nextstep/Makefile.in index 3168fee76c0..42b2ab2715d 100644 --- a/nextstep/Makefile.in +++ b/nextstep/Makefile.in @@ -36,6 +36,7 @@ MKDIR_P = @MKDIR_P@ ns_appdir = @ns_appdir@ ## GNUstep: ns_appdir; macOS: ns_appdir/Contents/MacOS ns_appbindir = @ns_appbindir@ +ns_applibexecdir = @ns_applibexecdir@ ## GNUstep/Emacs.base or Cocoa/Emacs.base. ns_appsrc = @ns_appsrc@ ## GNUstep: GNUstep/Emacs.base/Resources/Info-gnustep.plist @@ -44,7 +45,7 @@ ns_check_file = @ns_appdir@/@ns_check_file@ .PHONY: all -all: ${ns_appdir} ${ns_appbindir}/Emacs ${ns_appbindir}/Emacs.pdmp +all: ${ns_appdir} ${ns_appbindir}/Emacs ${ns_applibexecdir}/Emacs.pdmp ${ns_check_file} ${ns_appdir}: ${srcdir}/${ns_appsrc} ${ns_appsrc} rm -rf ${ns_appdir} @@ -63,8 +64,10 @@ ${ns_appbindir}/Emacs: ${ns_appdir} ${ns_check_file} ../src/emacs${EXEEXT} ${MKDIR_P} ${ns_appbindir} cp -f ../src/emacs${EXEEXT} $@ -${ns_appbindir}/Emacs.pdmp: ${ns_appdir} ${ns_check_file} ../src/emacs${EXEEXT}.pdmp - ${MKDIR_P} ${ns_appbindir} +# FIXME: Don't install the dump file into the app bundle when +# self-contained install is disabled. +${ns_applibexecdir}/Emacs.pdmp: ${ns_appdir} ${ns_check_file} ../src/emacs${EXEEXT}.pdmp + ${MKDIR_P} ${ns_applibexecdir} cp -f ../src/emacs${EXEEXT}.pdmp $@ .PHONY: FORCE @@ -85,9 +88,8 @@ links: ../src/emacs${EXEEXT} ln -s $(top_srcdir_abs)/info ${ns_appdir}/Contents/Resources ${MKDIR_P} ${ns_appbindir} ln -s $(abs_top_builddir)/src/emacs${EXEEXT} ${ns_appbindir}/Emacs - ln -s $(abs_top_builddir)/src/emacs${EXEEXT}.pdmp ${ns_appbindir}/Emacs.pdmp ln -s $(abs_top_builddir)/lib-src ${ns_appbindir}/bin - ln -s $(abs_top_builddir)/lib-src ${ns_appbindir}/libexec + ln -s $(abs_top_builddir)/lib-src ${ns_applibexecdir} ${MKDIR_P} ${ns_appdir}/Contents/Resources/etc for f in $(shell cd $(top_srcdir_abs)/etc; ls); do ln -s $(top_srcdir_abs)/etc/$$f ${ns_appdir}/Contents/Resources/etc; done ln -s $(abs_top_builddir)/etc/DOC ${ns_appdir}/Contents/Resources/etc diff --git a/src/Makefile.in b/src/Makefile.in index 79cddb35b55..22c7aeed5c6 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -55,7 +55,7 @@ lwlibdir = ../lwlib # Configuration files for .o files to depend on. config_h = config.h $(srcdir)/conf_post.h -## ns-app if HAVE_NS, else empty. +## ns-app if NS self contained app, else empty. OTHER_FILES = @OTHER_FILES@ ## Flags to pass for profiling builds diff --git a/src/callproc.c b/src/callproc.c index e44e243680d..aabc39313b8 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1661,32 +1661,15 @@ make_environment_block (Lisp_Object current_dir) void init_callproc_1 (void) { -#ifdef HAVE_NS - const char *etc_dir = ns_etc_directory (); - const char *path_exec = ns_exec_path (); -#endif - - Vdata_directory = decode_env_path ("EMACSDATA", -#ifdef HAVE_NS - etc_dir ? etc_dir : -#endif - PATH_DATA, 0); + Vdata_directory = decode_env_path ("EMACSDATA", PATH_DATA, 0); Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory)); - Vdoc_directory = decode_env_path ("EMACSDOC", -#ifdef HAVE_NS - etc_dir ? etc_dir : -#endif - PATH_DOC, 0); + Vdoc_directory = decode_env_path ("EMACSDOC", PATH_DOC, 0); Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory)); /* Check the EMACSPATH environment variable, defaulting to the PATH_EXEC path from epaths.h. */ - Vexec_path = decode_env_path ("EMACSPATH", -#ifdef HAVE_NS - path_exec ? path_exec : -#endif - PATH_EXEC, 0); + Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0); Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); /* FIXME? For ns, path_exec should go at the front? */ Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); @@ -1701,10 +1684,6 @@ init_callproc (void) char *sh; Lisp_Object tempdir; -#ifdef HAVE_NS - if (data_dir == 0) - data_dir = ns_etc_directory () != 0; -#endif if (!NILP (Vinstallation_directory)) { @@ -1716,15 +1695,8 @@ init_callproc (void) /* MSDOS uses wrapped binaries, so don't do this. */ if (NILP (Fmember (tem, Vexec_path))) { -#ifdef HAVE_NS - const char *path_exec = ns_exec_path (); -#endif /* Running uninstalled, so default to tem rather than PATH_EXEC. */ - Vexec_path = decode_env_path ("EMACSPATH", -#ifdef HAVE_NS - path_exec ? path_exec : -#endif - SSDATA (tem), 0); + Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0); Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); } diff --git a/src/emacs.c b/src/emacs.c index 60a57a693ce..b7982ece646 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -835,7 +835,13 @@ load_pdump (int argc, char **argv) NULL #endif ; - const char *argv0_base = "emacs"; + const char *argv0_base = +#ifdef NS_SELF_CONTAINED + "Emacs" +#else + "emacs" +#endif + ; /* TODO: maybe more thoroughly scrub process environment in order to make this use case (loading a dump file in an unexeced emacs) @@ -912,6 +918,8 @@ load_pdump (int argc, char **argv) /* On MS-Windows, PATH_EXEC normally starts with a literal "%emacs_dir%", so it will never work without some tweaking. */ path_exec = w32_relocate (path_exec); +#elif defined (HAVE_NS) + path_exec = ns_relocate (path_exec); #endif /* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in @@ -929,6 +937,7 @@ load_pdump (int argc, char **argv) } sprintf (dump_file, "%s%c%s%s", path_exec, DIRECTORY_SEP, argv0_base, suffix); +#if !defined (NS_SELF_CONTAINED) /* Assume the Emacs binary lives in a sibling directory as set up by the default installation configuration. */ const char *go_up = "../../../../bin/"; @@ -943,6 +952,7 @@ load_pdump (int argc, char **argv) sprintf (emacs_executable, "%s%c%s%s%s", path_exec, DIRECTORY_SEP, go_up, argv0_base, strip_suffix ? strip_suffix : ""); +#endif result = pdumper_load (dump_file, emacs_executable); if (result == PDUMPER_LOAD_FILE_NOT_FOUND) @@ -2960,7 +2970,11 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) path = 0; if (!path) { +#ifdef NS_SELF_CONTAINED + path = ns_relocate (defalt); +#else path = defalt; +#endif #ifdef WINDOWSNT defaulted = 1; #endif diff --git a/src/lread.c b/src/lread.c index 0b33fd0f254..4617ffd6265 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4769,14 +4769,9 @@ load_path_default (void) return decode_env_path (0, PATH_DUMPLOADSEARCH, 0); Lisp_Object lpath = Qnil; - const char *normal = PATH_LOADSEARCH; const char *loadpath = NULL; -#ifdef HAVE_NS - loadpath = ns_load_path (); -#endif - - lpath = decode_env_path (0, loadpath ? loadpath : normal, 0); + lpath = decode_env_path (0, PATH_LOADSEARCH, 0); if (!NILP (Vinstallation_directory)) { diff --git a/src/nsterm.h b/src/nsterm.h index f64354b8a7b..b29e76cc63f 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1190,9 +1190,7 @@ extern void ns_run_ascript (void); #define NSAPP_DATA2_RUNFILEDIALOG 11 extern void ns_run_file_dialog (void); -extern const char *ns_etc_directory (void); -extern const char *ns_exec_path (void); -extern const char *ns_load_path (void); +extern const char *ns_relocate (const char *epath); extern void syms_of_nsterm (void); extern void syms_of_nsfns (void); extern void syms_of_nsmenu (void); diff --git a/src/nsterm.m b/src/nsterm.m index e81a4cbc0dc..8497138039c 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -499,118 +499,35 @@ append2 (Lisp_Object list, Lisp_Object item) const char * -ns_etc_directory (void) -/* If running as a self-contained app bundle, return as a string the - filename of the etc directory, if present; else nil. */ -{ - NSBundle *bundle = [NSBundle mainBundle]; - NSString *resourceDir = [bundle resourcePath]; - NSString *resourcePath; - NSFileManager *fileManager = [NSFileManager defaultManager]; - BOOL isDir; +ns_relocate (const char *epath) +/* If we're running in a self-contained app bundle some hard-coded + paths are relative to the root of the bundle, so work out the full + path. - resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"]; - if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) - { - if (isDir) return [resourcePath UTF8String]; - } - return NULL; -} - - -const char * -ns_exec_path (void) -/* If running as a self-contained app bundle, return as a path string - the filenames of the libexec and bin directories, ie libexec:bin. - Otherwise, return nil. - Normally, Emacs does not add its own bin/ directory to the PATH. - However, a self-contained NS build has a different layout, with - bin/ and libexec/ subdirectories in the directory that contains - Emacs.app itself. - We put libexec first, because init_callproc_1 uses the first - element to initialize exec-directory. An alternative would be - for init_callproc to check for invocation-directory/libexec. -*/ + FIXME: I think this should be able to handle cases where multiple + directories are separated by colons. */ { +#ifdef NS_SELF_CONTAINED NSBundle *bundle = [NSBundle mainBundle]; - NSString *resourceDir = [bundle resourcePath]; - NSString *binDir = [bundle bundlePath]; - NSString *resourcePath, *resourcePaths; - NSRange range; - NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR]; + NSString *root = [bundle bundlePath]; + NSString *original = [NSString stringWithUTF8String:epath]; + NSString *fixedPath = [NSString pathWithComponents:@[root, original]]; NSFileManager *fileManager = [NSFileManager defaultManager]; - NSArray *paths; - NSEnumerator *pathEnum; - BOOL isDir; - range = [resourceDir rangeOfString: @"Contents"]; - if (range.location != NSNotFound) - { - binDir = [binDir stringByAppendingPathComponent: @"Contents"]; -#ifdef NS_IMPL_COCOA - binDir = [binDir stringByAppendingPathComponent: @"MacOS"]; -#endif - } + if (![original isAbsolutePath] + && [fileManager fileExistsAtPath:fixedPath isDirectory:NULL]) + return [fixedPath UTF8String]; - paths = [binDir stringsByAppendingPaths: - [NSArray arrayWithObjects: @"libexec", @"bin", nil]]; - pathEnum = [paths objectEnumerator]; - resourcePaths = @""; + /* If we reach here either the path is absolute and therefore we + don't need to complete it, or we're unable to relocate the + file/directory. If it's the latter it may be because the user is + trying to use a bundled app as though it's a Unix style install + and we have no way to guess what was intended, so return the + original string unaltered. */ - while ((resourcePath = [pathEnum nextObject])) - { - if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) - if (isDir) - { - if ([resourcePaths length] > 0) - resourcePaths - = [resourcePaths stringByAppendingString: pathSeparator]; - resourcePaths - = [resourcePaths stringByAppendingString: resourcePath]; - } - } - if ([resourcePaths length] > 0) return [resourcePaths UTF8String]; - - return NULL; -} - - -const char * -ns_load_path (void) -/* If running as a self-contained app bundle, return as a path string - the filenames of the site-lisp and lisp directories. - Ie, site-lisp:lisp. Otherwise, return nil. */ -{ - NSBundle *bundle = [NSBundle mainBundle]; - NSString *resourceDir = [bundle resourcePath]; - NSString *resourcePath, *resourcePaths; - NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR]; - NSFileManager *fileManager = [NSFileManager defaultManager]; - BOOL isDir; - NSArray *paths = [resourceDir stringsByAppendingPaths: - [NSArray arrayWithObjects: - @"site-lisp", @"lisp", nil]]; - NSEnumerator *pathEnum = [paths objectEnumerator]; - resourcePaths = @""; - - /* Hack to skip site-lisp. */ - if (no_site_lisp) resourcePath = [pathEnum nextObject]; - - while ((resourcePath = [pathEnum nextObject])) - { - if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) - if (isDir) - { - if ([resourcePaths length] > 0) - resourcePaths - = [resourcePaths stringByAppendingString: pathSeparator]; - resourcePaths - = [resourcePaths stringByAppendingString: resourcePath]; - } - } - if ([resourcePaths length] > 0) return [resourcePaths UTF8String]; +#endif - return NULL; + return epath; } -- cgit v1.2.3 From ecf7e8b20ea095bd1232175160c3521ee299c069 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 26 Jun 2021 12:46:43 +0100 Subject: Fix NS self-contained build configuration * configure.ac: When rebuilding epaths.h for NS check that we're actually doing an NS build first. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 92527056b95..c8920d877e3 100644 --- a/configure.ac +++ b/configure.ac @@ -6020,12 +6020,12 @@ dnl the use of force in the 'epaths-force' rule in Makefile.in. AC_CONFIG_COMMANDS([src/epaths.h], [ if test "${opsys}" = "mingw32"; then ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-w32 -elif test "$EN_NS_SELF_CONTAINED" = "yes"; then +elif test "$HAVE_NS" = "yes" && test "$EN_NS_SELF_CONTAINED" = "yes"; then ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-ns-self-contained else ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force fi || AC_MSG_ERROR(['src/epaths.h' could not be made.]) -], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" +], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" HAVE_NS="$HAVE_NS" EN_NS_SELF_CONTAINED="$EN_NS_SELF_CONTAINED"]) dnl NB we have to cheat and use the ac_... version because abs_top_srcdir -- cgit v1.2.3 From 995ab9d0a916e4b1385fe6a25c0a9febe8dbb481 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Tue, 29 Jun 2021 22:02:43 +0100 Subject: Fix NS native comp search path (bug#49270) * configure.ac (NS_SELF_CONTAINED): We need to make lispdirrel the same as lispdir when building a self contained app bundle as they're both relative paths. --- configure.ac | 1 + 1 file changed, 1 insertion(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c8920d877e3..6e2cda947ae 100644 --- a/configure.ac +++ b/configure.ac @@ -2025,6 +2025,7 @@ if test "${HAVE_NS}" = yes; then infodir="\${ns_appresdir}/info" mandir="\${ns_appresdir}/man" lispdir="\${ns_appresdir}/lisp" + lispdirrel="\${ns_appresdir}/lisp" test "$locallisppathset" = no && locallisppath="\${ns_appresdir}/site-lisp" INSTALL_ARCH_INDEP_EXTRA= fi -- cgit v1.2.3 From 1b88404acc4b6399b617dac2b14f1eaa78135670 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 30 Jun 2021 19:58:13 +0100 Subject: Fix NS self contained eln location (bug#49271) * Makefile.in: * configure.ac: Change eln file install location to Contents/Frameworks. * src/comp.c (hash_native_abi): Replace dots with underscores in the eln install location as the macOS code-signing tool won't sign the files if the parent directories have dots. --- Makefile.in | 2 +- configure.ac | 4 ++-- src/comp.c | 28 +++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/Makefile.in b/Makefile.in index 8fccdf7580a..8c14c5cc7db 100644 --- a/Makefile.in +++ b/Makefile.in @@ -333,7 +333,7 @@ BIN_DESTDIR='$(DESTDIR)${bindir}/' ELN_DESTDIR = $(DESTDIR)${libdir}/emacs/${version}/ else BIN_DESTDIR='${ns_appbindir}/' -ELN_DESTDIR = ${ns_applibdir}/emacs/${version}/ +ELN_DESTDIR = ${ns_applibdir}/ endif all: ${SUBDIR} info diff --git a/configure.ac b/configure.ac index 6e2cda947ae..c924634d5b1 100644 --- a/configure.ac +++ b/configure.ac @@ -1895,7 +1895,7 @@ if test "${with_ns}" != no; then ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir}/Contents/MacOS ns_applibexecdir=${ns_appdir}/Contents/MacOS/libexec - ns_applibdir=${ns_appdir}/Contents/MacOS/lib + ns_applibdir=${ns_appdir}/Contents/Frameworks ns_appresdir=${ns_appdir}/Contents/Resources ns_appsrc=Cocoa/Emacs.base ns_fontfile=macfont.o @@ -1954,7 +1954,7 @@ fail; ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir} ns_applibexecdir=${ns_appdir}/libexec - ns_applibdir=${ns_appdir}/lib + ns_applibdir=${ns_appdir}/Frameworks ns_appresdir=${ns_appdir}/Resources ns_appsrc=GNUstep/Emacs.base ns_fontfile=nsfont.o diff --git a/src/comp.c b/src/comp.c index ea059526274..c3803464827 100644 --- a/src/comp.c +++ b/src/comp.c @@ -744,8 +744,34 @@ hash_native_abi (void) Vsystem_configuration_options), Fmapconcat (intern_c_string ("comp--subr-signature"), Vcomp_subr_list, build_string ("")))); + + Lisp_Object version = Vemacs_version; + +#ifdef NS_SELF_CONTAINED + /* MacOS self contained app bundles do not like having dots in the + directory names under the Contents/Frameworks directory, so + convert them to underscores. */ + version = STRING_MULTIBYTE (Vemacs_version) + ? make_uninit_multibyte_string (SCHARS (Vemacs_version), + SBYTES (Vemacs_version)) + : make_uninit_string (SBYTES (Vemacs_version)); + + const unsigned char *from = SDATA (Vemacs_version); + unsigned char *to = SDATA (version); + + while (from < SDATA (Vemacs_version) + SBYTES (Vemacs_version)) + { + unsigned char c = *from++; + + if (c == '.') + c = '_'; + + *to++ = c; + } +#endif + Vcomp_native_version_dir = - concat3 (Vemacs_version, build_string ("-"), Vcomp_abi_hash); + concat3 (version, build_string ("-"), Vcomp_abi_hash); } static void -- cgit v1.2.3 From a4d2c88cdee90a3e4863a62c4ff69896d0c1a347 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 29 May 2021 09:48:51 +0100 Subject: Simplify macOS drawing code Convert EmacsSurface into a CALayer subclass so we can use the built-in relationships. Also simplify the macOS versioning code. This will result in more warnings on older versions of macOS but makes reading the code easier. * configure.ac: Add QuartzCore framework. * src/nsterm.h (NS_DRAW_TO_BUFFER): Remove define and all references. (EmacsSurface, EmacsLayer): Rename EmacsSurface to EmacsLayer and modify the definition to fit the new function. * src/nsterm.m (ns_update_begin): (ns_update_end): (ns_focus): (ns_unfocus): Use the new overridden lockFocus and unlockFocus and simplify the frame management. ([EmacsView dealloc]): ([EmacsView viewDidResize:]):Don't explicitly release surfaces. ([EmacsView initFrameFromEmacs:]): Move the layer code to after the NSWindow has been created as creating the layer now relies on some of it's properties. ([EmacsView makeBackingLayer]): New function. ([EmacsView lockFocus]): ([EmacsView focusOnDrawingBuffer]): Rename to lockFocus. ([EmacsView unlockFocus]): ([EmacsView unfocusDrawingBuffer]): Rename to unlockFocus. ([EmacsView windowDidChangeBackingProperties]): Don't explicitly release surfaces but reset EmacsLayer properties. ([EmacsView layout]): ([EmacsView viewWillDraw]): Rename to layout. ([EmacsView wantsUpdateLayer]): Remove function and change all callers to [EmacsView wantsLayer]. (EmacsSurface, EmacsLayer): Rename to EmacsLayer. ([EmacsSurface getSize]): ([EmacsSurface initWithSize:ColorSpace:Scale:]): Remove methods. ([EmacsSurface initWithColorSpace:]): ([EmacsLayer checkDimensions]): ([EmacsLayer releaseSurfaces]): ([EmacsLayer display]): New functions. * src/nsterm.m ([EmacsLayer dealloc]): Use releaseSurfaces. ([EmacsSurface getContext]): Automatically detect frame property changes and clear the cache if required. Use built-in CALayer properties where available. ([EmacsLayer copyContentsTo:]): Use [CALayer contents] as source. --- configure.ac | 3 +- src/nsterm.h | 35 +---- src/nsterm.m | 496 ++++++++++++++++++++++++----------------------------------- 3 files changed, 207 insertions(+), 327 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index c924634d5b1..79cc56f9a73 100644 --- a/configure.ac +++ b/configure.ac @@ -5660,7 +5660,8 @@ case "$opsys" in if test "$HAVE_NS" = "yes"; then libs_nsgui="-framework AppKit" if test "$NS_IMPL_COCOA" = "yes"; then - libs_nsgui="$libs_nsgui -framework IOKit -framework Carbon -framework IOSurface" + libs_nsgui="$libs_nsgui -framework IOKit -framework Carbon \ + -framework IOSurface -framework QuartzCore" fi else libs_nsgui= diff --git a/src/nsterm.h b/src/nsterm.h index 57c1e4cbae0..c61c6986556 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -348,16 +348,6 @@ typedef id instancetype; #endif -/* macOS 10.14 and above cannot draw directly "to the glass" and - therefore we draw to an offscreen buffer and swap it in when the - toolkit wants to draw the frame. GNUstep and macOS 10.7 and below - do not support this method, so we revert to drawing directly to the - glass. */ -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 -#define NS_DRAW_TO_BUFFER 1 -#endif - - /* ========================================================================== NSColor, EmacsColor category. @@ -423,7 +413,7 @@ typedef id instancetype; ========================================================================== */ @class EmacsToolbar; -@class EmacsSurface; +@class EmacsLayer; #ifdef NS_IMPL_COCOA @interface EmacsView : NSView @@ -443,9 +433,6 @@ typedef id instancetype; int maximized_width, maximized_height; NSWindow *nonfs_window; BOOL fs_is_native; -#ifdef NS_DRAW_TO_BUFFER - EmacsSurface *surface; -#endif @public struct frame *emacsframe; int scrollbarsNeedingUpdate; @@ -483,9 +470,9 @@ typedef id instancetype; #endif - (int)fullscreenState; -#ifdef NS_DRAW_TO_BUFFER -- (void)focusOnDrawingBuffer; -- (void)unfocusDrawingBuffer; +#ifdef NS_IMPL_COCOA +- (void)lockFocus; +- (void)unlockFocus; #endif - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect; @@ -714,23 +701,17 @@ typedef id instancetype; + (CGFloat)scrollerWidth; @end -#ifdef NS_DRAW_TO_BUFFER -@interface EmacsSurface : NSObject +#ifdef NS_IMPL_COCOA +@interface EmacsLayer : CALayer { NSMutableArray *cache; - NSSize size; CGColorSpaceRef colorSpace; IOSurfaceRef currentSurface; - IOSurfaceRef lastSurface; CGContextRef context; - CGFloat scale; } -- (id) initWithSize: (NSSize)s ColorSpace: (CGColorSpaceRef)cs Scale: (CGFloat)scale; -- (void) dealloc; -- (NSSize) getSize; +- (id) initWithColorSpace: (CGColorSpaceRef)cs; +- (void) setColorSpace: (CGColorSpaceRef)cs; - (CGContextRef) getContext; -- (void) releaseContext; -- (IOSurfaceRef) getSurface; @end #endif diff --git a/src/nsterm.m b/src/nsterm.m index 853c0fa2fa9..b2ee459c427 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -70,9 +70,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #ifdef NS_IMPL_COCOA #include "macfont.h" #include -#endif - -#ifdef NS_DRAW_TO_BUFFER #include #endif @@ -272,9 +269,6 @@ long context_menu_value = 0; /* display update */ static struct frame *ns_updating_frame; -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 -static NSView *focus_view = NULL; -#endif static int ns_window_num = 0; static BOOL gsaved = NO; #ifdef NS_IMPL_COCOA @@ -1039,26 +1033,7 @@ ns_update_begin (struct frame *f) #endif ns_updating_frame = f; -#ifdef NS_DRAW_TO_BUFFER -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) - { -#endif - [view focusOnDrawingBuffer]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } - else - { -#endif -#endif /* NS_DRAW_TO_BUFFER */ - -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - [view lockFocus]; -#endif -#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } -#endif - + [view lockFocus]; } @@ -1069,39 +1044,21 @@ ns_update_end (struct frame *f) external (RIF) call; for whole frame, called after gui_update_window_end -------------------------------------------------------------------------- */ { -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 EmacsView *view = FRAME_NS_VIEW (f); -#endif NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ MOUSE_HL_INFO (f)->mouse_face_defer = 0; -#ifdef NS_DRAW_TO_BUFFER -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) - { -#endif - [FRAME_NS_VIEW (f) unfocusDrawingBuffer]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } - else - { -#endif -#endif /* NS_DRAW_TO_BUFFER */ - -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - block_input (); - - [view unlockFocus]; - [[view window] flushWindow]; + block_input (); - unblock_input (); -#endif -#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } + [view unlockFocus]; +#if defined (NS_IMPL_GNUSTEP) + [[view window] flushWindow]; #endif + + unblock_input (); ns_updating_frame = NULL; } @@ -1116,8 +1073,6 @@ ns_focus (struct frame *f, NSRect *r, int n) the entire window. -------------------------------------------------------------------------- */ { - EmacsView *view = FRAME_NS_VIEW (f); - NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_focus"); if (r != NULL) { @@ -1126,39 +1081,10 @@ ns_focus (struct frame *f, NSRect *r, int n) if (f != ns_updating_frame) { -#ifdef NS_DRAW_TO_BUFFER -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) - { -#endif - [view focusOnDrawingBuffer]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } - else - { -#endif -#endif /* NS_DRAW_TO_BUFFER */ - -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if (view != focus_view) - { - if (focus_view != NULL) - { - [focus_view unlockFocus]; - [[focus_view window] flushWindow]; - } - - if (view) - [view lockFocus]; - focus_view = view; - } -#endif -#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } -#endif + EmacsView *view = FRAME_NS_VIEW (f); + [view lockFocus]; } - /* clipping */ if (r) { @@ -1186,35 +1112,14 @@ ns_unfocus (struct frame *f) gsaved = NO; } -#ifdef NS_DRAW_TO_BUFFER - #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) - { -#endif - if (! ns_updating_frame) - [FRAME_NS_VIEW (f) unfocusDrawingBuffer]; - [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - } - else + if (f != ns_updating_frame) { + EmacsView *view = FRAME_NS_VIEW (f); + [view unlockFocus]; +#if defined (NS_IMPL_GNUSTEP) + [[view window] flushWindow]; #endif -#endif /* NS_DRAW_TO_BUFFER */ - -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if (f != ns_updating_frame) - { - if (focus_view != NULL) - { - [focus_view unlockFocus]; - [[focus_view window] flushWindow]; - focus_view = NULL; - } - } -#endif -#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } -#endif } @@ -1381,7 +1286,7 @@ ns_ring_bell (struct frame *f) } } -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 +#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 static void hide_bell (void) /* -------------------------------------------------------------------------- @@ -6178,10 +6083,6 @@ not_in_argv (NSString *arg) name:NSViewFrameDidChangeNotification object:nil]; -#ifdef NS_DRAW_TO_BUFFER - [surface release]; -#endif - [toolbar release]; if (fs_state == FULLSCREEN_BOTH) [nonfs_window release]; @@ -7192,24 +7093,6 @@ not_in_argv (NSString *arg) NSTRACE ("[EmacsView viewDidResize]"); -#ifdef NS_DRAW_TO_BUFFER - /* If the buffer size doesn't match the view's backing size, destroy - the buffer and let it be recreated at the correct size later. */ - if ([self wantsUpdateLayer] && surface) - { - NSRect surfaceRect = {{0, 0}, [surface getSize]}; - NSRect frameRect = [[self window] convertRectToBacking:frame]; - - if (!NSEqualRects (frameRect, surfaceRect)) - { - [surface release]; - surface = nil; - - [self setNeedsDisplay:YES]; - } - } -#endif - neww = (int)NSWidth (frame); newh = (int)NSHeight (frame); oldw = FRAME_PIXEL_WIDTH (emacsframe); @@ -7388,16 +7271,6 @@ not_in_argv (NSString *arg) [self initWithFrame: r]; [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; -#ifdef NS_DRAW_TO_BUFFER - /* These settings mean AppKit will retain the contents of the frame - on resize. Unfortunately it also means the frame will not be - automatically marked for display, but we can do that ourselves in - viewDidResize. */ - [self setLayerContentsRedrawPolicy: - NSViewLayerContentsRedrawOnSetNeedsDisplay]; - [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; -#endif - FRAME_NS_VIEW (f) = self; emacsframe = f; #ifdef NS_IMPL_COCOA @@ -7437,6 +7310,17 @@ not_in_argv (NSString *arg) [[win contentView] addSubview: self]; +#ifdef NS_IMPL_COCOA + /* These settings mean AppKit will retain the contents of the frame + on resize. Unfortunately it also means the frame will not be + automatically marked for display, but we can do that ourselves in + viewDidResize. */ + [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawOnSetNeedsDisplay]; + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; +#endif + if (ns_drag_types) [self registerForDraggedTypes: ns_drag_types]; @@ -8201,44 +8085,54 @@ not_in_argv (NSString *arg) } -#ifdef NS_DRAW_TO_BUFFER -- (void)focusOnDrawingBuffer +#ifdef NS_IMPL_COCOA +- (CALayer *)makeBackingLayer; { - CGFloat scale = [[self window] backingScaleFactor]; - - NSTRACE ("[EmacsView focusOnDrawingBuffer]"); + EmacsLayer *l = [[EmacsLayer alloc] + initWithColorSpace:[[[self window] colorSpace] CGColorSpace]]; + [l setDelegate:(id)self]; + [l setContentsScale:[[self window] backingScaleFactor]]; - if (! surface) - { - NSRect frame = [self frame]; - NSSize s = NSMakeSize (NSWidth (frame) * scale, NSHeight (frame) * scale); + return l; +} - surface = [[EmacsSurface alloc] initWithSize:s - ColorSpace:[[[self window] colorSpace] - CGColorSpace] - Scale:scale]; - /* Since we're using NSViewLayerContentsRedrawOnSetNeedsDisplay - the layer's scale factor is not set automatically, so do it - now. */ - [[self layer] setContentsScale:scale]; - } +- (void)lockFocus +{ + NSTRACE ("[EmacsView lockFocus]"); - CGContextRef context = [surface getContext]; + if ([self wantsLayer]) + { + CGContextRef context = [(EmacsLayer*)[self layer] getContext]; - [NSGraphicsContext - setCurrentContext:[NSGraphicsContext - graphicsContextWithCGContext:context - flipped:YES]]; + [NSGraphicsContext + setCurrentContext:[NSGraphicsContext + graphicsContextWithCGContext:context + flipped:YES]]; + } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + else + [super lockFocus]; +#endif } -- (void)unfocusDrawingBuffer +- (void)unlockFocus { - NSTRACE ("[EmacsView unfocusDrawingBuffer]"); + NSTRACE ("[EmacsView unlockFocus]"); - [NSGraphicsContext setCurrentContext:nil]; - [self setNeedsDisplay:YES]; + if ([self wantsLayer]) + { + [NSGraphicsContext setCurrentContext:nil]; + [self setNeedsDisplay:YES]; + } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + else + { + [super unlockFocus]; + [super flushWindow]; + } +#endif } @@ -8247,18 +8141,19 @@ not_in_argv (NSString *arg) { NSTRACE ("EmacsView windowDidChangeBackingProperties:]"); - if ([self wantsUpdateLayer]) + if ([self wantsLayer]) { NSRect frame = [self frame]; + EmacsLayer *layer = (EmacsLayer *)[self layer]; - [surface release]; - surface = nil; + [layer setContentsScale:[[notification object] backingScaleFactor]]; + [layer setColorSpace:[[[notification object] colorSpace] CGColorSpace]]; ns_clear_frame (emacsframe); expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); } } -#endif /* NS_DRAW_TO_BUFFER */ +#endif /* NS_IMPL_COCOA */ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect @@ -8267,11 +8162,9 @@ not_in_argv (NSString *arg) NSTRACE_RECT ("Source", srcRect); NSTRACE_RECT ("Destination", dstRect); -#ifdef NS_DRAW_TO_BUFFER -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if ([self wantsUpdateLayer]) +#ifdef NS_IMPL_COCOA + if ([self wantsLayer]) { -#endif double scale = [[self window] backingScaleFactor]; CGContextRef context = [[NSGraphicsContext currentContext] CGContext]; int bpp = CGBitmapContextGetBitsPerPixel (context) / 8; @@ -8297,14 +8190,14 @@ not_in_argv (NSString *arg) (char *) srcPixels + y * rowSize, srcRowSize); -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 else { #endif -#endif /* NS_DRAW_TO_BUFFER */ +#endif /* NS_IMPL_COCOA */ -#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 +#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 hide_bell(); // Ensure the bell image isn't scrolled. ns_focus (emacsframe, &dstRect, 1); @@ -8313,77 +8206,40 @@ not_in_argv (NSString *arg) dstRect.origin.y - srcRect.origin.y)]; ns_unfocus (emacsframe); #endif -#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } #endif } -#ifdef NS_DRAW_TO_BUFFER +#ifdef NS_IMPL_COCOA /* If the frame has been garbaged but the toolkit wants to draw, for example when resizing the frame, we end up with a blank screen. Sometimes this results in an unpleasant flicker, so try to - redisplay before drawing. */ -- (void)viewWillDraw -{ - if (FRAME_GARBAGED_P (emacsframe) - && !redisplaying_p - && [self wantsUpdateLayer]) - { - /* If there is IO going on when redisplay is run here Emacs - crashes. I think it's because this code will always be run - within the run loop and for whatever reason processing input - is dangerous. This technique was stolen wholesale from - nsmenu.m and seems to work. */ - bool owfi = waiting_for_input; - waiting_for_input = 0; - block_input (); - - redisplay (); - - unblock_input (); - waiting_for_input = owfi; - } -} - + redisplay before drawing. -- (BOOL)wantsUpdateLayer + This used to be done in viewWillDraw, but with the custom layer + that method is not called. */ +- (void)layout { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 - if (NSAppKitVersionNumber < 1671) - return NO; -#endif - - /* Running on macOS 10.14 or above. */ - return YES; -} + [super layout]; + /* If there is IO going on when redisplay is run here Emacs + crashes. I think it's because this code will always be run + within the run loop and for whatever reason processing input + is dangerous. This technique was stolen wholesale from + nsmenu.m and seems to work. */ + bool owfi = waiting_for_input; + waiting_for_input = 0; + block_input (); -- (void)updateLayer -{ - NSTRACE ("[EmacsView updateLayer]"); - - /* We run redisplay on frames that are garbaged, but marked for - display, before updateLayer is called so if the frame is still - garbaged that means the last redisplay must have refused to - update the frame. */ - if (FRAME_GARBAGED_P (emacsframe)) - return; + redisplay (); - /* This can fail to update the screen if the same surface is - provided twice in a row, even if its contents have changed. - There's a private method, -[CALayer setContentsChanged], that we - could use to force it, but we shouldn't often get the same - surface twice in a row. */ - [surface releaseContext]; - [[self layer] setContents:(id)[surface getSurface]]; - [surface performSelectorOnMainThread:@selector (getContext) - withObject:nil - waitUntilDone:NO]; + unblock_input (); + waiting_for_input = owfi; } #endif - - (void)drawRect: (NSRect)rect { NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", @@ -9550,7 +9406,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) @end /* EmacsScroller */ -#ifdef NS_DRAW_TO_BUFFER +#ifdef NS_IMPL_COCOA /* ========================================================================== @@ -9558,7 +9414,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) ========================================================================== */ -@implementation EmacsSurface +@implementation EmacsLayer /* An IOSurface is a pixel buffer that is efficiently copied to VRAM @@ -9571,80 +9427,106 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) ability to draw to the screen at any time, we need to keep a cache of multiple surfaces that we can use at will. - The EmacsSurface class maintains this cache of surfaces, and + The EmacsLayer class maintains this cache of surfaces, and handles the conversion to a CGGraphicsContext that AppKit can use to draw on. The cache is simple: if a free surface is found it is removed from - the cache and set as the "current" surface. Once Emacs is done - with drawing to the current surface, the previous surface that was - drawn to is added to the cache for reuse, and the current one is - set as the last surface. If no free surfaces are found in the - cache then a new one is created. - - When AppKit wants to update the screen, we provide it with the last - surface, as that has the most recent data. - - FIXME: It is possible for the cache to grow if Emacs draws faster - than the surfaces can be drawn to the screen, so there should - probably be some sort of pruning job that removes excess - surfaces. */ + the cache and set as the "current" surface. Emacs draws to the + surface and when the layer wants to update the screen we set it's + contents to the surface and then add it back on to the end of the + cache. If no free surfaces are found in the cache then a new one + is created. */ #define CACHE_MAX_SIZE 2 -- (id) initWithSize: (NSSize)s - ColorSpace: (CGColorSpaceRef)cs - Scale: (CGFloat)scl +- (id) initWithColorSpace: (CGColorSpaceRef)cs { - NSTRACE ("[EmacsSurface initWithSize:ColorSpace:]"); - - [super init]; + NSTRACE ("[EmacsLayer initWithColorSpace:]"); - cache = [[NSMutableArray arrayWithCapacity:CACHE_MAX_SIZE] retain]; - size = s; - colorSpace = cs; - scale = scl; + self = [super init]; + if (self) + { + cache = [[NSMutableArray arrayWithCapacity:CACHE_MAX_SIZE] retain]; + colorSpace = cs; + } + else + { + return nil; + } return self; } -- (void) dealloc +- (void) setColorSpace: (CGColorSpaceRef)cs { - if (context) - CGContextRelease (context); - - if (currentSurface) - CFRelease (currentSurface); + /* We don't need to clear the cache because the new colorspace will + be used next time we create a new context. */ + colorSpace = cs; +} - for (id object in cache) - CFRelease ((IOSurfaceRef)object); +- (void) dealloc +{ + [self releaseSurfaces]; [cache release]; [super dealloc]; } -/* Return the size values our cached data is using. */ -- (NSSize) getSize +- (void) releaseSurfaces { - return size; + [self setContents:nil]; + [self releaseContext]; + + if (currentSurface) + { + CFRelease (currentSurface); + currentSurface = nil; + } + + if (cache) + { + for (id object in cache) + CFRelease ((IOSurfaceRef)object); + + [cache removeAllObjects]; + } +} + + +/* Check whether the current bounds match the IOSurfaces we are using. + If they do return YES, otherwise NO. */ +- (BOOL) checkDimensions +{ + int width = NSWidth ([self bounds]) * [self contentsScale]; + int height = NSHeight ([self bounds]) * [self contentsScale]; + IOSurfaceRef s = currentSurface ? currentSurface + : (IOSurfaceRef)[cache firstObject]; + + return !s || (IOSurfaceGetWidth (s) == width + && IOSurfaceGetHeight (s) == height); } -/* Return a CGContextRef that can be used for drawing to the screen. - This must ALWAYS be paired with a call to releaseContext, and the - calls cannot be nested. */ +/* Return a CGContextRef that can be used for drawing to the screen. */ - (CGContextRef) getContext { - NSTRACE ("[EmacsSurface getContext]"); + CGFloat scale = [self contentsScale]; + + NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "[EmacsLayer getContext]"); + NSTRACE_MSG ("IOSurface count: %lu", [cache count] + (currentSurface ? 1 : 0)); + + if (![self checkDimensions]) + [self releaseSurfaces]; if (!context) { IOSurfaceRef surface = NULL; - - NSTRACE_MSG ("IOSurface count: %lu", [cache count] + (lastSurface ? 1 : 0)); + int width = NSWidth ([self bounds]) * scale; + int height = NSHeight ([self bounds]) * scale; for (id object in cache) { @@ -9667,11 +9549,11 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) else if (!surface) { int bytesPerRow = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow, - size.width * 4); + width * 4); surface = IOSurfaceCreate - ((CFDictionaryRef)@{(id)kIOSurfaceWidth:[NSNumber numberWithInt:size.width], - (id)kIOSurfaceHeight:[NSNumber numberWithInt:size.height], + ((CFDictionaryRef)@{(id)kIOSurfaceWidth:[NSNumber numberWithInt:width], + (id)kIOSurfaceHeight:[NSNumber numberWithInt:height], (id)kIOSurfaceBytesPerRow:[NSNumber numberWithInt:bytesPerRow], (id)kIOSurfaceBytesPerElement:[NSNumber numberWithInt:4], (id)kIOSurfacePixelFormat:[NSNumber numberWithUnsignedInt:'BGRA']}); @@ -9694,7 +9576,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(context, 0, size.height); + CGContextTranslateCTM(context, 0, IOSurfaceGetHeight (currentSurface)); CGContextScaleCTM(context, scale, -scale); } @@ -9706,7 +9588,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) IOSurface, so it will be sent to VRAM. */ - (void) releaseContext { - NSTRACE ("[EmacsSurface releaseContextAndGetSurface]"); + NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "[EmacsLayer releaseContext]"); if (!context) return; @@ -9717,19 +9599,34 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) IOReturn lockStatus = IOSurfaceUnlock (currentSurface, 0, nil); if (lockStatus != kIOReturnSuccess) NSLog (@"Failed to unlock surface: %x", lockStatus); - - /* Put currentSurface back on the end of the cache. */ - [cache addObject:(id)currentSurface]; - lastSurface = currentSurface; - currentSurface = NULL; } -/* Get the IOSurface that we want to draw to the screen. */ -- (IOSurfaceRef) getSurface +- (void) display { - /* lastSurface always contains the most up-to-date and complete data. */ - return lastSurface; + NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "[EmacsLayer display]"); + + if (context) + { + [self releaseContext]; + +#if CACHE_MAX_SIZE == 1 + /* This forces the layer to see the surface as updated. */ + [self setContents:nil]; +#endif + + [self setContents:(id)currentSurface]; + + /* Put currentSurface back on the end of the cache. */ + [cache addObject:(id)currentSurface]; + currentSurface = NULL; + + /* Schedule a run of getContext so that if Emacs is idle it will + perform the buffer copy, etc. */ + [self performSelectorOnMainThread:@selector (getContext) + withObject:nil + waitUntilDone:NO]; + } } @@ -9739,19 +9636,20 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) - (void) copyContentsTo: (IOSurfaceRef) destination { IOReturn lockStatus; + IOSurfaceRef source = (IOSurfaceRef)[self contents]; void *sourceData, *destinationData; int numBytes = IOSurfaceGetAllocSize (destination); - NSTRACE ("[EmacsSurface copyContentsTo:]"); + NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "[EmacsLayer copyContentsTo:]"); - if (!lastSurface || lastSurface == destination) + if (!source || source == destination) return; - lockStatus = IOSurfaceLock (lastSurface, kIOSurfaceLockReadOnly, nil); + lockStatus = IOSurfaceLock (source, kIOSurfaceLockReadOnly, nil); if (lockStatus != kIOReturnSuccess) NSLog (@"Failed to lock source surface: %x", lockStatus); - sourceData = IOSurfaceGetBaseAddress (lastSurface); + sourceData = IOSurfaceGetBaseAddress (source); destinationData = IOSurfaceGetBaseAddress (destination); /* Since every IOSurface should have the exact same settings, a @@ -9759,17 +9657,17 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) the other. */ memcpy (destinationData, sourceData, numBytes); - lockStatus = IOSurfaceUnlock (lastSurface, kIOSurfaceLockReadOnly, nil); + lockStatus = IOSurfaceUnlock (source, kIOSurfaceLockReadOnly, nil); if (lockStatus != kIOReturnSuccess) NSLog (@"Failed to unlock source surface: %x", lockStatus); } #undef CACHE_MAX_SIZE -@end /* EmacsSurface */ +@end /* EmacsLayer */ -#endif +#endif /* NS_IMPL_COCOA */ #ifdef NS_IMPL_GNUSTEP -- cgit v1.2.3 From 8ce7a697ca8d654271021a9580ed1054df58100e Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 Aug 2021 11:56:37 +0200 Subject: Allow building on MacOS with MacPorts and libgccjit * configure.ac: Check for the "port" command (MacPorts). Add the required lib/include directories for nativecomp. * src/Makefile.in (LIBGCCJIT_CFLAGS, LIBGCCJIT_LIBS): Split into two parts to allow including -L/-I for MacPorts. (LIBES): Adjust. (EMACS_CFLAGS): Ditto. --- configure.ac | 33 +++++++++++++++++++++++++++++---- src/Makefile.in | 7 ++++--- 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 79cc56f9a73..be97d9c8a08 100644 --- a/configure.ac +++ b/configure.ac @@ -1334,6 +1334,9 @@ if test -n "$BREW"; then [`$BREW --prefix texinfo 2>/dev/null`/bin$PATH_SEPARATOR$PATH]) fi +# Check MacPorts on macOS. +AC_PATH_PROG(HAVE_MACPORTS, port) + ## Require makeinfo >= 4.13 (last of the 4.x series) to build the manuals. : ${MAKEINFO:=makeinfo} case `($MAKEINFO --version) 2>/dev/null` in @@ -3807,7 +3810,8 @@ source on this site: .])]) HAVE_NATIVE_COMP=no -LIBGCCJIT_LIB= +LIBGCCJIT_LIBS= +LIBGCCJIT_CFLAGS= if test "${with_native_compilation}" != "no"; then if test "${HAVE_PDUMPER}" = no; then AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper']) @@ -3827,6 +3831,20 @@ if test "${with_native_compilation}" != "no"; then fi fi + # Ensure libgccjit installed by MacPorts can be found. + if test -n "$HAVE_MACPORTS"; then + # Determine which gcc version has been installed (gcc11, for + # instance). + PORT_PACKAGE=$(port installed active | grep '^ *gcc@<:@0-9@:>@* ' | \ + awk '{ print $1; }') + MACPORTS_LIBGCCJIT_INCLUDE=$(dirname $(port contents $PORT_PACKAGE | \ + grep libgccjit.h)) + MACPORTS_LIBGCCJIT_LIB=$(dirname $(port contents $PORT_PACKAGE | \ + grep libgccjit.dylib)) + CFLAGS="$CFLAGS -I${MACPORTS_LIBGCCJIT_INCLUDE}" + LDFLAGS="$LDFLAGS -L${MACPORTS_LIBGCCJIT_LIB}" + fi + # Check if libgccjit is available. AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, [], [libgccjit_not_found]) AC_CHECK_HEADERS(libgccjit.h, [], [libgccjit_dev_not_found]) @@ -3841,17 +3859,24 @@ if test "${with_native_compilation}" != "no"; then mingw32) ;; # OpenBSD doesn't have libdl, all the functions are in libc netbsd|openbsd) - LIBGCCJIT_LIB="-lgccjit" ;; + LIBGCCJIT_LIBS="-lgccjit" ;; *) - LIBGCCJIT_LIB="-lgccjit -ldl" ;; + LIBGCCJIT_LIBS="-lgccjit -ldl" ;; esac NEED_DYNLIB=yes AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if native compiler is available.]) + + # Ensure libgccjit installed by MacPorts can be found. + if test -n "$HAVE_MACPORTS"; then + LIBGCCJIT_CFLAGS="$LIBGCCJIT_CFLAGS -I${MACPORTS_LIBGCCJIT_INCLUDE}" + LIBGCCJIT_LIBS="-L${MACPORTS_LIBGCCJIT_LIB} $LIBGCCJIT_LIBS" + fi fi AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln", [System extension for native compiled elisp]) AC_SUBST(HAVE_NATIVE_COMP) -AC_SUBST(LIBGCCJIT_LIB) +AC_SUBST(LIBGCCJIT_CFLAGS) +AC_SUBST(LIBGCCJIT_LIBS) DYNLIB_OBJ= if test "${NEED_DYNLIB}" = yes; then diff --git a/src/Makefile.in b/src/Makefile.in index 22c7aeed5c6..732cd8f0998 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -326,7 +326,8 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ LIBGMP = @LIBGMP@ -LIBGCCJIT = @LIBGCCJIT_LIB@ +LIBGCCJIT_LIBS = @LIBGCCJIT_LIBS@ +LIBGCCJIT_CFLAGS = @LIBGCCJIT_CFLAGS@ ## dynlib.o if necessary, else empty DYNLIB_OBJ = @DYNLIB_OBJ@ @@ -367,7 +368,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \ -I$(lib) -I$(top_srcdir)/lib \ $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \ $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ - $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ + $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \ $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \ $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ @@ -516,7 +517,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ - $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT) + $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) ## FORCE it so that admin/unidata can decide whether this file is ## up-to-date. Although since charprop depends on bootstrap-emacs, -- cgit v1.2.3 From 23973a58985d2e11e880cadea79705d063a770fa Mon Sep 17 00:00:00 2001 From: Grégoire Jadi Date: Mon, 9 Aug 2021 14:25:36 +0200 Subject: Fix freeze on OpenBSD when reading the SECONDARY selection * configure.ac (NSIG_MINIMUM): OpenBSD doesn't have a broken SIGIO any more (bug#29170). Backport fix from the current OpenBSD port tree. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index be97d9c8a08..eff55915436 100644 --- a/configure.ac +++ b/configure.ac @@ -4909,7 +4909,7 @@ emacs_broken_SIGIO=no case $opsys in dnl SIGIO exists, but the feature doesn't work in the way Emacs needs. - hpux* | nacl | openbsd | solaris | unixware ) + hpux* | nacl | solaris | unixware ) emacs_broken_SIGIO=yes ;; -- cgit v1.2.3