summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-27 16:29:52 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-27 16:29:52 -0700
commit53ab016bcb85e1b8924440907309b7b89449ca6f (patch)
tree865db22e13e478b06fccf9d164df803e9562390c
parentdbbf8084e8e4d6c30bf38d649c6cbbb2c86c0134 (diff)
downloadclink-master.tar.gz
clink-master.tar.bz2
clink-master.zip
Starting repo for clink.HEADmaster
This is old code developed in 2005 to replace the "clisp-link" script in the CLISP project with GNU Makefile rules. * Makefile: New file. * binding.lisp: New file. * call-in.lisp: New file. * call-out.c: New file. * clink.mk: New file. * main.lisp: New file.
-rw-r--r--Makefile66
-rw-r--r--binding.lisp15
-rw-r--r--call-in.lisp2
-rw-r--r--call-out.c9
-rw-r--r--clink.mk253
-rw-r--r--main.lisp2
6 files changed, 347 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c60caae
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,66 @@
+CFLAGS = $(CPPFLAGS)
+
+#
+# Set up namespace for clink.mk
+#
+
+CLK = CFOO_
+
+#
+# Set up input variables for clink.mk
+#
+
+CFOO_SOURCE_LS := full
+CFOO_TARGET_DIR := new/
+CFOO_MODULES := binding
+CFOO_OBJECTS := call-out.o
+CFOO_PRELOAD := call-in
+CFOO_LOAD := main
+
+#
+# all target should be the first one so make with no arguments
+# does "make all"
+#
+
+.PHONY all:
+
+all:
+
+#
+# bring in the magic!
+#
+
+include clink.mk
+
+#
+# a clean target which includes the output variable produces by
+# clink.mk, which expands to all of the targets and intermediate
+# files produced by the rules therein.
+#
+
+clean:
+ $(RM) $(CFOO_CLEAN) call-out.o
+
+#
+# Phony target all depends on the Lisp executable and memory
+# image, forcing them to be updated.
+#
+
+all: new/$(CFOO_LISPRUN) new/lispinit.mem
+
+#
+# Compiling the extra object files is outside of the responsibility
+# of clink.mk, but clink.mk does take care of Lisp -> FAS compiling
+# of all of the files mentioned in $(CLK)MODULES, $(CLK)PRELOAD and
+# $(CLK)LOAD.
+#
+
+call-out.o: call-out.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+#
+# A kind of test: after all the rules are read, if we switch the
+# namespace, it should not screw up any of the rule bodies.
+#
+
+CLK = BAR_
diff --git a/binding.lisp b/binding.lisp
new file mode 100644
index 0000000..a1c1e21
--- /dev/null
+++ b/binding.lisp
@@ -0,0 +1,15 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (setf ffi:*output-c-functions* t)
+ (setf ffi:*output-c-variables* t))
+
+(ffi:def-call-out call-out
+ (:language :stdc)
+ (:name "call_out")
+ (:arguments (value ffi:c-string))
+ (:return-type))
+
+(ffi:def-call-in call-in
+ (:language :stdc)
+ (:name "call_in")
+ (:arguments (value ffi:c-string))
+ (:return-type))
diff --git a/call-in.lisp b/call-in.lisp
new file mode 100644
index 0000000..e6b82b3
--- /dev/null
+++ b/call-in.lisp
@@ -0,0 +1,2 @@
+(defun call-in (x)
+ (format t "(call-in ~a)~%" x))
diff --git a/call-out.c b/call-out.c
new file mode 100644
index 0000000..42279a4
--- /dev/null
+++ b/call-out.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+extern void call_in(const char *);
+
+void call_out(const char *string)
+{
+ printf("call_out(\"%s\");\n", string);
+ call_in(string);
+}
diff --git a/clink.mk b/clink.mk
new file mode 100644
index 0000000..e9582ac
--- /dev/null
+++ b/clink.mk
@@ -0,0 +1,253 @@
+#
+# clink.mk
+# written by Kaz Kylheku
+# June 2005
+#
+# This a GNU Make include file that provides a system for creating a new CLISP
+# linking set by adding modules to an existing one. These rules meet several
+# objectives. They:
+#
+# - replace the arcane old 'clisp-link add-module-set' script;
+# - create a lisp image directly, without file copying, symbolic
+# links, generated shell scripts and other such things;
+# - do not require the added module to be located in a particular
+# directory setup with a link.sh script; all the files and dependencies
+# are handled by these rules;
+# - eliminate the use of clumsy symbolic links, since the new Lisp image
+# is linked directly out of the source directory, using relative paths.
+#
+# This makefile is intended to be included into another Makefile. It requires
+# certain inputs in the form of certain variables being set prior to the
+# inclusion. It produces outputs by assigning to variables.
+#
+# Input variables:
+#
+# CLK A string serving as the namespace for all internal
+# variables. This allows multiple independent instantiations
+# of the rules within a single GNU make process. If
+# you leave out this variable, it's set to CLINK_,
+# and so all the $(CLK)X variables become just CLINK_X.
+# $(CLK)SOURCE_LS The name of the existing CLISP linking set, such as
+# "base" or "full" (without the quotes). This makefile
+# will find the linking set by itself, provided that the
+# clisp executable is in the executable search path.
+# If this variable is not set, it takes on the default
+# value "base".
+# $(CLK)TARGET_DIR The directory where to place the resulting lisp.run
+# and lispinit.mem, with trailing slash!
+# $(CLK)MODULES Names of FFI modules with no .c or .lisp suffix.
+# It's assumed that for each of these, there is a .lisp
+# file containing CLISP FFI definitions, and is compiled
+# compiled to produce a .c file and a .fas file.
+# It's possible, but pointless, to leave this variable unset.
+# $(CLK)OBJECTS Optional names of additional object files and libraries to
+# load into the new CLISP executable.
+# $(CLK)PRELOAD If this is not empty, then the boostrapping process
+# will use an intermediate lispinit.mem, which will be
+# stuffed with the specified Lisp modules. Probably the
+# biggest use for this is to set up packages. If you are
+# using DEF-CALL-OUT to make Lisp functions callable from C,
+# and those functions are named by packaged symbols, then
+# the package has to exist in the lispinit.mem, otherwise
+# the lisp.run will fail to run at all. It will iterate
+# over its global linked list of modules and bail when
+# it sees references to nonexistent packages. But at this
+# point we haven't had a chance to build our lispinit.mem.
+# The way out of this chicken-egg problem is to build
+# an intermediate lispinit.mem.
+# $(CLK)LOAD List of Lisp modules to load into the final memory image,
+# not including those listed in $(CLK)MODULES.
+#
+# Output variables:
+#
+# $(CLK)CLEAN List of intermediate files to be blown away by
+# a "make clean".
+#
+
+# -- internals start here --
+
+#
+# Set up a default namespace
+#
+
+ifeq ($(CLK),)
+CLK := CLINK_
+endif
+
+ifeq ($($(CLK)SOURCE_LS),)
+$(CLK)SOURCE_LS := base
+endif
+
+#
+# $(CLK)CLISP_DIR holds the CLISP library directory, underneath which
+# one finds the linkkit and linking sets. E.g. /usr/local/lib/clisp
+#
+
+$(CLK)CLISP_DIR := $(shell clisp -q -norc -x \
+ '(progn (princ *lib-directory*) (values))')
+
+#
+# $(CLK)SOURCE_DIR is the source linking set, e.g. /usr/local/lib/clisp/full
+#
+
+$(CLK)SOURCE_DIR := $($(CLK)CLISP_DIR)$($(CLK)SOURCE_LS)/
+
+#
+# $(CLK)SOURCE_RUN is the Lisp executable in the source linking set.
+# It could be lisp.run, or lisp.exe on Cygwin. So we just get it
+# using wildcard expansion. (The GNU Make $(wildcard) function
+# doesn't expand variables in the pattern, so we use shell echo).
+#
+
+$(CLK)SOURCE_RUN := $(filter-out %lisp.a,\
+ $(shell echo $($(CLK)SOURCE_DIR)lisp.*))
+
+$(CLK)LISPRUN := $(notdir $($(CLK)SOURCE_RUN))
+
+#
+# $(CLK)RUN_TGT is the target lisp.run that we want to build.
+# $(CLK)MEM_TGT is the target lispinit.mem that we want to build.
+# The rules in this makefile update that target, as well as the memory image.
+# It's up to the parent makefile to hook these targets as dependencies in its
+# own set of rules, so that these targets actually get updated.
+#
+
+$(CLK)RUN_TGT := $($(CLK)TARGET_DIR)$($(CLK)LISPRUN)
+$(CLK)MEM_TGT := $($(CLK)TARGET_DIR)lispinit.mem
+$(CLK)MOD_TABLE_TGT := $($(CLK)TARGET_DIR)modules.o
+$(CLK)MOD_HEADER_TGT := $($(CLK)TARGET_DIR)modules.h
+$(CLK)PRELOAD_FAS_TGTS := $(addsuffix .fas,$($(CLK)PRELOAD))
+$(CLK)PRELOAD_LIB_TGTS := $(addsuffix .lib,$($(CLK)PRELOAD))
+$(CLK)LOAD_FAS_TGTS := $(addsuffix .fas,$($(CLK)LOAD))
+$(CLK)LOAD_LIB_TGTS := $(addsuffix .lib,$($(CLK)LOAD))
+$(CLK)FAS_TGTS := $(addsuffix .fas,$($(CLK)MODULES))
+$(CLK)C_TGTS := $(addsuffix .c,$($(CLK)MODULES))
+$(CLK)OBJ_TGTS := $(addsuffix .o,$($(CLK)MODULES))
+$(CLK)LIB_TGTS := $(addsuffix .lib,$($(CLK)MODULES))
+$(CLK)VARS_MKF := $($(CLK)TARGET_DIR)vars.mk
+$(CLK)CLEAN := $($(CLK)RUN_TGT) $($(CLK)MEM_TGT) $($(CLK)MOD_TABLE_TGT) \
+ $($(CLK)VARS_MKF) $($(CLK)FAS_TGTS) $($(CLK)C_TGTS) \
+ $($(CLK)OBJ_TGTS) $($(CLK)LIB_TGTS) $($(CLK)MOD_HEADER_TGT) \
+ $($(CLK)PRELOAD_FAS_TGTS) $($(CLK)PRELOAD_LIB_TGTS) \
+ $($(CLK)LOAD_FAS_TGTS) $($(CLK)LOAD_LIB_TGTS)
+$(CLK)ALL_OBJ_TGTS := $($(CLK)OBJ_TGTS) $($(CLK)MOD_TABLE_TGT)
+
+#
+# Rule to create the vars.mk file in the target directory.
+# This rule also creates the target directory, if it does
+# not exist. Since vars.mk is a dependency of this makefile
+# itself by way of include, this rule is processed first,
+# and so ensures that the target directory exist.
+#
+
+
+$($(CLK)VARS_MKF):
+ mkdir -p $(CLINK_TARGET_DIR)
+ . $(CLINK_SOURCE_DIR)makevars ; \
+ echo "\$$(\$$(CLK)RUN_TGT): CFLAGS += $$CFLAGS" > $@ ; \
+ echo "\$$(\$$(CLK)ALL_OBJ_TGTS): CPPFLAGS += $$CPPFLAGS" >> $@ ; \
+ echo "\$$(\$$(CLK)RUN_TGT): CLFLAGS += $$CLFLAGS" >> $@ ; \
+ echo "\$$(CLK)LIBS := $$LIBS" >> $@
+
+$($(CLK)MOD_TABLE_TGT): CFLAGS += -I$(CLINK_TARGET_DIR)
+
+$($(CLK)MOD_TABLE_TGT): $($(CLK)CLISP_DIR)linkkit/modules.c \
+ $($(CLK)MOD_HEADER_TGT)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$($(CLK)MOD_HEADER_TGT):
+ $(RM) $@
+ for mod in $(CLINK_MODULES) ; do echo "MODULE($$mod)" >> $@ ; done
+
+ifneq ($(MAKECMDGOALS),clean)
+include $($(CLK)VARS_MKF)
+endif
+
+#
+# $(CLK)SOURCE_ARS is the list of archive files in the source linking
+# set. We get this by way of the $(CLK)LIBS variable in the makevars file
+# in that directory, rather than by wildcard globbing. The reason for
+# that is that we don't want to mistakenly include libnoreadline.a.
+#
+
+$(CLK)SOURCE_ARS := $(foreach LIB,$($(CLK)LIBS),\
+ $(if $(filter -%,$(LIB)),,$($(CLK)SOURCE_DIR)$(LIB)))
+
+#
+# $(CLK)SOURCE_LIBS is a list of additional libraries that need
+# to be linked. Like $(CLK)SOURCE_ARS, this comes from the $(CLK)LIBS variable
+# in the makevars file of the source linking set.
+#
+
+$(CLK)SOURCE_LIBS := $(foreach LIB,$($(CLK)LIBS),\
+ $(if $(filter -%,$(LIB)),\
+ $(LIB),))
+
+$($(CLK)RUN_TGT): $($(CLK)SOURCE_ARS) $($(CLK)MOD_TABLE_TGT) \
+ $($(CLK)OBJ_TGTS) $($(CLK)OBJECTS)
+ $(CC) $(CFLAGS) $(CLFLAGS) -o $@ $^ $(CLINK_SOURCE_LIBS)
+
+$($(CLK)OBJ_TGTS): $($(CLK)C_TGTS)
+ $(CC) $(CFLAGS) -I$(CLINK_CLISP_DIR)linkkit -o $@ $^ -c
+
+$($(CLK)C_TGTS): %.c: %.lisp
+ "$(CLINK_SOURCE_RUN)" -B "$(CLINK_CLISP_DIR)" \
+ -M "$(CLINK_SOURCE_DIR)lispinit.mem" -q -c $<
+
+$($(CLK)PRELOAD_FAS_TGTS): %.fas: %.lisp
+ "$(CLINK_SOURCE_RUN)" -B "$(CLINK_CLISP_DIR)" \
+ -M "$(CLINK_SOURCE_DIR)lispinit.mem" -q -c $<
+
+$($(CLK)LOAD_FAS_TGTS): %.fas: %.lisp
+ "$(CLINK_RUN_TGT)" -B "$(CLINK_CLISP_DIR)" \
+ -M "$(CLINK_INTERMEDIATE_MEM)" -q -c $<
+
+#
+# If $(CLK)PRELOAD contains something, then we need to set up rules that
+# make an intermediate memory image by loading these files using the original
+# linking set. The new CLISP binary is then used in conjunction with this
+# intermediate image to load more Lisp code and dump the final image.
+#
+
+ifeq ($($(CLK)PRELOAD),)
+$(CLK)INTERMEDIATE_MEM := $($(CLK)SOURCE_DIR)lispinit.mem
+else
+$(CLK)INTERMEDIATE_MEM := $($(CLK)TARGET_DIR)intermediate.mem
+
+$(CLK)CLEAN += $($(CLK)INTERMEDIATE_MEM)
+
+$($(CLK)INTERMEDIATE_MEM): $($(CLK)PRELOAD_FAS_TGTS)
+ "$(CLINK_SOURCE_RUN)" -B "$(CLINK_CLISP_DIR)" \
+ -M "$(CLINK_SOURCE_DIR)lispinit.mem" -norc -q -i \
+ $(CLINK_PRELOAD) -x "(saveinitmem \"$@\")"
+endif
+
+$($(CLK)MEM_TGT): $($(CLK)RUN_TGT) $($(CLK)INTERMEDIATE_MEM) \
+ $($(CLK)FAS_TGTS) $($(CLK)LOAD_FAS_TGTS)
+ "$(CLINK_RUN_TGT)" -B "$(CLINK_CLISP_DIR)" \
+ -M "$(CLINK_INTERMEDIATE_MEM)" -norc -q -i \
+ $(CLINK_MODULES) $(CLINK_LOAD) -x "(saveinitmem \"$@\")"
+
+#
+# Hack: GNU Make has a problem. Variables that occur in
+# rule action bodies are expanded when those rules are run, not when
+# they are defined, and there doesn't appear to be a way to change
+# the behavior. So the namespace trick $($(CLK)VAR) won't work
+# within rule bodies; the value of the global variable CLK will be taken at the
+# time the rule is run to update its target, not at the time the makefile is
+# read out. The target-specific-assignment mechanism, however, gives us a kind
+# of dynamic scoping namespace surrounding a target, so here we exploit that to
+# create target-local ``bindings'' of all our global namespaced variables. We
+# use those bindings in rule bodies.
+#
+
+$($(CLK)CLEAN): CLINK_TARGET_DIR := $($(CLK)TARGET_DIR)
+$($(CLK)CLEAN): CLINK_CLISP_DIR := $($(CLK)CLISP_DIR)
+$($(CLK)CLEAN): CLINK_SOURCE_DIR := $($(CLK)SOURCE_DIR)
+$($(CLK)CLEAN): CLINK_SOURCE_RUN := $($(CLK)SOURCE_RUN)
+$($(CLK)CLEAN): CLINK_MODULES := $($(CLK)MODULES)
+$($(CLK)CLEAN): CLINK_SOURCE_LIBS := $($(CLK)SOURCE_LIBS)
+$($(CLK)CLEAN): CLINK_PRELOAD := $($(CLK)PRELOAD)
+$($(CLK)CLEAN): CLINK_LOAD := $($(CLK)LOAD)
+$($(CLK)CLEAN): CLINK_INTERMEDIATE_MEM := $($(CLK)INTERMEDIATE_MEM)
+$($(CLK)CLEAN): CLINK_RUN_TGT := $($(CLK)RUN_TGT)
diff --git a/main.lisp b/main.lisp
new file mode 100644
index 0000000..75ffce3
--- /dev/null
+++ b/main.lisp
@@ -0,0 +1,2 @@
+(defun main ()
+ (call-out "hello"))