On 2012-02-03, at 8:02 AM, Marc Feeley wrote:
I should have thought of that when writing the makefile. The rule .c.o in the makefile can be improved to use "gsc -obj" instead of "gcc -c" (or "g++ -c"). That way, the C compiler which was configured with the system will be used indirectly through a call to gsc, and there are no longer any dependencies on the specific setup of the target platform. In other words the makefile itself is very portable. The only portability issues left are the file extensions (for example Unix and MinGW use .o and .a and Microsoft Visual C++ uses .obj and .lib) and the program to create libraries ("ar" on Unix and MinGW and "link" on Microsoft Visual C++). These issues could be resolved by using the gambc-cc shell script which has this knowledge. For example, on Mac OS X
% gambc-cc LIB_EXTENSION .a
But accounting for this in the makefile to make it totally portable might make it very hard to understand. So I'm not sure what's best here, portability or maintainability.
Marc
I have committed a change to the gambc-cc script so that it can report the object file extension (for some reason it was missing). This makes it possible to write a makefile which abstracts the differences between various C compilers. Now a makefile can be written like this:
# example makefile to build an executable out of 2 Scheme libraries
# lib1 is composed of lib1-a.scm (Scheme code) and lib1-b.c (C code) # lib2 is composed of lib2-a.scm (Scheme code) and lib2-b.c (C code) # app is composed of lib1, lib2, and app.scm (Scheme code)
GSC=gsc -verbose
MAKE_LIB=ar -rc
LIB1_OBJECTS=lib1-a$(OBJ) lib1-b$(OBJ) LIB2_OBJECTS=lib2-a$(OBJ) lib2-b$(OBJ)
.SUFFIXES: .SUFFIXES: $(OBJ) .c .scm .exe
all clean: $(MAKE) $@-recursive LIB="`$(GSC) -e '(shell-command (string-append (path-expand "gambc-cc" (path-expand "~~bin")) " LIB_EXTENSION"))'`" OBJ="`$(GSC) -e '(shell-command (string-append (path-expand "gambc-cc" (path-expand "~~bin")) " OBJ_EXTENSION"))'`"
all-recursive: app.exe
clean-recursive: rm -f lib1-a.c lib1-a$(OBJ) lib1-b$(OBJ) lib1_.c lib1_$(OBJ) lib1$(LIB) lib2-a.c lib2-a$(OBJ) lib2-b$(OBJ) lib2_.c lib2_$(OBJ) lib2$(LIB) app.c app$(OBJ) app_.c app_$(OBJ) app.exe *~
.c$(OBJ): $(GSC) -obj -o $@ $*.c
.scm$(OBJ): $(GSC) -obj -keep-c -o $@ $*.scm
lib1_$(OBJ): $(LIB1_OBJECTS) $(GSC) -link -flat -o $*.c $(patsubst %$(OBJ),%.c,$^) $(GSC) -obj -o $@ -cc-options "-D___LIBRARY" $*.c
lib1$(LIB): $(LIB1_OBJECTS) lib1_$(OBJ) $(MAKE_LIB) $@ $^
lib2_$(OBJ): $(LIB2_OBJECTS) $(GSC) -link -flat -o $*.c $(patsubst %$(OBJ),%.c,$^) $(GSC) -obj -o $@ -cc-options "-D___LIBRARY" $*.c
lib2$(LIB): $(LIB2_OBJECTS) lib2_$(OBJ) $(MAKE_LIB) $@ $^
app.exe: lib1$(LIB) lib2$(LIB) app$(OBJ) $(GSC) -link -o $*_.c $(patsubst %$(LIB),%_.c,$^) $*.c $(GSC) -obj -o $*_$(OBJ) $*_.c $(GSC) -exe -o $@ -ld-options "$^" $*_$(OBJ)
The source code for an example project is attached below.
I'm considering adding a new compiler flag "-lib" to create libraries. This would combine the "gsc -link", the "gsc -obj" and MAKE_LIB into one command:
gsc -lib -o lib1.a lib1-a.scm lib1-b.c
I'm not sure however how to get this to work with separate compilation, because the .c files are required for the Scheme-level link, and the .o files are required for the C-level link, and it would be unfortunate to recompile the .c files every time the library is created.
Marc