Simplify GNU Make build config

This commit is contained in:
Justine Tunney 2023-12-06 03:24:35 -08:00
parent 394d998315
commit 7c39818c13
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
7 changed files with 10 additions and 1728 deletions

View file

@ -3,84 +3,20 @@
PKGS += THIRD_PARTY_MAKE
THIRD_PARTY_MAKE_COMS = \
o/$(MODE)/third_party/make/make.com
THIRD_PARTY_MAKE_A = o/$(MODE)/third_party/make/make.a
THIRD_PARTY_MAKE_FILES := $(wildcard third_party/make/*)
THIRD_PARTY_MAKE_HDRS = $(filter %.h,$(THIRD_PARTY_MAKE_FILES))
THIRD_PARTY_MAKE_SRCS = $(filter %.c,$(THIRD_PARTY_MAKE_FILES))
THIRD_PARTY_MAKE_OBJS = $(THIRD_PARTY_MAKE_SRCS:%.c=o/$(MODE)/%.o)
THIRD_PARTY_MAKE_COMS = o/$(MODE)/third_party/make/make.com
THIRD_PARTY_MAKE_CHECKS = $(THIRD_PARTY_MAKE_A).pkg
THIRD_PARTY_MAKE_BINS = \
$(THIRD_PARTY_MAKE_COMS) \
$(THIRD_PARTY_MAKE_COMS:%=%.dbg)
THIRD_PARTY_MAKE_A = \
o/$(MODE)/third_party/make/make.a
THIRD_PARTY_MAKE_HDRS = \
third_party/make/concat-filename.h \
third_party/make/commands.h \
third_party/make/glob.h \
third_party/make/config.h \
third_party/make/debug.h \
third_party/make/dep.h \
third_party/make/findprog.h \
third_party/make/filedef.h \
third_party/make/filename.h \
third_party/make/getopt.h \
third_party/make/gettext.h \
third_party/make/gnumake.h \
third_party/make/hash.h \
third_party/make/job.h \
third_party/make/makeint.h \
third_party/make/mkconfig.h \
third_party/make/mkcustom.h \
third_party/make/os.h \
third_party/make/output.h \
third_party/make/rule.h \
third_party/make/shuffle.h \
third_party/make/variable.h
THIRD_PARTY_MAKE_INCS = \
third_party/make/makeint.h
THIRD_PARTY_MAKE_CHECKS = \
$(THIRD_PARTY_MAKE_A).pkg
THIRD_PARTY_MAKE_SRCS = \
third_party/make/glob.c \
third_party/make/commands.c \
third_party/make/default.c \
third_party/make/dir.c \
third_party/make/concat-filename.c \
third_party/make/findprog-in.c \
third_party/make/expand.c \
third_party/make/file.c \
third_party/make/function.c \
third_party/make/getopt.c \
third_party/make/getopt1.c \
third_party/make/guile.c \
third_party/make/hash.c \
third_party/make/implicit.c \
third_party/make/job.c \
third_party/make/load.c \
third_party/make/loadapi.c \
third_party/make/main.c \
third_party/make/misc.c \
third_party/make/output.c \
third_party/make/posixos.c \
third_party/make/read.c \
third_party/make/remake.c \
third_party/make/remote-stub.c \
third_party/make/rule.c \
third_party/make/strcache.c \
third_party/make/variable.c \
third_party/make/version.c \
third_party/make/shuffle.c \
third_party/make/vpath.c
THIRD_PARTY_MAKE_OBJS = \
$(THIRD_PARTY_MAKE_SRCS:%.c=o/$(MODE)/%.o)
THIRD_PARTY_MAKE_DIRECTDEPS = \
LIBC_CALLS \
LIBC_ELF \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
@ -90,16 +26,10 @@ THIRD_PARTY_MAKE_DIRECTDEPS = \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_SOCK \
LIBC_NT_KERNEL32 \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_MUSL \
THIRD_PARTY_GDTOA
THIRD_PARTY_MUSL
THIRD_PARTY_MAKE_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_MAKE_DIRECTDEPS),$($(x))))
@ -122,14 +52,6 @@ o/$(MODE)/third_party/make/make.com.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/third_party/make/make.com: \
o/$(MODE)/third_party/make/make.com.dbg \
o/$(MODE)/third_party/zip/zip.com \
o/$(MODE)/tool/build/symtab.com
@$(MAKE_OBJCOPY)
@$(MAKE_SYMTAB_CREATE)
@$(MAKE_SYMTAB_ZIP)
o/$(MODE)/third_party/make/strcache.o \
o/$(MODE)/third_party/make/expand.o \
o/$(MODE)/third_party/make/read.o: private \
@ -146,6 +68,8 @@ $(THIRD_PARTY_MAKE_OBJS): private \
-DNO_ARCHIVES \
-DHAVE_CONFIG_H
$(THIRD_PARTY_MAKE_OBJS): third_party/make/BUILD.mk
.PHONY: o/$(MODE)/third_party/make
o/$(MODE)/third_party/make: \
$(THIRD_PARTY_MAKE_BINS) \

332
third_party/make/ar.c vendored
View file

@ -1,332 +0,0 @@
/* Interface to 'ar' archives for GNU Make.
Copyright (C) 1988-2023 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make 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 Make 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/>. */
#include "makeint.h"
#ifndef NO_ARCHIVES
#include "filedef.h"
#include "dep.h"
#include <fnmatch.h>
#include <intprops.h>
/* Return nonzero if NAME is an archive-member reference, zero if not. An
archive-member reference is a name like 'lib(member)' where member is a
non-empty string.
If a name like 'lib((entry))' is used, a fatal error is signaled at
the attempt to use this unsupported feature. */
int
ar_name (const char *name)
{
const char *p = strchr (name, '(');
const char *end;
if (p == NULL || p == name)
return 0;
end = p + strlen (p) - 1;
if (*end != ')' || end == p + 1)
return 0;
if (p[1] == '(' && end[-1] == ')')
OS (fatal, NILF, _("attempt to use unsupported feature: '%s'"), name);
return 1;
}
/* Parse the archive-member reference NAME into the archive and member names.
Creates one allocated string containing both names, pointed to by ARNAME_P.
MEMNAME_P points to the member. */
void
ar_parse_name (const char *name, char **arname_p, char **memname_p)
{
char *p;
*arname_p = xstrdup (name);
p = strchr (*arname_p, '(');
/* This is never called unless ar_name() is true so p cannot be NULL. */
if (!p)
OS (fatal, NILF, "Internal: ar_parse_name: bad name '%s'", *arname_p);
*(p++) = '\0';
p[strlen (p) - 1] = '\0';
*memname_p = p;
}
/* This function is called by 'ar_scan' to find which member to look at. */
/* ARGSUSED */
static intmax_t
ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, intmax_t date,
int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
const void *name)
{
return ar_name_equal (name, mem, truncated) ? date : 0;
}
/* Return the modtime of NAME. */
time_t
ar_member_date (const char *name)
{
char *arname;
char *memname;
intmax_t val;
ar_parse_name (name, &arname, &memname);
/* Make sure we know the modtime of the archive itself because we are
likely to be called just before commands to remake a member are run,
and they will change the archive itself.
But we must be careful not to enter_file the archive itself if it does
not exist, because pattern_search assumes that files found in the data
base exist or can be made. */
{
struct file *arfile;
arfile = lookup_file (arname);
if (arfile == 0 && file_exists_p (arname))
arfile = enter_file (strcache_add (arname));
if (arfile != 0)
(void) f_mtime (arfile, 0);
}
val = ar_scan (arname, ar_member_date_1, memname);
free (arname);
return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
}
/* Set the archive-member NAME's modtime to now. */
#ifdef VMS
int
ar_touch (const char *name)
{
O (error, NILF, _("touch archive member is not available on VMS"));
return -1;
}
#else
int
ar_touch (const char *name)
{
char *arname, *memname;
int val;
ar_parse_name (name, &arname, &memname);
/* Make sure we know the modtime of the archive itself before we
touch the member, since this will change the archive modtime. */
{
struct file *arfile;
arfile = enter_file (strcache_add (arname));
f_mtime (arfile, 0);
}
val = 1;
switch (ar_member_touch (arname, memname))
{
case -1:
OS (error, NILF, _("touch: Archive '%s' does not exist"), arname);
break;
case -2:
OS (error, NILF, _("touch: '%s' is not a valid archive"), arname);
break;
case -3:
perror_with_name ("touch: ", arname);
break;
case 1:
OSS (error, NILF,
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
break;
case 0:
val = 0;
break;
default:
OS (error, NILF,
_("touch: Bad return code from ar_member_touch on '%s'"), name);
}
free (arname);
return val;
}
#endif /* !VMS */
/* State of an 'ar_glob' run, passed to 'ar_glob_match'. */
/* On VMS, (object) modules in libraries do not have suffixes. That is, to
find a match for a pattern, the pattern must not have any suffix. So the
suffix of the pattern is saved and the pattern is stripped (ar_glob).
If there is a match and the match, which is a module name, is added to
the chain, the saved suffix is added back to construct a source filename
(ar_glob_match). */
struct ar_glob_state
{
const char *arname;
const char *pattern;
#ifdef VMS
char *suffix;
#endif
size_t size;
struct nameseq *chain;
unsigned int n;
};
/* This function is called by 'ar_scan' to match one archive
element against the pattern in STATE. */
static intmax_t
ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, intmax_t date UNUSED, int uid UNUSED,
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
{
struct ar_glob_state *state = (struct ar_glob_state *)arg;
if (fnmatch (state->pattern, mem, FNM_PATHNAME|FNM_PERIOD) == 0)
{
/* We have a match. Add it to the chain. */
struct nameseq *new = xcalloc (state->size);
#ifdef VMS
if (state->suffix)
new->name = strcache_add(
concat(5, state->arname, "(", mem, state->suffix, ")"));
else
#endif
new->name = strcache_add(concat(4, state->arname, "(", mem, ")"));
new->next = state->chain;
state->chain = new;
++state->n;
}
return 0;
}
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
static int
ar_glob_pattern_p (const char *pattern, int quote)
{
const char *p;
int opened = 0;
for (p = pattern; *p != '\0'; ++p)
switch (*p)
{
case '?':
case '*':
return 1;
case '\\':
if (quote)
++p;
break;
case '[':
opened = 1;
break;
case ']':
if (opened)
return 1;
break;
}
return 0;
}
/* Glob for MEMBER_PATTERN in archive ARNAME.
Return a malloc'd chain of matching elements (or nil if none). */
struct nameseq *
ar_glob (const char *arname, const char *member_pattern, size_t size)
{
struct ar_glob_state state;
struct nameseq *n;
const char **names;
unsigned int i;
#ifdef VMS
char *vms_member_pattern;
#endif
if (! ar_glob_pattern_p (member_pattern, 1))
return 0;
/* Scan the archive for matches.
ar_glob_match will accumulate them in STATE.chain. */
state.arname = arname;
state.pattern = member_pattern;
#ifdef VMS
{
/* In a copy of the pattern, find the suffix, save it and remove it from
the pattern */
char *lastdot;
vms_member_pattern = xstrdup(member_pattern);
lastdot = strrchr(vms_member_pattern, '.');
state.suffix = lastdot;
if (lastdot)
{
state.suffix = xstrdup(lastdot);
*lastdot = 0;
}
state.pattern = vms_member_pattern;
}
#endif
state.size = size;
state.chain = 0;
state.n = 0;
ar_scan (arname, ar_glob_match, &state);
#ifdef VMS
/* Deallocate any duplicated string */
free(vms_member_pattern);
if (state.suffix)
{
free(state.suffix);
}
#endif
if (state.chain == 0)
return 0;
/* Now put the names into a vector for sorting. */
names = alloca (state.n * sizeof (const char *));
i = 0;
for (n = state.chain; n != 0; n = n->next)
names[i++] = n->name;
/* Sort them alphabetically. */
/* MSVC erroneously warns without a cast here. */
qsort ((void *)names, i, sizeof (*names), alpha_compare);
/* Put them back into the chain in the sorted order. */
i = 0;
for (n = state.chain; n != 0; n = n->next)
n->name = names[i++];
return state.chain;
}
#endif /* Not NO_ARCHIVES. */

File diff suppressed because it is too large Load diff

View file

@ -1,297 +0,0 @@
/* GNU Make remote job exportation interface to the Customs daemon.
THIS CODE IS NOT SUPPORTED BY THE GNU PROJECT.
Please do not send bug reports or questions about it to
the Make maintainers.
Copyright (C) 1988-2023 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make 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 Make 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/>. */
#include "makeint.h"
#include "filedef.h"
#include "job.h"
#include "commands.h"
#include "debug.h"
#if HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netdb.h>
#include "customs.h"
char *remote_description = "Customs";
/* File name of the Customs 'export' client command.
A full path name can be used to avoid some path-searching overhead. */
#define EXPORT_COMMAND "/usr/local/bin/export"
/* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */
static ExportPermit permit;
/* Normalized path name of the current directory. */
static char *normalized_cwd;
/* Call once at startup even if no commands are run. */
void
remote_setup (void)
{
}
/* Called before exit. */
void
remote_cleanup (void)
{
}
/* Return nonzero if the next job should be done remotely. */
int
start_remote_job_p (int first_p)
{
static int inited = 0;
int status;
int njobs;
if (!inited)
{
/* Allow the user to turn off job exportation (useful while he is
debugging Customs, for example). */
if (getenv ("GNU_MAKE_NO_CUSTOMS") != 0)
{
inited = -1;
return 0;
}
if (ISDB (DB_JOBS))
Rpc_Debug (1);
/* Ping the daemon once to see if it is there. */
inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1;
if (starting_directory == 0)
/* main couldn't figure it out. */
inited = -1;
else
{
/* Normalize the current directory path name to something
that should work on all machines exported to. */
normalized_cwd = xmalloc (GET_PATH_MAX);
strcpy (normalized_cwd, starting_directory);
if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0)
/* Path normalization failure means using Customs
won't work, but it's not really an error. */
inited = -1;
}
}
if (inited < 0)
return 0;
njobs = job_slots_used;
if (!first_p)
njobs -= 1; /* correction for being called from reap_children() */
/* the first job should run locally, or, if the -l flag is given, we use
that as clue as to how many local jobs should be scheduled locally */
if (max_load_average < 0 && njobs == 0 || njobs < max_load_average)
return 0;
status = Customs_Host (EXPORT_SAME, &permit);
if (status != RPC_SUCCESS)
{
DB (DB_JOBS, (_("Customs won't export: %s\n"),
Rpc_ErrorMessage (status)));
return 0;
}
return !CUSTOMS_FAIL (&permit.addr);
}
/* Start a remote job running the command in ARGV, with environment from
ENVP. It gets standard input from STDIN_FD. On failure, return
nonzero. On success, return zero, and set *USED_STDIN to nonzero if it
will actually use STDIN_FD, zero if not, set *ID_PTR to a unique
identification, and set *IS_REMOTE to nonzero if the job is remote, zero
if it is local (meaning *ID_PTR is a process ID). */
int
start_remote_job (char **argv, char **envp, int stdin_fd,
int *is_remote, pid_t *id_ptr, int *used_stdin)
{
char waybill[MAX_DATA_SIZE], msg[128];
struct hostent *host;
struct timeval timeout;
struct sockaddr_in sin;
int len;
int retsock, retport, sock;
Rpc_Stat status;
pid_t pid;
/* Create the return socket. */
retsock = Rpc_UdpCreate (True, 0);
if (retsock < 0)
{
O (error, NILF, "exporting: Couldn't create return socket.");
return 1;
}
/* Get the return socket's port number. */
len = sizeof (sin);
if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0)
{
(void) close (retsock);
perror_with_name ("exporting: ", "getsockname");
return 1;
}
retport = sin.sin_port;
/* Create the TCP socket for talking to the remote child. */
sock = Rpc_TcpCreate (False, 0);
/* Create a WayBill to give to the server. */
len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv,
envp, retport, waybill);
/* Modify the waybill for the child's uid/gid. */
{
WayBill *wb = (WayBill *) waybill;
wb->ruid = wb->euid;
wb->rgid = wb->egid;
}
/* Send the request to the server, timing out in 20 seconds. */
timeout.tv_usec = 0;
timeout.tv_sec = 20;
sin.sin_family = AF_INET;
sin.sin_port = htons (Customs_Port ());
sin.sin_addr = permit.addr;
status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
len, (Rpc_Opaque) waybill,
sizeof (msg), (Rpc_Opaque) msg,
1, &timeout);
host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
{
const char *hnm = host ? host->h_name : inet_ntoa (permit.addr);
size_t hlen = strlen (hnm);
if (status != RPC_SUCCESS)
{
const char *err = Rpc_ErrorMessage (status);
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (err),
"exporting to %s: %s", hnm, err);
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (msg), "exporting to %s: %s", hnm, msg);
return 1;
}
else
{
error (NILF, hlen + INTSTR_LENGTH,
"*** exported to %s (id %u)", hnm, permit.id);
}
fflush (stdout);
fflush (stderr);
}
pid = vfork ();
if (pid < 0)
{
/* The fork failed! */
perror_with_name ("fork", "");
return 1;
}
else if (pid == 0)
{
/* Child side. Run 'export' to handle the connection. */
static char sock_buf[INTSTR_LENGTH], retsock_buf[INTSTR_LENGTH];
static char id_buf[INTSTR_LENGTH];
static char *new_argv[6] =
{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };
/* Set up the arguments. */
(void) sprintf (sock_buf, "%d", sock);
(void) sprintf (retsock_buf, "%d", retsock);
(void) sprintf (id_buf, "%x", permit.id);
/* Get the right stdin. */
if (stdin_fd != 0)
(void) dup2 (stdin_fd, 0);
/* Unblock signals in the child. */
unblock_all_sigs ();
/* Run the command. */
exec_command (new_argv, envp);
}
/* Parent side. Return the 'export' process's ID. */
(void) close (retsock);
(void) close (sock);
*is_remote = 0;
*id_ptr = pid;
*used_stdin = 1;
return 0;
}
/* Get the status of a dead remote child. Block waiting for one to die
if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
to the termination signal or zero if it exited normally, and *COREDUMP_PTR
nonzero if it dumped core. Return the ID of the child that died,
0 if we would have to block and !BLOCK, or < 0 if there were none. */
int
remote_status (int *exit_code_ptr, int *signal_ptr, int *coredump_ptr,
int block)
{
return -1;
}
/* Block asynchronous notification of remote child death.
If this notification is done by raising the child termination
signal, do not block that signal. */
void
block_remote_children (void)
{
return;
}
/* Restore asynchronous notification of remote child death.
If this is done by raising the child termination signal,
do not unblock that signal. */
void
unblock_remote_children (void)
{
return;
}
/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */
int
remote_kill (pid_t id, int sig)
{
return -1;
}