Commit 5c2f94a1 authored by Paul Eggert's avatar Paul Eggert

Replace executable’s fingerprint in place

* admin/merge-gnulib (GNULIB_MODULES): Add memmem-simple.
(AVOIDED_MODULES): Add memchr.
* configure.ac (HAVE_PDUMPER): AC_SUBST it, too, for use in makefiles.
* lib/Makefile.in (libgnu_a_OBJECTS): Add fingerprint.o.
* lib/fingerprint.c: New file.
* lib/memmem.c, lib/str-two-way.h, m4/memmem.m4: New files,
copied from Gnulib.
* lib/fingerprint.h: Rename from src/fingerprint.h.
* lib-src/make-fingerprint.c: Include limits.h, sys/stat.h,
fingerprint.h, intprops.h, min-max.h.
(SSIZE_MAX): New macro, if not already defined.
(main): Without -r, Replace the fingerprint in the input file
instead of generating a fingerprint.c.
* lib/Makefile.in (libgnu_a_OBJECTS): Add fingerprint.o.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* src/Makefile.in (HAVE_PDUMPER, MAKE_PDUMPER_FINGERPRINT):
New macros.
(temacs$(EXEEXT)): Use them to replace the fingerprint instead
of precalculating it.
(mostlyclean, ctagsfiles1): Do not worry about fingerprint.c.
parent 661f4494
Pipeline #1294 failed with stage
in 50 minutes and 8 seconds
......@@ -36,7 +36,7 @@ GNULIB_MODULES='
filemode filevercmp flexmember fpieee fstatat fsusage fsync
getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
ieee754-h ignore-value intprops largefile lstat
manywarnings memrchr minmax mkostemp mktime nstrftime
manywarnings memmem-simple memrchr minmax mkostemp mktime nstrftime
pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat regex
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
stpcpy strtoimax symlink sys_stat sys_time
......@@ -47,7 +47,7 @@ GNULIB_MODULES='
AVOIDED_MODULES='
btowc close dup fchdir fstat langinfo lock
malloc-posix mbrtowc mbsinit mkdir msvc-inval msvc-nothrow nl_langinfo
malloc-posix mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
openat-die opendir raise
save-cwd select setenv sigprocmask stat stdarg stdbool
threadlib tzset unsetenv utime utime-h
......
......@@ -379,8 +379,12 @@ if test "$with_dumping" = "unexec" && test "$with_unexec" = "no"; then
fi
if test "$with_pdumper" = "yes"; then
AC_DEFINE(HAVE_PDUMPER, 1, [Define to build with portable dumper support])
AC_DEFINE([HAVE_PDUMPER], 1, [Define to build with portable dumper support])
HAVE_PDUMPER=yes
else
HAVE_PDUMPER=no
fi
AC_SUBST([HAVE_PDUMPER])
DUMPING=$with_dumping
AC_SUBST(DUMPING)
......
......@@ -25,14 +25,25 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sysstdio.h>
#include <sha256.h>
#include <fingerprint.h>
#include <getopt.h>
#include <intprops.h>
#include <min-max.h>
#include <sha256.h>
#ifndef SSIZE_MAX
# define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
#endif
#ifdef WINDOWSNT
/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
......@@ -54,41 +65,62 @@ main (int argc, char **argv)
raw = true;
break;
case 'h':
printf ("make-fingerprint [-r] FILES...: compute a hash\n");
return 0;
printf ("make-fingerprint [-r] FILE: replace or compute a hash\n");
return EXIT_SUCCESS;
default:
return 1;
return EXIT_FAILURE;
}
}
struct sha256_ctx ctx;
sha256_init_ctx (&ctx);
for (int i = optind; i < argc; ++i)
if (argc - optind != 1)
{
FILE *f = fopen (argv[i], "r" FOPEN_BINARY);
if (!f)
{
fprintf (stderr, "%s: Error: could not open %s\n",
argv[0], argv[i]);
return 1;
}
fprintf (stderr, "%s: missing or extra file operand\n", argv[0]);
return EXIT_FAILURE;
}
char buf[128*1024];
do
{
size_t chunksz = fread (buf, 1, sizeof (buf), f);
if (ferror (f))
{
fprintf (stderr, "%s: Error: could not read %s\n",
argv[0], argv[i]);
return 1;
}
sha256_process_bytes (buf, chunksz, &ctx);
} while (!feof (f));
fclose (f);
FILE *f = fopen (argv[1], raw ? "r" FOPEN_BINARY : "r+" FOPEN_BINARY);
struct stat st;
if (!f || fstat (fileno (f), &st) != 0)
{
perror (argv[1]);
return EXIT_FAILURE;
}
if (!S_ISREG (st.st_mode))
{
fprintf (stderr, "%s: Error: %s is not a regular file\n",
argv[0], argv[1]);
return EXIT_FAILURE;
}
ptrdiff_t maxlen = min (min (TYPE_MAXIMUM (off_t), PTRDIFF_MAX),
min (SIZE_MAX, SSIZE_MAX));
if (maxlen <= st.st_size)
{
fprintf (stderr, "%s: %s: file too big\n", argv[0], argv[1]);
return EXIT_FAILURE;
}
char *buf = malloc (st.st_size + 1);
if (!buf)
{
perror ("malloc");
return EXIT_FAILURE;
}
size_t chunksz = fread (buf, 1, st.st_size + 1, f);
if (ferror (f) || chunksz != st.st_size)
{
fprintf (stderr, "%s: Error: could not read %s\n",
argv[0], argv[1]);
return EXIT_FAILURE;
}
sha256_process_bytes (buf, chunksz, &ctx);
unsigned char digest[32];
sha256_finish_ctx (&ctx, digest);
......@@ -99,12 +131,37 @@ main (int argc, char **argv)
}
else
{
puts ("#include \"fingerprint.h\"\n"
"unsigned char const fingerprint[] =\n"
"{");
for (int i = 0; i < 32; ++i)
printf ("\t0x%02X,\n", digest[i]);
puts ("};");
char *finger = memmem (buf, chunksz, fingerprint, sizeof fingerprint);
if (!finger)
{
fprintf (stderr, "%s: %s: missing fingerprint\n", argv[0], argv[1]);
return EXIT_FAILURE;
}
else if (memmem (finger + 1, buf + chunksz - (finger + 1),
fingerprint, sizeof fingerprint))
{
fprintf (stderr, "%s: %s: two occurrences of fingerprint\n",
argv[0], argv[1]);
return EXIT_FAILURE;
}
if (fseeko (f, finger - buf, SEEK_SET) != 0)
{
perror (argv[1]);
return EXIT_FAILURE;
}
if (fwrite (digest, 1, sizeof digest, f) != sizeof digest)
{
perror (argv[1]);
return EXIT_FAILURE;
}
}
if (fclose (f) != 0)
{
perror (argv[1]);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
......
......@@ -84,7 +84,7 @@ Makefile: ../config.status $(srcdir)/Makefile.in
# and building it would just waste time.
not_emacs_OBJECTS = regex.o
libgnu_a_OBJECTS = $(gl_LIBOBJS) \
libgnu_a_OBJECTS = fingerprint.o $(gl_LIBOBJS) \
$(patsubst %.c,%.o,$(filter %.c,$(libgnu_a_SOURCES)))
for_emacs_OBJECTS = $(filter-out $(not_emacs_OBJECTS),$(libgnu_a_OBJECTS))
libegnu_a_OBJECTS = $(patsubst %.o,e-%.o,$(for_emacs_OBJECTS))
......
/* Placeholder fingerprint for Emacs
Copyright 2019 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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "fingerprint.h"
/* This random fingerprint was generated by the shell command:
shuf -i 0-255 -n 32 -r | awk '{printf " 0x%.02X,\n", $0}'
In the final Emacs executable, this random fingerprint is replaced
by a fingerprint of the temporary Emacs executable that was built
along the way. */
unsigned char const fingerprint[] =
{
0xDE,
0x86,
0xBB,
0x99,
0xFF,
0xF5,
0x46,
0x9A,
0x9E,
0x3F,
0x9F,
0x5D,
0x9A,
0xDF,
0xF0,
0x91,
0xBD,
0xCD,
0xC1,
0xE8,
0x0C,
0x16,
0x1E,
0xAF,
0xB8,
0x6C,
0xE2,
0x2B,
0xB1,
0x24,
0xCE,
0xB0,
};
......@@ -44,6 +44,7 @@
# --avoid=malloc-posix \
# --avoid=mbrtowc \
# --avoid=mbsinit \
# --avoid=memchr \
# --avoid=mkdir \
# --avoid=msvc-inval \
# --avoid=msvc-nothrow \
......@@ -111,6 +112,7 @@
# largefile \
# lstat \
# manywarnings \
# memmem-simple \
# memrchr \
# minmax \
# mkostemp \
......@@ -1053,7 +1055,6 @@ gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7 = @gl_GNULIB_ENABLED_03e0aaad
gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9 = @gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9@
gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467 = @gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467@
gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b@
gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547 = @gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547@
gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@
gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@
gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec@
......@@ -1963,6 +1964,17 @@ EXTRA_libgnu_a_SOURCES += lstat.c
endif
## end gnulib module lstat
## begin gnulib module memmem-simple
ifeq (,$(OMIT_GNULIB_MODULE_memmem-simple))
EXTRA_DIST += memmem.c str-two-way.h
EXTRA_libgnu_a_SOURCES += memmem.c
endif
## end gnulib module memmem-simple
## begin gnulib module memrchr
ifeq (,$(OMIT_GNULIB_MODULE_memrchr))
......
/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2019 Free Software
Foundation, Inc.
This file is part of the GNU C Library.
This program 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, or (at your option)
any later version.
This program 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 this program; if not, see <https://www.gnu.org/licenses/>. */
/* This particular implementation was written by Eric Blake, 2008. */
#ifndef _LIBC
# include <config.h>
#endif
/* Specification of memmem. */
#include <string.h>
#define RETURN_TYPE void *
#define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
#include "str-two-way.h"
/* Return the first occurrence of NEEDLE in HAYSTACK. Return HAYSTACK
if NEEDLE_LEN is 0, otherwise NULL if NEEDLE is not found in
HAYSTACK. */
void *
memmem (const void *haystack_start, size_t haystack_len,
const void *needle_start, size_t needle_len)
{
/* Abstract memory is considered to be an array of 'unsigned char' values,
not an array of 'char' values. See ISO C 99 section 6.2.6.1. */
const unsigned char *haystack = (const unsigned char *) haystack_start;
const unsigned char *needle = (const unsigned char *) needle_start;
if (needle_len == 0)
/* The first occurrence of the empty string is deemed to occur at
the beginning of the string. */
return (void *) haystack;
/* Sanity check, otherwise the loop might search through the whole
memory. */
if (__builtin_expect (haystack_len < needle_len, 0))
return NULL;
/* Use optimizations in memchr when possible, to reduce the search
size of haystack using a linear algorithm with a smaller
coefficient. However, avoid memchr for long needles, since we
can often achieve sublinear performance. */
if (needle_len < LONG_NEEDLE_THRESHOLD)
{
haystack = memchr (haystack, *needle, haystack_len);
if (!haystack || __builtin_expect (needle_len == 1, 0))
return (void *) haystack;
haystack_len -= haystack - (const unsigned char *) haystack_start;
if (haystack_len < needle_len)
return NULL;
return two_way_short_needle (haystack, haystack_len, needle, needle_len);
}
else
return two_way_long_needle (haystack, haystack_len, needle, needle_len);
}
#undef LONG_NEEDLE_THRESHOLD
This diff is collapsed.
......@@ -113,6 +113,7 @@ AC_DEFUN([gl_EARLY],
# Code from module localtime-buffer:
# Code from module lstat:
# Code from module manywarnings:
# Code from module memmem-simple:
# Code from module memrchr:
# Code from module minmax:
# Code from module mkostemp:
......@@ -195,6 +196,7 @@ AC_DEFUN([gl_INIT],
gl_source_base='lib'
gl_FUNC_ACL
gl_FUNC_ALLOCA
gl___BUILTIN_EXPECT
gl_BYTESWAP
AC_CHECK_FUNCS_ONCE([readlinkat])
gl_CLOCK_TIME
......@@ -302,6 +304,11 @@ AC_DEFUN([gl_INIT],
gl_PREREQ_LSTAT
fi
gl_SYS_STAT_MODULE_INDICATOR([lstat])
gl_FUNC_MEMMEM_SIMPLE
if test $HAVE_MEMMEM = 0 || test $REPLACE_MEMMEM = 1; then
AC_LIBOBJ([memmem])
fi
gl_STRING_MODULE_INDICATOR([memmem])
gl_FUNC_MEMRCHR
if test $ac_cv_func_memrchr = no; then
AC_LIBOBJ([memrchr])
......@@ -426,7 +433,6 @@ AC_DEFUN([gl_INIT],
gl_UTIMENS
AC_C_VARARRAYS
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547=false
gl_gnulib_enabled_cloexec=false
gl_gnulib_enabled_dirfd=false
gl_gnulib_enabled_euidaccess=false
......@@ -450,13 +456,6 @@ AC_DEFUN([gl_INIT],
func_gl_gnulib_m4code_open
fi
}
func_gl_gnulib_m4code_37f71b604aa9c54446783d80f42fe547 ()
{
if ! $gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547; then
gl___BUILTIN_EXPECT
gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547=true
fi
}
func_gl_gnulib_m4code_cloexec ()
{
if ! $gl_gnulib_enabled_cloexec; then
......@@ -652,9 +651,6 @@ AC_DEFUN([gl_INIT],
if test $HAVE_READLINKAT = 0; then
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
fi
if test $ac_use_included_regex = yes; then
func_gl_gnulib_m4code_37f71b604aa9c54446783d80f42fe547
fi
if test $ac_use_included_regex = yes; then
func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
fi
......@@ -666,7 +662,6 @@ AC_DEFUN([gl_INIT],
fi
m4_pattern_allow([^gl_GNULIB_ENABLED_])
AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
AM_CONDITIONAL([gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547], [$gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547])
AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd])
AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess])
......@@ -916,6 +911,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/lstat.c
lib/md5.c
lib/md5.h
lib/memmem.c
lib/memrchr.c
lib/minmax.h
lib/mkostemp.c
......@@ -959,6 +955,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/stdio.in.h
lib/stdlib.in.h
lib/stpcpy.c
lib/str-two-way.h
lib/strftime.h
lib/string.in.h
lib/strtoimax.c
......@@ -1049,6 +1046,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/manywarnings.m4
m4/mbstate_t.m4
m4/md5.m4
m4/memmem.m4
m4/memrchr.m4
m4/minmax.m4
m4/mkostemp.m4
......
# memmem.m4 serial 25
dnl Copyright (C) 2002-2004, 2007-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Check that memmem is present and functional.
AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
[
dnl Persuade glibc <string.h> to declare memmem().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([memmem])
if test $ac_cv_func_memmem = yes; then
HAVE_MEMMEM=1
else
HAVE_MEMMEM=0
fi
AC_CHECK_DECLS_ONCE([memmem])
if test $ac_cv_have_decl_memmem = no; then
HAVE_DECL_MEMMEM=0
else
dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092.
dnl Also check that we handle empty needles correctly.
AC_CACHE_CHECK([whether memmem works],
[gl_cv_func_memmem_works_always],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <string.h> /* for memmem */
#define P "_EF_BF_BD"
#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
#define NEEDLE P P P P P
]], [[
int result = 0;
if (memmem (HAYSTACK, strlen (HAYSTACK), NEEDLE, strlen (NEEDLE)))
result |= 1;
/* Check for empty needle behavior. */
{
const char *haystack = "AAA";
if (memmem (haystack, 3, NULL, 0) != haystack)
result |= 2;
}
return result;
]])],
[gl_cv_func_memmem_works_always=yes],
[gl_cv_func_memmem_works_always=no],
[dnl glibc 2.9..2.12 and cygwin 1.7.7 have issue #12092 above.
dnl Also empty needles work on glibc >= 2.1 and cygwin >= 1.7.0.
dnl uClibc is not affected, since it uses different source code.
dnl Assume that it works on all other platforms (even if not linear).
AC_EGREP_CPP([Lucky user],
[
#ifdef __GNU_LIBRARY__
#include <features.h>
#if ((__GLIBC__ == 2 && ((__GLIBC_MINOR > 0 && __GLIBC_MINOR__ < 9) \
|| __GLIBC_MINOR__ > 12)) \
|| (__GLIBC__ > 2)) \
|| defined __UCLIBC__
Lucky user
#endif
#elif defined __CYGWIN__
#include <cygwin/version.h>
#if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
Lucky user
#endif
#else
Lucky user
#endif
],
[gl_cv_func_memmem_works_always="guessing yes"],
[gl_cv_func_memmem_works_always="guessing no"])
])
])
case "$gl_cv_func_memmem_works_always" in
*yes) ;;
*)
REPLACE_MEMMEM=1
;;
esac
fi
gl_PREREQ_MEMMEM
]) # gl_FUNC_MEMMEM_SIMPLE
dnl Additionally, check that memmem has linear performance characteristics
AC_DEFUN([gl_FUNC_MEMMEM],
[
AC_REQUIRE([gl_FUNC_MEMMEM_SIMPLE])
if test $HAVE_DECL_MEMMEM = 1 && test $REPLACE_MEMMEM = 0; then
AC_CACHE_CHECK([whether memmem works in linear time],
[gl_cv_func_memmem_works_fast],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <signal.h> /* for signal */
#include <string.h> /* for memmem */
#include <stdlib.h> /* for malloc */
#include <unistd.h> /* for alarm */
static void quit (int sig) { _exit (sig + 128); }
]], [[
int result = 0;
size_t m = 1000000;
char *haystack = (char *) malloc (2 * m + 1);
char *needle = (char *) malloc (m + 1);
/* Failure to compile this test due to missing alarm is okay,
since all such platforms (mingw) also lack memmem. */
signal (SIGALRM, quit);
alarm (5);
/* Check for quadratic performance. */
if (haystack && needle)
{
memset (haystack, 'A', 2 * m);
haystack[2 * m] = 'B';
memset (needle, 'A', m);
needle[m] = 'B';
if (!memmem (haystack, 2 * m + 1, needle, m + 1))
result |= 1;
}
/* Free allocated memory, in case some sanitizer is watching. */
free (haystack);
free (needle);
return result;
]])],
[gl_cv_func_memmem_works_fast=yes], [gl_cv_func_memmem_works_fast=no],
[dnl Only glibc >= 2.9 and cygwin > 1.7.0 are known to have a
dnl memmem that works in linear time.
AC_EGREP_CPP([Lucky user],
[
#include <features.h>
#ifdef __GNU_LIBRARY__
#if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 9) || (__GLIBC__ > 2)) \
&& !defined __UCLIBC__
Lucky user
#endif
#endif
#ifdef __CYGWIN__
#include <cygwin/version.h>
#if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 0)
Lucky user
#endif
#endif
],
[gl_cv_func_memmem_works_fast="guessing yes"],
[gl_cv_func_memmem_works_fast="guessing no"])
])
])
case "$gl_cv_func_memmem_works_fast" in
*yes) ;;
*)
REPLACE_MEMMEM=1
;;
esac
fi
]) # gl_FUNC_MEMMEM
# Prerequisites of lib/memmem.c.
AC_DEFUN([gl_PREREQ_MEMMEM], [:])
......@@ -332,6 +332,7 @@ UNEXEC_OBJ = @UNEXEC_OBJ@
DUMPING=@DUMPING@
CHECK_STRUCTS = @CHECK_STRUCTS@
HAVE_PDUMPER = @HAVE_PDUMPER@
# 'make' verbosity.
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
......@@ -627,19 +628,25 @@ LIBEGNU_ARCHIVE = $(lib)/lib$(if $(HYBRID_MALLOC),e)gnu.a
$(LIBEGNU_ARCHIVE): $(config_h)
$(MAKE) -C $(dir $@) all
FINGERPRINTED = $(LIBXMENU) $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES)
fingerprint.c: $(FINGERPRINTED) $(libsrc)/make-fingerprint$(EXEEXT)
$(AM_V_GEN)$(libsrc)/make-fingerprint$(EXEEXT) $(FINGERPRINTED) >$@.tmp
$(AM_V_at)mv $@.tmp $@
ifeq ($(HAVE_PDUMPER),yes)
MAKE_PDUMPER_FINGERPRINT = $(libsrc)/make-fingerprint$(EXEEXT)
else
MAKE_PDUMPER_FINGERPRINT =
endif
## We have to create $(etc) here because init_cmdargs tests its
## existence when setting Vinstallation_directory (FIXME?).
## This goes on to affect various things, and the emacs binary fails
## to start if Vinstallation_directory has the wrong value.
temacs$(EXEEXT): fingerprint.o $(charsets) $(charscript)
$(AM_V_CCLD)$(CC) -o $@ $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
$(ALLOBJS) fingerprint.o \
$(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES) \
$(charsets) $(charscript) $(MAKE_PDUMPER_FINGERPRINT)
$(AM_V_CCLD)$(CC) -o $@.tmp \
$(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
$(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
ifeq ($(HAVE_PDUMPER),yes)
$(AM_V_at)$(MAKE_PDUMPER_FINGERPRINT) $@.tmp
endif
$(AM_V_at)mv $@.tmp $@
$(MKDIR_P) $(etc)
ifeq ($(DUMPING),unexec)
ifneq ($(PAXCTL_notdumped),)
......@@ -676,7 +683,7 @@ ns-app: emacs$(EXEEXT) $(pdmp)
mostlyclean:
rm -f temacs$(EXEEXT) core ./*.core \#* ./*.o
rm -f dmpstruct.h fingerprint.c
rm -f dmpstruct.h
rm -f emacs.pdmp
rm -f ../etc/DOC
rm -f bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
......@@ -716,10 +723,9 @@ ETAGS = ../lib-src/etags${EXEEXT}
${ETAGS}: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Remove macuvs.h and fingerprint.c since they'd cause `src/emacs`
# Remove macuvs.h since it'd cause `src/emacs`
# to be built before we can get TAGS.
ctagsfiles1 = $(filter-out ${srcdir}/macuvs.h ${srcdir}/fingerprint.c, \
$(wildcard ${srcdir}/*.[hc]))
ctagsfiles1 = $(filter-out ${srcdir}/macuvs.h, $(wildcard ${srcdir}/*.[hc]))
ctagsfiles2 = $(wildcard ${srcdir}/*.m)
## In out-of-tree builds, TAGS are generated in the build dir, like
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment