Let's say I have the following set of files ...
f1a.scm and f1b.c
f2a.scm and f2b.c
f3.scm
File f1a.scm contains scheme procedures that call C functions in f1b.c.
File f2a.scm contains scheme procedures that call C funcitons in f2b.c.
I would like to build a static library f1.a from f1a.scm and f1b.c,
and likewise I wish to build a static library f2.a from f2a.scm and f2b.c.
Finally, assume f3.scm will call scheme procedures from both the f1.a and f2.a static libraries.
What are the appropriate commands for:
1) building the f1.a and f2.a static libraries
2) compiling and linking f3.scm with *both* of those static libraries at the same time.
(I'm looking for an example using gcc on a Linux platform.)
Afficher les réponses par date
On 2012-02-02, at 10:45 AM, REPLeffect wrote:
Let's say I have the following set of files ...
f1a.scm and f1b.c
f2a.scm and f2b.c
f3.scm
File f1a.scm contains scheme procedures that call C functions in f1b.c.
File f2a.scm contains scheme procedures that call C funcitons in f2b.c.
I would like to build a static library f1.a from f1a.scm and f1b.c,
and likewise I wish to build a static library f2.a from f2a.scm and f2b.c.
Finally, assume f3.scm will call scheme procedures from both the f1.a and f2.a static libraries.
What are the appropriate commands for:
building the f1.a and f2.a static libraries
compiling and linking f3.scm with *both* of those static libraries
at the same time.
(I'm looking for an example using gcc on a Linux platform.)
Here are the steps. The gist is that you have to create flat link files for each library, and then create an incremental link file for the final executable from the library link files.
gsc -c -o f1a.c f1a.scm gsc -obj -o f1a.o f1a.c gcc -c -o f1b.o f1b.c gsc -link -flat -o f1_.c f1a.c f1b.c *** WARNING -- "display" is not defined, *** referenced in: ("f1a.c") gsc -obj -o f1_.o -cc-options "-D___LIBRARY" f1_.c ar -rc f1.a f1a.o f1b.o f1_.o gsc -c -o f2a.c f2a.scm gsc -obj -o f2a.o f2a.c gcc -c -o f2b.o f2b.c gsc -link -flat -o f2_.c f2a.c f2b.c *** WARNING -- "display" is not defined, *** referenced in: ("f2a.c") gsc -obj -o f2_.o -cc-options "-D___LIBRARY" f2_.c ar -rc f2.a f2a.o f2b.o f2_.o gsc -c -o f3.c f3.scm gsc -obj -o f3.o f3.c gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o f3.exe -ld-options "f1.a f2.a" f3_.o f3.o
I have included a tar file which contains an example with makefile. It has been tested on Linux and Mac OS X.
Marc
On Thu, Feb 2, 2012 at 11:03 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-02-02, at 10:45 AM, REPLeffect wrote:
Let's say I have the following set of files ...
f1a.scm and f1b.c
f2a.scm and f2b.c
f3.scm
File f1a.scm contains scheme procedures that call C functions in f1b.c.
File f2a.scm contains scheme procedures that call C funcitons in f2b.c.
I would like to build a static library f1.a from f1a.scm and f1b.c,
and likewise I wish to build a static library f2.a from f2a.scm and f2b.c.
Finally, assume f3.scm will call scheme procedures from both the f1.a and f2.a static libraries.
What are the appropriate commands for:
building the f1.a and f2.a static libraries
compiling and linking f3.scm with *both* of those static libraries
at the same time.
(I'm looking for an example using gcc on a Linux platform.)
Here are the steps. The gist is that you have to create flat link files for each library, and then create an incremental link file for the final executable from the library link files.
gsc -c -o f1a.c f1a.scm gsc -obj -o f1a.o f1a.c gcc -c -o f1b.o f1b.c gsc -link -flat -o f1_.c f1a.c f1b.c *** WARNING -- "display" is not defined, *** referenced in: ("f1a.c") gsc -obj -o f1_.o -cc-options "-D___LIBRARY" f1_.c ar -rc f1.a f1a.o f1b.o f1_.o gsc -c -o f2a.c f2a.scm gsc -obj -o f2a.o f2a.c gcc -c -o f2b.o f2b.c gsc -link -flat -o f2_.c f2a.c f2b.c *** WARNING -- "display" is not defined, *** referenced in: ("f2a.c") gsc -obj -o f2_.o -cc-options "-D___LIBRARY" f2_.c ar -rc f2.a f2a.o f2b.o f2_.o gsc -c -o f3.c f3.scm gsc -obj -o f3.o f3.c gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o f3.exe -ld-options "f1.a f2.a" f3_.o f3.o
I have included a tar file which contains an example with makefile. It has been tested on Linux and Mac OS X.
Marc
OK, now I don't feel quite so stupid for not being able to figure it out on my own :-D
I was pretty sure the link files were my problem, but I wasn't sure how to get from point A to point B. Unless I'm just blind (which is always a possibility) there aren't any examples in the manual of creating a static library, and I didn't have any luck finding what I was looking for in the mailing list archive.
Thanks again for the superb and timely help, Marc!
On Thu, Feb 2, 2012 at 11:03 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-02-02, at 10:45 AM, REPLeffect wrote:
Let's say I have the following set of files ...
f1a.scm and f1b.c
f2a.scm and f2b.c
f3.scm
File f1a.scm contains scheme procedures that call C functions in f1b.c.
File f2a.scm contains scheme procedures that call C funcitons in f2b.c.
I would like to build a static library f1.a from f1a.scm and f1b.c,
and likewise I wish to build a static library f2.a from f2a.scm and f2b.c.
Finally, assume f3.scm will call scheme procedures from both the f1.a and f2.a static libraries.
What are the appropriate commands for:
building the f1.a and f2.a static libraries
compiling and linking f3.scm with *both* of those static libraries
at the same time.
(I'm looking for an example using gcc on a Linux platform.)
Here are the steps. The gist is that you have to create flat link files for each library, and then create an incremental link file for the final executable from the library link files.
gsc -c -o f1a.c f1a.scm gsc -obj -o f1a.o f1a.c gcc -c -o f1b.o f1b.c gsc -link -flat -o f1_.c f1a.c f1b.c *** WARNING -- "display" is not defined, *** referenced in: ("f1a.c") gsc -obj -o f1_.o -cc-options "-D___LIBRARY" f1_.c ar -rc f1.a f1a.o f1b.o f1_.o gsc -c -o f2a.c f2a.scm gsc -obj -o f2a.o f2a.c gcc -c -o f2b.o f2b.c gsc -link -flat -o f2_.c f2a.c f2b.c *** WARNING -- "display" is not defined, *** referenced in: ("f2a.c") gsc -obj -o f2_.o -cc-options "-D___LIBRARY" f2_.c ar -rc f2.a f2a.o f2b.o f2_.o gsc -c -o f3.c f3.scm gsc -obj -o f3.o f3.c gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o f3.exe -ld-options "f1.a f2.a" f3_.o f3.o
I have included a tar file which contains an example with makefile. It has been tested on Linux and Mac OS X.
Marc
I finally tried actually building the contents of the tar file (silly me, I should have done that right away).
Here are the results I got:
$ make gsc -c -o f1a.c f1a.scm gsc -obj -o f1a.o f1a.c gcc -c -o f1b.o f1b.c gsc -link -flat -o f1_.c f1a.c f1b.c *** WARNING -- "display" is not defined, *** referenced in: ("f1a.c") gsc -obj -o f1_.o -cc-options "-D___LIBRARY" f1_.c ar -rc f1.a f1a.o f1b.o f1_.o gsc -c -o f2a.c f2a.scm gsc -obj -o f2a.o f2a.c gcc -c -o f2b.o f2b.c gsc -link -flat -o f2_.c f2a.c f2b.c *** WARNING -- "display" is not defined, *** referenced in: ("f2a.c") gsc -obj -o f2_.o -cc-options "-D___LIBRARY" f2_.c ar -rc f2.a f2a.o f2b.o f2_.o gsc -c -o f3.c f3.scm gsc -obj -o f3.o f3.c gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o f3.exe -ld-options "f1.a f2.a" f3_.o f3.o f1.a(f1a.o): In function `___H__20_f1a(___processor_state_struct*)': f1a.c:(.text+0x126): undefined reference to `f1b_hello()' f2.a(f2a.o): In function `___H__20_f2a(___processor_state_struct*)': f2a.c:(.text+0x126): undefined reference to `f2b_hello()' collect2: ld returned 1 exit status *** ERROR IN ##main -- C link failed while linking "f3_.o" "f3.o" make: *** [f3.exe] Error 70
I suspected this was due to the fact that I am using Gambit 4.6.3 compiled with --enable-cplusplus. Sure enough, I compiled another copy without the -enable-cplusplus option, and the code above compiles fine on it.
Then I finally woke up from my stupor, and changed the call to "gcc" on line 7 of the makefile to "g++".
Sometimes I wonder what exotic places my brain visits when it is "on vacation", and if it had a good time while it was there. :-D
On 2012-02-03, at 3:50 AM, REPLeffect wrote:
I finally tried actually building the contents of the tar file (silly me, I should have done that right away).
Here are the results I got:
$ make gsc -c -o f1a.c f1a.scm gsc -obj -o f1a.o f1a.c gcc -c -o f1b.o f1b.c gsc -link -flat -o f1_.c f1a.c f1b.c *** WARNING -- "display" is not defined, *** referenced in: ("f1a.c") gsc -obj -o f1_.o -cc-options "-D___LIBRARY" f1_.c ar -rc f1.a f1a.o f1b.o f1_.o gsc -c -o f2a.c f2a.scm gsc -obj -o f2a.o f2a.c gcc -c -o f2b.o f2b.c gsc -link -flat -o f2_.c f2a.c f2b.c *** WARNING -- "display" is not defined, *** referenced in: ("f2a.c") gsc -obj -o f2_.o -cc-options "-D___LIBRARY" f2_.c ar -rc f2.a f2a.o f2b.o f2_.o gsc -c -o f3.c f3.scm gsc -obj -o f3.o f3.c gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o f3.exe -ld-options "f1.a f2.a" f3_.o f3.o f1.a(f1a.o): In function `___H__20_f1a(___processor_state_struct*)': f1a.c:(.text+0x126): undefined reference to `f1b_hello()' f2.a(f2a.o): In function `___H__20_f2a(___processor_state_struct*)': f2a.c:(.text+0x126): undefined reference to `f2b_hello()' collect2: ld returned 1 exit status *** ERROR IN ##main -- C link failed while linking "f3_.o" "f3.o" make: *** [f3.exe] Error 70
I suspected this was due to the fact that I am using Gambit 4.6.3 compiled with --enable-cplusplus. Sure enough, I compiled another copy without the -enable-cplusplus option, and the code above compiles fine on it.
Then I finally woke up from my stupor, and changed the call to "gcc" on line 7 of the makefile to "g++".
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
P.S. Here is the improved makefile:
.SUFFIXES: .SUFFIXES: .o .c .scm .exe
all: f3.exe
.c.o: gsc -obj -o $@ $*.c
.scm.o: gsc -c -o $*.c $*.scm gsc -obj -o $@ $*.c
f1_.o: f1a.o f1b.o gsc -link -flat -o $*.c f1a.c f1b.c gsc -obj -o $@ -cc-options "-D___LIBRARY" $*.c
f2_.o: f2a.o f2b.o gsc -link -flat -o $*.c f2a.c f2b.c gsc -obj -o $@ -cc-options "-D___LIBRARY" $*.c
f1.a: f1a.o f1b.o f1_.o ar -rc $@ $^
f2.a: f2a.o f2b.o f2_.o ar -rc $@ $^
f3.exe: f1.a f2.a f3.o gsc -link -o f3_.c f1_.c f2_.c f3.c gsc -obj -o f3_.o f3_.c gsc -exe -o $@ -ld-options "f1.a f2.a" f3_.o f3.o
clean: rm -f f1a.c f1_.c f2a.c f2_.c f3.c f3_.c *.o *.exe *.a *~
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
[snip]
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
It is probably just a matter of personal taste, but I actually prefer doing the individual steps separately. I generally don't go straight from a .scm file to an object file or an executable. I write my makefiles to generate the C files from the .scm files, then generate the link file(s), then compile the C files to .o files, then separately link the .o files into an executable. But that's just me.
In the case of the -lib flag, couldn't you have -keep-c turned on by default whenever -lib is used (and then only rebuild the *.scm file when the *.c file isn't up-to-date)? Then you could add a -no-keep-c flag, or whatever you wish to call it, for any masochist who wishes to rebuild every time :-D. Of course, I'm probably going to continue to do my builds explicitly in separate steps, so perhaps I'm not the right person to ask how it should work.
On Fri, 2012-02-03 at 11:07 -0500, Marc Feeley wrote:
I have committed a change to the gambc-cc script ...
With the following commands:
493 14:14 tar zxf gambc-v4_6_3-devel.tgz 494 14:14 cd gambc-v4_6_3-devel 495 14:14 gsi -v 496 14:14 ./configure 'CC=gcc -march=native -fschedule-insns -frename-registers' '--enable-single-host' '--enable-shared' '--enable-multiple-versions' 497 14:15 make -j 4 498 14:17 make doc 499 14:18 git pull http://www.iro.umontreal.ca/~gambit/repo/gambit.git 500 14:18 make
I get the following messages:
heine:~/programs/gambc-v4_6_3-devel> make cd . && autoconf configure.ac > configure && chmod 755 configure configure.ac:588: warning: AC_CACHE_VAL(C_COMP_GNUC, ...): suspicious cache-id, must contain _cv_ to be cached ../../lib/autoconf/general.m4:2032: AC_CACHE_VAL is expanded from... ../../lib/autoconf/general.m4:2053: AC_CACHE_CHECK is expanded from... configure.ac:496: AC_CHECK_C_COMPILER_DEF is expanded from... configure.ac:588: the top level configure.ac:588: warning: AC_CACHE_VAL(C_COMP_GNUC, ...): suspicious presence of an AC_SUBST in the second argument, where no actions should be taken ../../lib/autoconf/general.m4:2032: AC_CACHE_VAL is expanded from... ../../lib/autoconf/general.m4:2053: AC_CACHE_CHECK is expanded from... configure.ac:496: AC_CHECK_C_COMPILER_DEF is expanded from... configure.ac:588: the top level configure.ac:589: warning: AC_CACHE_VAL(C_COMP_CLANG, ...): suspicious cache-id, must contain _cv_ to be cached
etc. This is with
heine:~/programs/gambc-v4_6_3-devel> autoconf -V autoconf (GNU Autoconf) 2.68 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+/Autoconf: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html, http://gnu.org/licenses/exceptions.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
Written by David J. MacKenzie and Akim Demaille. heine:~/programs/gambc-v4_6_3-devel> /pkgs/gcc-4.6.2/bin/gcc -v Using built-in specs. COLLECT_GCC=/pkgs/gcc-4.6.2/bin/gcc COLLECT_LTO_WRAPPER=/pkgs/gcc-4.6.2/libexec/gcc/x86_64-unknown-linux-gnu/4.6.2/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../../gcc-4.6.2/configure --prefix=/pkgs/gcc-4.6.2 --enable-languages=c --disable-multilib Thread model: posix gcc version 4.6.2 (GCC) heine:~/programs/gambc-v4_6_3-devel> uname -a Linux heine 3.0.0-15-generic #26-Ubuntu SMP Fri Jan 20 17:23:00 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Brad