CMUCL commit: src (8 files)
Raymond Toy
rtoy at common-lisp.net
Sat Jul 31 00:51:58 CEST 2010
Date: Friday, July 30, 2010 @ 18:51:58
Author: rtoy
Path: /project/cmucl/cvsroot/src
Added: lisp/mach-o.c
Modified: bootfiles/20a/boot-2010-07-1.lisp code/bsd-os.lisp
lisp/Config.x86_darwin lisp/lisp.c lisp/save.c tools/linker-x86.sh
tools/make-main-dist.sh
First cut at executable images on Darwin/x86. The resulting
executable appears to work!
bootfiles/20a/boot-2010-07-1.lisp:
o Add :executable for darwin/x86.
code/bsd-os.lisp:
o Make :elf and :mach-o runtime features too.
o Register :executable of :executable is defined.
lisp/Config.x86_darwin:
o Need mach-o.c
o Add exec-final.c
lisp/lisp.c:
o Don't include elf.h if we're on Darwin since Darwin uses Mach-O, not
ELF.
o For Darwin, we get the initial function address from
initial_function_addr, not from &initial_function_addr, like for
Linux.
lisp/save.c
o Don't include libgen.h and elf.h on Darwin.
tools/linker-x86.sh:
o Update to support Darwin.
tools/make-main-dist.sh:
o Add support for executables on Darwin.
lisp/mach-o.c:
o Initial support for writing Mach-O files for the Lisp spaces.
o Initial support for reading a Mach-O executable to find and map the
Lisp spaces.
-----------------------------------+
bootfiles/20a/boot-2010-07-1.lisp | 2
code/bsd-os.lisp | 8
lisp/Config.x86_darwin | 5
lisp/lisp.c | 10
lisp/mach-o.c | 393 ++++++++++++++++++++++++++++++++++++
lisp/save.c | 4
tools/linker-x86.sh | 46 +++-
tools/make-main-dist.sh | 32 +-
8 files changed, 468 insertions(+), 32 deletions(-)
Index: src/bootfiles/20a/boot-2010-07-1.lisp
diff -u src/bootfiles/20a/boot-2010-07-1.lisp:1.4 src/bootfiles/20a/boot-2010-07-1.lisp:1.5
--- src/bootfiles/20a/boot-2010-07-1.lisp:1.4 Wed Jul 21 09:32:25 2010
+++ src/bootfiles/20a/boot-2010-07-1.lisp Fri Jul 30 18:51:58 2010
@@ -34,5 +34,5 @@
)
;; Executable feature works on sparc!
-#+sparc
+#+(or sparc (and x86 darwin))
(pushnew :executable *features*)
Index: src/code/bsd-os.lisp
diff -u src/code/bsd-os.lisp:1.16 src/code/bsd-os.lisp:1.17
--- src/code/bsd-os.lisp:1.16 Tue Apr 20 13:57:43 2010
+++ src/code/bsd-os.lisp Fri Jul 30 18:51:58 2010
@@ -5,7 +5,7 @@
;;; Carnegie Mellon University, and has been placed in the public domain.
;;;
(ext:file-comment
- "$Header: /project/cmucl/cvsroot/src/code/bsd-os.lisp,v 1.16 2010-04-20 17:57:43 rtoy Exp $")
+ "$Header: /project/cmucl/cvsroot/src/code/bsd-os.lisp,v 1.17 2010-07-30 22:51:58 rtoy Exp $")
;;;
;;; **********************************************************************
;;;
@@ -35,11 +35,11 @@
#-(or freebsd NetBSD OpenBSD Darwin) :bsd)
#+elf
-(register-lisp-feature :elf)
+(register-lisp-runtime-feature :elf)
#+mach-o
-(register-lisp-feature :mach-o)
+(register-lisp-runtime-feature :mach-o)
-#+freebsd
+#+executable
(register-lisp-runtime-feature :executable)
(setq *software-type* #+OpenBSD "OpenBSD"
Index: src/lisp/Config.x86_darwin
diff -u src/lisp/Config.x86_darwin:1.8 src/lisp/Config.x86_darwin:1.9
--- src/lisp/Config.x86_darwin:1.8 Sun Jan 11 12:52:44 2009
+++ src/lisp/Config.x86_darwin Fri Jul 30 18:51:58 2010
@@ -12,7 +12,10 @@
UNDEFSYMPATTERN = -Xlinker -u -Xlinker &
-OS_SRC += Darwin-os.c
+OS_SRC += Darwin-os.c mach-o.c
OS_LINK_FLAGS = $(MIN_VER)
OS_LIBS =
+EXEC_FINAL_OBJ = exec-final.o
+
+
Index: src/lisp/lisp.c
diff -u src/lisp/lisp.c:1.72 src/lisp/lisp.c:1.73
--- src/lisp/lisp.c:1.72 Fri Jul 30 16:26:11 2010
+++ src/lisp/lisp.c Fri Jul 30 18:51:58 2010
@@ -1,7 +1,7 @@
/*
* main() entry point for a stand alone lisp image.
*
- * $Header: /project/cmucl/cvsroot/src/lisp/lisp.c,v 1.72 2010-07-30 20:26:11 rtoy Exp $
+ * $Header: /project/cmucl/cvsroot/src/lisp/lisp.c,v 1.73 2010-07-30 22:51:58 rtoy Exp $
*
*/
@@ -32,9 +32,11 @@
#include "core.h"
#include "save.h"
#include "lispregs.h"
-#if defined FEATURE_EXECUTABLE
+#if defined(FEATURE_EXECUTABLE)
+#if !defined(DARWIN)
#include "elf.h"
#endif
+#endif
/* SIGINT handler that invokes the monitor. */
@@ -437,8 +439,8 @@
lispobj initial_function = 0;
if (builtin_image_flag != 0) {
-#if defined(i386) && defined(__linux__)
- initial_function = initial_function_addr;
+#if defined(i386) && (defined(__linux__) || defined(DARWIN))
+ initial_function = (lispobj) initial_function_addr;
#else
initial_function = (lispobj) & initial_function_addr;
#endif
Index: src/lisp/mach-o.c
diff -u /dev/null src/lisp/mach-o.c:1.1
--- /dev/null Fri Jul 30 18:51:58 2010
+++ src/lisp/mach-o.c Fri Jul 30 18:51:58 2010
@@ -0,0 +1,393 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "os.h"
+#include "core.h"
+#include "internals.h"
+#include "globals.h"
+#include "validate.h"
+
+#include "mach-o/loader.h"
+
+#define LINKER_SCRIPT "linker-x86.sh"
+#define C_COMPILER "cc"
+
+typedef struct mach_header MachO_hdr;
+
+/* Elf data structures. */
+static MachO_hdr eh;
+
+/* Names of the Lisp image ELF sections. These names must be the same as
+ the corresponding names found in the linker script. */
+
+static char *section_names[] = {"CORDYN", "CORSTA", "CORRO"};
+
+/* Note: write errors are not fatal. */
+static int
+ewrite(int fd, const void *buf, size_t nbytes, const char *func)
+{
+ if (write(fd, buf, nbytes) < nbytes) {
+ perror(func);
+ return -1; /* Simple way to indicate error. */
+ }
+ return 0;
+}
+
+/*
+ Read errors are fatal, because these reads have to succeed for lisp to
+ get off the ground.
+ */
+static void
+eread(int d, void *buf, size_t nbytes, const char *func)
+{
+ int res = read(d, buf, nbytes);
+
+ if (res == -1) {
+ perror(func);
+ exit(-1);
+ }
+
+ if (res < nbytes) {
+ fprintf(stderr, "Short read in %s!\n", func);
+ exit(-1);
+ }
+}
+
+static void
+elseek(int d, off_t o, int whence, const char *func)
+{
+ if (lseek(d, o, whence) == -1) {
+ perror(func);
+ exit(-1);
+ }
+}
+
+
+static int
+create_elf_file (const char *dir, int id)
+{
+ char outfilename[FILENAME_MAX + 1];
+ int out;
+
+ /* Note: the space id will be either 1, 2 or 3. Subtract one to index
+ the name array. */
+ snprintf(outfilename, FILENAME_MAX, "%s/%s.o", dir, section_names[id - 1]);
+ out = open(outfilename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+
+ if(!out) {
+ perror("write_elf_object: can't open file");
+ fprintf(stderr, "%s\n", outfilename);
+ }
+
+ return out;
+}
+
+
+static int
+write_elf_header(int fd)
+{
+ extern MachO_hdr eh;
+
+ /* Ident array. */
+ eh.magic = MH_MAGIC;
+ /* Support any kind x86. (Should we be more specific?) */
+ eh.cputype = CPU_TYPE_I386;
+ eh.cpusubtype = CPU_SUBTYPE_I386_ALL;
+
+ eh.filetype = MH_OBJECT;
+
+ /* We only have 1 load command in our object */
+ eh.ncmds = 1;
+ /* Size of 1 segment command plus size of 1 section */
+ eh.sizeofcmds = sizeof(struct segment_command) + sizeof(struct section);
+ eh.flags = MH_NOUNDEFS | MH_NOMULTIDEFS;
+
+ return ewrite(fd, &eh, sizeof(MachO_hdr), __func__);
+}
+
+static int
+write_load_command(int fd, char* name, int length, os_vm_address_t start)
+{
+ struct segment_command lc;
+
+ lc.cmd = LC_SEGMENT;
+ /* Size is 1 segment command + 1 section command */
+ lc.cmdsize = sizeof(lc) + sizeof(struct section);
+ strncpy(lc.segname, name, sizeof(lc.segname));
+ lc.vmaddr = start;
+ lc.vmsize = length;
+ /* Offset where the data is. It's the header, the segment
+ * command, and one section */
+ lc.fileoff = lc.cmdsize + sizeof(struct mach_header);
+ lc.filesize = length;
+ lc.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
+ lc.initprot = lc.maxprot;
+ lc.nsects = 1;
+ lc.flags = 0;
+
+ return ewrite(fd, &lc, sizeof(lc), __func__);
+}
+
+static int
+write_section(int fd, int length, os_vm_address_t start, char* object_name)
+{
+ struct section sc;
+
+ strncpy(sc.sectname, object_name, sizeof(sc.sectname));
+ strncpy(sc.segname, object_name, sizeof(sc.segname));
+ sc.addr = start;
+ sc.size = length;
+ /* Offset of the data. We have one header, one segment and one
+ * section */
+ sc.offset = sizeof(struct mach_header) + sizeof(struct segment_command) +
+ sizeof(struct section);
+ sc.align = 12; /* Align on 2^12 = 4096 boundary */
+ sc.reloff = 0;
+ sc.nreloc = 0;
+ sc.flags = 0;
+ sc.reserved1 = 0;
+ sc.reserved2 = 0;
+
+ return ewrite(fd, &sc, sizeof(sc), __func__);
+}
+
+static int
+write_section_data(int fd, long length, os_vm_address_t real_addr)
+{
+ return ewrite(fd, (void *)real_addr, length, __func__);
+}
+
+
+int
+write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t end)
+{
+ int out = create_elf_file(dir, id);
+ int ret = 0;
+ /* The length should be a multiple of the page size. */
+ size_t length = end - start + (os_vm_page_size -
+ ((end - start) % os_vm_page_size));
+
+ if(id < 1 || id > 3) {
+ fprintf(stderr, "Invalid space id in %s: %d\n", __func__, id);
+ fprintf(stderr, "Executable not built.\n");
+ ret = -1;
+ }
+
+ /* Make id be 0-based to match array. */
+ id--;
+
+ if ((write_elf_header(out) == -1)
+ || (write_load_command(out, section_names[id], length, start) == -1)
+ || (write_section(out, length, start, section_names[id]) == -1)
+ || (write_section_data(out, length, start) == -1)) {
+ fprintf(stderr, "Executable not built.\n");
+ ret = -1;
+ }
+
+ close(out);
+ return ret;
+}
+
+void
+elf_cleanup(const char *dirname)
+{
+ char filename[FILENAME_MAX + 1];
+ int i;
+
+ /* Get rid of lisp space files. */
+ for(i = 0; i < 3; i++) {
+ /* Delete core space .o files. */
+ sprintf(filename, "%s/%s.o", dirname, section_names[i]);
+ unlink(filename);
+ }
+}
+
+int
+elf_run_linker(long init_func_address, char *file)
+{
+ lispobj libstring = SymbolValue(CMUCL_LIB); /* Get library: */
+ struct vector *vec = (struct vector *)PTR(libstring);
+ char *paths;
+ char command[FILENAME_MAX + 1];
+ char command_line[FILENAME_MAX + FILENAME_MAX + 10];
+ char *strptr;
+ struct stat st;
+ int ret;
+ extern int debug_lisp_search;
+#ifndef UNICODE
+ paths = strdup((char *)vec->data);
+#else
+ /*
+ * What should we do here with 16-bit characters? For now we just
+ * take the low 8-bits.
+ */
+ paths = malloc(vec->length);
+ {
+ int k;
+ unsigned short *data;
+ data = (unsigned short*) vec->data;
+
+ for (k = 0; k < vec->length; ++k) {
+ paths[k] = data[k] & 0xff;
+ }
+ }
+#endif
+ strptr = strtok(paths, ":");
+
+ if (debug_lisp_search) {
+ printf("Searching for linker.sh script\n");
+ }
+
+ while(strptr != NULL) {
+
+ sprintf(command, "%s/%s", strptr, LINKER_SCRIPT);
+
+ if (debug_lisp_search) {
+ printf(" %s\n", command);
+ }
+
+ if (stat(command, &st) == 0) {
+ extern int main();
+
+ free(paths);
+ printf("\t[%s: linking %s... \n", command, file);
+ fflush(stdout);
+ sprintf(command_line, "%s %s 0x%lx '%s' 0x%lx 0x%lx 0x%lx", command,
+ C_COMPILER, init_func_address, file,
+ (unsigned long) READ_ONLY_SPACE_START,
+ (unsigned long) STATIC_SPACE_START,
+ (unsigned long) DYNAMIC_0_SPACE_START);
+ ret = system(command_line);
+ if(ret == -1) {
+ perror("Can't run link script");
+ } else {
+ printf("\tdone]\n");
+ fflush(stdout);
+ }
+ return ret;
+ }
+ strptr = strtok(NULL, ":");
+ }
+
+ fprintf(stderr,
+ "Can't find %s script in CMUCL library directory list.\n", LINKER_SCRIPT);
+ free(paths);
+ return -1;
+}
+
+
+/* Read the ELF header from a file descriptor and stuff it into a
+ structure. Make sure it is really an elf header etc. */
+static void
+read_elf_header(int fd, MachO_hdr *ehp)
+{
+ eread(fd, ehp, sizeof(MachO_hdr), __func__);
+
+ if (ehp->magic != MH_MAGIC) {
+ fprintf(stderr,
+ "Bad ELF magic number --- not an elf file. Exiting in %s.\n",
+ __func__);
+ exit(-1);
+ }
+}
+
+
+/*
+ Map the built-in lisp core sections.
+
+ NOTE! We need to do this without using malloc because the memory layout
+ is not set until some time after this is done.
+*/
+void
+map_core_sections(const char *exec_name)
+{
+ int exec_fd;
+ int sections_remaining = 3;
+ int i, j;
+ extern int image_dynamic_space_size;
+ extern int image_static_space_size;
+ extern int image_read_only_space_size;
+
+ if (!(exec_fd = open(exec_name, O_RDONLY))) {
+ perror("Can't open executable!");
+ exit(-1);
+ }
+
+ read_elf_header(exec_fd, &eh);
+
+ for (i = 0; i < eh.ncmds && sections_remaining > 0; i++) {
+ struct load_command lc;
+ struct segment_command sc;
+
+ /* Read the load command and see if its segname matches one of
+ * our section names. If it does, save the file offset for
+ * later so we can map the data */
+
+ eread(exec_fd, &lc, sizeof(lc), __func__);
+ fprintf(stderr, "Load %d: cmd = %d, cmdsize = %d\n", i, lc.cmd, lc.cmdsize);
+
+ if (lc.cmd == LC_SEGMENT) {
+ /* Read the segment command and save the file offset */
+ fprintf(stderr, "Reading next %d bytes for SEGMENT\n", sizeof(sc) - sizeof(lc));
+ eread(exec_fd, &sc.segname, sizeof(sc) - sizeof(lc), __func__);
+ fprintf(stderr, "LC_SEGMENT: name = %s\n", sc.segname);
+
+ for (j = 0; j < 3; ++j) {
+ if (strncmp(sc.segname, section_names[j], sizeof(sc.segname)) == 0) {
+ /* Found a core segment. Map it! */
+ fprintf(stderr, "Matched!\n");
+ fprintf(stderr, " Fileoff = %ld\n", sc.fileoff);
+ fprintf(stderr, " vmaddr = 0x%lx\n", sc.vmaddr);
+ fprintf(stderr, " vmsize = 0x%lx\n", sc.vmsize);
+
+ if ((os_vm_address_t) os_map(exec_fd, sc.fileoff,
+ (os_vm_address_t) sc.vmaddr,
+ sc.vmsize)
+ == (os_vm_address_t) -1) {
+ fprintf(stderr, "%s: Can't map section %s\n", __func__, section_names[j]);
+ exit(-1);
+ }
+ switch (j) {
+ case 0:
+ /* Dynamic space */
+ image_dynamic_space_size = sc.vmsize;
+ break;
+ case 1:
+ /* Static space */
+ image_static_space_size = sc.vmsize;
+ break;
+ case 2:
+ /* Read only */
+ image_read_only_space_size = sc.vmsize;
+ break;
+ default:
+ /* Shouldn't happen! */
+ abort();
+ }
+ --sections_remaining;
+ break;
+ }
+ }
+ fprintf(stderr, "Reading %d remainder bytes left in command\n",
+ lc.cmdsize - sizeof(sc));
+ elseek(exec_fd, lc.cmdsize - sizeof(sc), SEEK_CUR, __func__);
+ } else {
+ /* Seek to the next command */
+ fprintf(stderr, "Seeking by %d bytes\n", lc.cmdsize - sizeof(lc));
+ elseek(exec_fd, lc.cmdsize - sizeof(lc), SEEK_CUR, __func__);
+ }
+ }
+
+ close(exec_fd);
+
+ if (sections_remaining != 0) {
+ fprintf(stderr, "Couldn't map all core sections! Exiting!\n");
+ exit(-1);
+ }
+}
+
Index: src/lisp/save.c
diff -u src/lisp/save.c:1.25 src/lisp/save.c:1.26
--- src/lisp/save.c:1.25 Fri Jul 30 16:26:11 2010
+++ src/lisp/save.c Fri Jul 30 18:51:58 2010
@@ -1,6 +1,6 @@
/*
- $Header: /project/cmucl/cvsroot/src/lisp/save.c,v 1.25 2010-07-30 20:26:11 rtoy Exp $
+ $Header: /project/cmucl/cvsroot/src/lisp/save.c,v 1.26 2010-07-30 22:51:58 rtoy Exp $
This code was written as part of the CMU Common Lisp project at
Carnegie Mellon University, and has been placed in the public domain.
@@ -28,9 +28,11 @@
#endif
#ifdef FEATURE_EXECUTABLE
+#if !defined(DARWIN)
#include <libgen.h>
#include "elf.h"
#endif
+#endif
extern int version;
Index: src/tools/linker-x86.sh
diff -u src/tools/linker-x86.sh:1.2 src/tools/linker-x86.sh:1.3
--- src/tools/linker-x86.sh:1.2 Fri Jul 30 16:26:12 2010
+++ src/tools/linker-x86.sh Fri Jul 30 18:51:58 2010
@@ -1,6 +1,6 @@
#!/bin/sh
-# $Id: linker-x86.sh,v 1.2 2010-07-30 20:26:12 rtoy Exp $
+# $Id: linker-x86.sh,v 1.3 2010-07-30 22:51:58 rtoy Exp $
# This file written by Raymond Toy as part of CMU Common Lisp and is
# placed in the public domain.
@@ -19,23 +19,53 @@
CCOMPILER=$1
IFADDR=$2
EXEC=$3
-RO_ADDR="-Wl,--section-start=CORRO=$4"
-STATIC_ADDR="-Wl,--section-start=CORSTA=$5"
-DYN_ADDR="-Wl,--section-start=CORDYN=$6"
OUTDIR=`dirname $EXEC`
OUTNAME=`basename $EXEC`
CMUCLLIB=`dirname $0`
-#OPT_IFADDR="-Wl,--defsym -Wl,initial_function_addr=$IFADDR"
-OPT_IFADDR="ifaddr.c"
-OPT_ARCHIVE="-Wl,--whole-archive -Wl,$CMUCLLIB/lisp.a -Wl,--no-whole-archive"
+# Name of file where we write the actual initial function address.
+OPT_IFADDR="cmu-ifaddr-$$.c"
+# Names of the core sections from Lisp.
OPT_CORE="CORRO.o CORSTA.o CORDYN.o"
+case `uname` in
+ Linux*)
+ # How to specify the starting address for each of the sections
+ RO_ADDR="-Wl,--section-start=CORRO=$4"
+ STATIC_ADDR="-Wl,--section-start=CORSTA=$5"
+ DYN_ADDR="-Wl,--section-start=CORDYN=$6"
+
+ #OPT_IFADDR="-Wl,--defsym -Wl,initial_function_addr=$IFADDR"
+
+ # Specify how to link the entire lisp.a library
+ OPT_ARCHIVE="-Wl,--whole-archive -Wl,$CMUCLLIB/lisp.a -Wl,--no-whole-archive"
+ # See Config.x86_linux
+ OS_LIBS=-ldl
+ ;;
+ Darwin*)
+ # How to specify the starting address for each of the sections
+ RO_ADDR="-segaddr CORRO $4"
+ STATIC_ADDR="-segaddr CORSTA $5"
+ DYN_ADDR="-segaddr CORDYN $6"
+
+ # Specify how to link the entire lisp.a library
+ OPT_ARCHIVE="-all_load $CMUCLLIB/lisp.a"
+
+ # Extra stuff. For some reason one __LINKEDIT segment is mapped
+ # just past the dynamic space. This messes things up, so we move it
+ # to another address. This seems to be free, at least on 10.5.
+
+ OPT_EXTRA="-segaddr __LINKEDIT 0x99000000"
+ # See Config.x86_darwin
+ OS_LIBS=
+ ;;
+esac
+
trap 'rm -f $OUTDIR/$OPT_IFADDR' 0
(cd $OUTDIR
echo "long initial_function_addr = $IFADDR;" > $OPT_IFADDR
-$CCOMPILER -m32 -o $OUTNAME -rdynamic $OPT_IFADDR $OPT_ARCHIVE $OPT_CORE $RO_ADDR $STATIC_ADDR $DYN_ADDR -ldl -lm)
+$CCOMPILER -m32 -o $OUTNAME -rdynamic $OPT_IFADDR $OPT_ARCHIVE $OPT_CORE $RO_ADDR $STATIC_ADDR $DYN_ADDR $OPT_EXTRA $OS_LIBS -lm)
Index: src/tools/make-main-dist.sh
diff -u src/tools/make-main-dist.sh:1.22 src/tools/make-main-dist.sh:1.23
--- src/tools/make-main-dist.sh:1.22 Thu Jul 29 00:34:10 2010
+++ src/tools/make-main-dist.sh Fri Jul 30 18:51:58 2010
@@ -51,19 +51,24 @@
esac
case $OS in
- FreeBSD*)
- EXECUTABLE=true
- SCRIPT=FreeBSD
- ;;
- linux*)
- EXECUTABLE=true
- SCRIPT=Linux
- ;;
- solaris*)
- EXECUTABLE=true
- SCRIPT=SunOS
- ;;
- *) EXECUTABLE="" ;;
+ FreeBSD*)
+ EXECUTABLE=true
+ SCRIPT=FreeBSD
+ ;;
+ linux*)
+ EXECUTABLE=true
+ SCRIPT=Linux
+ ;;
+ solaris*)
+ EXECUTABLE=true
+ SCRIPT=SunOS
+ ;;
+ darwin*)
+ EXECUTABLE=true
+ ;;
+ *)
+ EXECUTABLE=""
+ ;;
esac
# Frob PATH to use /usr/ucb/install for Solaris
@@ -93,6 +98,7 @@
install ${GROUP} ${OWNER} -m 0755 $TARGET/lisp/lisp.a $DESTDIR/lib/cmucl/lib/
install ${GROUP} ${OWNER} -m 0755 src/tools/linker.sh $DESTDIR/lib/cmucl/lib/
install ${GROUP} ${OWNER} -m 0755 src/tools/linker-x86.sh $DESTDIR/lib/cmucl/lib/
+ install ${GROUP} ${OWNER} -m 0755 src/tools/linker-darwin.sh $DESTDIR/lib/cmucl/lib/
install ${GROUP} ${OWNER} -m 0755 src/tools/$SCRIPT-cmucl-linker-script $DESTDIR/lib/cmucl/lib/
fi
for corefile in $TARGET/lisp/$CORE
More information about the cmucl-commit
mailing list