I have the following setup
fileio.scm - contains c-lambda forms to bind C functions in fileio_util.cpp fileio_util.cpp - contains code that uses functions from gambit runtime library (data conversion functions like ___UTF_8STRING_to_SCMOBJ)
I'd like to make a loadable library from the above. Here is what I tried
bash-3.2$ uname -srmp Darwin 10.7.0 i386 i386 gsc -link -flat -o search.o1.c fileio g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio_util.o" -D___DYNAMIC fileio_util.cpp g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "search.o1.o" -D___DYNAMIC search.o1.c g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio.o" -D___DYNAMIC fileio.c g++ -bundle fileio_util.o fileio.o sqlite3.o search.o1.o -o search.o1
Linker gives the following errors
Undefined symbols: "___S64_to_SCMOBJ(long, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o "___UTF_8STRING_to_SCMOBJ(char*, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o w_sqlite_prepare(sqlite3*, char*)in fileio_util.o "___F64_to_SCMOBJ(double, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o
Since libgambc.a defines those symbols I tried liking with it. Here is what I get.
Undefined symbols: "_environ", referenced from: ___unsetenv_UCS_2(unsigned short*)in libgambc.a(os_shell.o) ___cleanup_shell_module() in libgambc.a(os_shell.o) ___os_environ() in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___getenv_UCS_2(unsigned short*, unsigned short**)in libgambc.a(os_shell.o) ___device_stream_setup_from_process(___device_stream_struct**, ___device_group_struct*, char**, char**, char*, int)in libgambc.a(os_io.o) (maybe you meant: ____G__23__23_fail_2d_check_2d_unbound_2d_os_2d_environment_2d_variable_2d_exception, ____G__23__23_display_2d_dynamic_2d_environment_3f_ , ... )
Also at first tried using gsc to run the compiler for me
gsc -verbose -cc-options "-D___DYNAMIC" -obj fileio.c fileio_util.cpp search.o1.c
But I kept getting
*** ERROR IN "fileio_util.cpp"@1.1 -- Invalid token
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly? How do I compile the above as a loadable library?
Thank you for Gambit. The more I use it the more I like it.
Afficher les réponses par date
On 2011-05-12, at 1:39 AM, Kartik Saranathan wrote:
I have the following setup
fileio.scm - contains c-lambda forms to bind C functions in fileio_util.cpp fileio_util.cpp - contains code that uses functions from gambit runtime library (data conversion functions like ___UTF_8STRING_to_SCMOBJ)
I'd like to make a loadable library from the above. Here is what I tried
bash-3.2$ uname -srmp Darwin 10.7.0 i386 i386 gsc -link -flat -o search.o1.c fileio g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio_util.o" -D___DYNAMIC fileio_util.cpp g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "search.o1.o" -D___DYNAMIC search.o1.c g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio.o" -D___DYNAMIC fileio.c g++ -bundle fileio_util.o fileio.o sqlite3.o search.o1.o -o search.o1
Linker gives the following errors
Undefined symbols: "___S64_to_SCMOBJ(long, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o "___UTF_8STRING_to_SCMOBJ(char*, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o w_sqlite_prepare(sqlite3*, char*)in fileio_util.o "___F64_to_SCMOBJ(double, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o
Since libgambc.a defines those symbols I tried liking with it. Here is what I get.
Undefined symbols: "_environ", referenced from: ___unsetenv_UCS_2(unsigned short*)in libgambc.a(os_shell.o) ___cleanup_shell_module() in libgambc.a(os_shell.o) ___os_environ() in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___getenv_UCS_2(unsigned short*, unsigned short**)in libgambc.a(os_shell.o) ___device_stream_setup_from_process(___device_stream_struct**, ___device_group_struct*, char**, char**, char*, int)in libgambc.a(os_io.o) (maybe you meant: ____G__23__23_fail_2d_check_2d_unbound_2d_os_2d_environment_2d_variable_2d_exception, ____G__23__23_display_2d_dynamic_2d_environment_3f_ , ... )
My guess is that some C linker options are missing to generate a dynamically loadable library. From the file bin/gambc-cc I see that, on a Mac, the build command for a dynamically loadable object file is:
${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
and
FLAGS_DYN="-mmacosx-version-min=10.5 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -bundle -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -flat_namespace -undefined suppress"
You can print that information with commands like:
% gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'
so in your makefile you could have something like:
BUILD_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")'` C_COMPILER=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")'` FLAGS_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'` ... BUILD_DYN_INPUT_FILENAMES=fileio_util.o fileio.o sqlite3.o search.o1.o BUILD_DYN_OUTPUT_FILENAME=search.o1
build_lib: ${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
I haven't tested this so YMMV.
Also at first tried using gsc to run the compiler for me
gsc -verbose -cc-options "-D___DYNAMIC" -obj fileio.c fileio_util.cpp search.o1.c
But I kept getting
*** ERROR IN "fileio_util.cpp"@1.1 -- Invalid token
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly?
The command-line processing of gsc treats files with a ".c" extension as C source files and other extensions as Scheme files. This is probably too conservative. I could add ".cpp" and ".cc" and ".m" as alternatives for C source files. Any others I should add?
How do I compile the above as a loadable library?
Thank you for Gambit. The more I use it the more I like it.
No problem! Thanks!
Marc
Hallo,
On Thu, May 12, 2011 at 9:56 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly?
The command-line processing of gsc treats files with a ".c" extension as C source files and other extensions as Scheme files. This is probably too conservative. I could add ".cpp" and ".cc" and ".m" as alternatives for C source files. Any others I should add?
There is also .mm for Objective-C++ and .C for C++, but I guess nobody uses the latter anymore (I used to).
You might use GCC's file-suffix conventions:
C++: .C .cc .cp .cpp .CPP .cxx .c++ Objective-C: .m Objective-C++: .M .mm
Suffixes for other languages (e.g. Fortran) can be found by searching for "file name suffix" within gcc's man page.
-- Matt
On Thu, May 12, 2011 at 9:36 AM, Alex Queiroz asandroq@gmail.com wrote:
Hallo,
On Thu, May 12, 2011 at 9:56 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly?
The command-line processing of gsc treats files with a ".c" extension as
C source files and other extensions as Scheme files. This is probably too conservative. I could add ".cpp" and ".cc" and ".m" as alternatives for C source files. Any others I should add?
There is also .mm for Objective-C++ and .C for C++, but I guess
nobody uses the latter anymore (I used to).
-- -alex http://www.artisancoder.com/ _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Hi Marc. Thanks for the pointer to gambc-cc. I've passed the necessary arguments to make the o1 file now but I get a segmentation fault on the first ___make_pair in fileio_util.cpp. I've tried searching through past messages on the maling list but couldn't find anything that helped (there were posts about a GLUT FFI that can be built as a loadable library but I couldn't find any code). Here are the relevant pieces of my code.
fileio.scm: (define test (c-lambda () scheme-object "test")) (pretty-print (test))
fileio_util.cpp: #include "gambit.h" ___SCMOBJ test() { return ___EXT(___make_pair)(___FIX(1), ___FIX(2), ___STILL); // return ___FIX(1); }
fileio_util.h: ___SCMOBJ test();
Here is how I compile it. I pass in $(FLAGS_DYN) $(DEFS_DYN) to the compiler as you suggested. I pass -x c++ to make sure fileio.c compiles as a c++ file.
--- gsc -link -flat -o search.o1.c fileio g++ -bundle -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -flat_namespace -undefined suppress -D___SINGLE_HOST -D___DYNAMIC -I"/usr/local/Gambit-C/include" -x c++ fileio_util.cpp fileio.c sqlite3.o search.o1.c -o search.o1 ----
Here is what happens when I run it
--- bash-3.2$ gdb gsi (gdb) r Starting program: /usr/local/bin/gsi Reading symbols for shared libraries ++. done Gambit v4.6.1
(load "search")
Reading symbols for shared libraries . done
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000818 0x0000000100702112 in test () ---
It is probably crashing in ___alloc_scmobj but I can't see why. The program prints '(1 . 2)' when compiled as an executable. I built gambit from source with g++ under mac osx.
As for the extension for source files Matthew gave a good list.
Thanks
On Thu, May 12, 2011 at 5:56 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2011-05-12, at 1:39 AM, Kartik Saranathan wrote:
I have the following setup
fileio.scm - contains c-lambda forms to bind C functions in fileio_util.cpp fileio_util.cpp - contains code that uses functions from gambit runtime library (data conversion functions like ___UTF_8STRING_to_SCMOBJ)
I'd like to make a loadable library from the above. Here is what I tried
bash-3.2$ uname -srmp Darwin 10.7.0 i386 i386 gsc -link -flat -o search.o1.c fileio g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio_util.o" -D___DYNAMIC fileio_util.cpp g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "search.o1.o" -D___DYNAMIC search.o1.c g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio.o" -D___DYNAMIC fileio.c g++ -bundle fileio_util.o fileio.o sqlite3.o search.o1.o -o search.o1
Linker gives the following errors
Undefined symbols: "___S64_to_SCMOBJ(long, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o "___UTF_8STRING_to_SCMOBJ(char*, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o w_sqlite_prepare(sqlite3*, char*)in fileio_util.o "___F64_to_SCMOBJ(double, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o
Since libgambc.a defines those symbols I tried liking with it. Here is what I get.
Undefined symbols: "_environ", referenced from: ___unsetenv_UCS_2(unsigned short*)in libgambc.a(os_shell.o) ___cleanup_shell_module() in libgambc.a(os_shell.o) ___os_environ() in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___getenv_UCS_2(unsigned short*, unsigned short**)in libgambc.a(os_shell.o) ___device_stream_setup_from_process(___device_stream_struct**, ___device_group_struct*, char**, char**, char*, int)in libgambc.a(os_io.o) (maybe you meant: ____G__23__23_fail_2d_check_2d_unbound_2d_os_2d_environment_2d_variable_2d_exception, ____G__23__23_display_2d_dynamic_2d_environment_3f_ , ... )
My guess is that some C linker options are missing to generate a dynamically loadable library. From the file bin/gambc-cc I see that, on a Mac, the build command for a dynamically loadable object file is:
${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
and
FLAGS_DYN="-mmacosx-version-min=10.5 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -bundle -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -flat_namespace -undefined suppress"
You can print that information with commands like:
% gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'
so in your makefile you could have something like:
BUILD_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")'` C_COMPILER=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")'` FLAGS_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'` ... BUILD_DYN_INPUT_FILENAMES=fileio_util.o fileio.o sqlite3.o search.o1.o BUILD_DYN_OUTPUT_FILENAME=search.o1
build_lib: ${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
I haven't tested this so YMMV.
Also at first tried using gsc to run the compiler for me
gsc -verbose -cc-options "-D___DYNAMIC" -obj fileio.c fileio_util.cpp search.o1.c
But I kept getting
*** ERROR IN "fileio_util.cpp"@1.1 -- Invalid token
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly?
The command-line processing of gsc treats files with a ".c" extension as C source files and other extensions as Scheme files. This is probably too conservative. I could add ".cpp" and ".cc" and ".m" as alternatives for C source files. Any others I should add?
How do I compile the above as a loadable library?
Thank you for Gambit. The more I use it the more I like it.
No problem! Thanks!
Marc
I found the problem is because the ___EXT macro uses the static variable ___local_gstate which is uninitialized in fileio_util.cpp. If I don't use the ___EXT macro the make_pair works fine. I'm guessing the local state is needed for multithreaded applications or maybe multiple versions of a loadable library?
I see the gambit scm to c compiler inserted a function to do the initialization of ___local_gstate in fileio.c but I haven't added anything in fileio_util.cpp to do the same initialization. Am I allowed to call functions like ___make_pair from fileio_util.cpp in the first place? Should I use embedded C code inside the scm file and call __make_pair from there instead?
Thanks
Kartik
On Fri, May 13, 2011 at 4:42 PM, Kartik Saranathan ksaranat@gmail.com wrote:
Hi Marc. Thanks for the pointer to gambc-cc. I've passed the necessary arguments to make the o1 file now but I get a segmentation fault on the first ___make_pair in fileio_util.cpp. I've tried searching through past messages on the maling list but couldn't find anything that helped (there were posts about a GLUT FFI that can be built as a loadable library but I couldn't find any code). Here are the relevant pieces of my code.
fileio.scm: (define test (c-lambda () scheme-object "test")) (pretty-print (test))
fileio_util.cpp: #include "gambit.h" ___SCMOBJ test() { return ___EXT(___make_pair)(___FIX(1), ___FIX(2), ___STILL); // return ___FIX(1); }
fileio_util.h: ___SCMOBJ test();
Here is how I compile it. I pass in $(FLAGS_DYN) $(DEFS_DYN) to the compiler as you suggested. I pass -x c++ to make sure fileio.c compiles as a c++ file.
--- gsc -link -flat -o search.o1.c fileio g++ -bundle -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -flat_namespace -undefined suppress -D___SINGLE_HOST -D___DYNAMIC -I"/usr/local/Gambit-C/include" -x c++ fileio_util.cpp fileio.c sqlite3.o search.o1.c -o search.o1 ----
Here is what happens when I run it
--- bash-3.2$ gdb gsi (gdb) r Starting program: /usr/local/bin/gsi Reading symbols for shared libraries ++. done Gambit v4.6.1
(load "search")
Reading symbols for shared libraries . done
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000818 0x0000000100702112 in test () ---
It is probably crashing in ___alloc_scmobj but I can't see why. The program prints '(1 . 2)' when compiled as an executable. I built gambit from source with g++ under mac osx.
As for the extension for source files Matthew gave a good list.
Thanks
On Thu, May 12, 2011 at 5:56 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2011-05-12, at 1:39 AM, Kartik Saranathan wrote:
I have the following setup
fileio.scm - contains c-lambda forms to bind C functions in fileio_util.cpp fileio_util.cpp - contains code that uses functions from gambit runtime library (data conversion functions like ___UTF_8STRING_to_SCMOBJ)
I'd like to make a loadable library from the above. Here is what I tried
bash-3.2$ uname -srmp Darwin 10.7.0 i386 i386 gsc -link -flat -o search.o1.c fileio g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio_util.o" -D___DYNAMIC fileio_util.cpp g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "search.o1.o" -D___DYNAMIC search.o1.c g++ -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -D___SINGLE_HOST -I"/usr/local/Gambit-C/include" -c -o "fileio.o" -D___DYNAMIC fileio.c g++ -bundle fileio_util.o fileio.o sqlite3.o search.o1.o -o search.o1
Linker gives the following errors
Undefined symbols: "___S64_to_SCMOBJ(long, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o "___UTF_8STRING_to_SCMOBJ(char*, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o w_sqlite_prepare(sqlite3*, char*)in fileio_util.o "___F64_to_SCMOBJ(double, long*, int)", referenced from: ConvertSqliteData(sqlite3_stmt*, int, int, long&)in fileio_util.o
Since libgambc.a defines those symbols I tried liking with it. Here is what I get.
Undefined symbols: "_environ", referenced from: ___unsetenv_UCS_2(unsigned short*)in libgambc.a(os_shell.o) ___cleanup_shell_module() in libgambc.a(os_shell.o) ___os_environ() in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___setenv_UCS_2(unsigned short*, unsigned short*)in libgambc.a(os_shell.o) ___getenv_UCS_2(unsigned short*, unsigned short**)in libgambc.a(os_shell.o) ___device_stream_setup_from_process(___device_stream_struct**, ___device_group_struct*, char**, char**, char*, int)in libgambc.a(os_io.o) (maybe you meant: ____G__23__23_fail_2d_check_2d_unbound_2d_os_2d_environment_2d_variable_2d_exception, ____G__23__23_display_2d_dynamic_2d_environment_3f_ , ... )
My guess is that some C linker options are missing to generate a dynamically loadable library. From the file bin/gambc-cc I see that, on a Mac, the build command for a dynamically loadable object file is:
${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
and
FLAGS_DYN="-mmacosx-version-min=10.5 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch x86_64 -m64 -bundle -no-cpp-precomp -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fno-move-loop-invariants -fPIC -fno-common -mieee-fp -flat_namespace -undefined suppress"
You can print that information with commands like:
% gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")' % gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'
so in your makefile you could have something like:
BUILD_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc BUILD_DYN")'` C_COMPILER=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc C_COMPILER")'` FLAGS_DYN=`gsi -e '(current-directory "~~bin")(shell-command "./gambc-cc FLAGS_DYN")'` ... BUILD_DYN_INPUT_FILENAMES=fileio_util.o fileio.o sqlite3.o search.o1.o BUILD_DYN_OUTPUT_FILENAME=search.o1
build_lib: ${C_COMPILER} ${FLAGS_DYN} ${DEFS_DYN} -I"${GAMBCDIR_INCLUDE}" -o "${BUILD_DYN_OUTPUT_FILENAME}" ${BUILD_DYN_CC_OPTIONS} ${BUILD_DYN_LD_OPTIONS_PRELUDE} ${BUILD_DYN_INPUT_FILENAMES} ${BUILD_DYN_LD_OPTIONS}
I haven't tested this so YMMV.
Also at first tried using gsc to run the compiler for me
gsc -verbose -cc-options "-D___DYNAMIC" -obj fileio.c fileio_util.cpp search.o1.c
But I kept getting
*** ERROR IN "fileio_util.cpp"@1.1 -- Invalid token
I realized it was treating the .cpp file as a scheme file and failing. Is this a bug or am I using it incorrectly?
The command-line processing of gsc treats files with a ".c" extension as C source files and other extensions as Scheme files. This is probably too conservative. I could add ".cpp" and ".cc" and ".m" as alternatives for C source files. Any others I should add?
How do I compile the above as a loadable library?
Thank you for Gambit. The more I use it the more I like it.
No problem! Thanks!
Marc
On 2011-05-14, at 12:28 AM, Kartik Saranathan wrote:
I found the problem is because the ___EXT macro uses the static variable ___local_gstate which is uninitialized in fileio_util.cpp. If I don't use the ___EXT macro the make_pair works fine. I'm guessing the local state is needed for multithreaded applications or maybe multiple versions of a loadable library?
It is more for doing dynamic linking on systems that don't natively support dynamic linking. But it is also useful for multithreading.
I see the gambit scm to c compiler inserted a function to do the initialization of ___local_gstate in fileio.c but I haven't added anything in fileio_util.cpp to do the same initialization. Am I allowed to call functions like ___make_pair from fileio_util.cpp in the first place? Should I use embedded C code inside the scm file and call __make_pair from there instead?
Thanks
Kartik
Can you try compiling Gambit this way:
./configure CC="gcc -D___CAN_IMPORT_DYNAMICALLY"
and compile your C files with gcc -D___CAN_IMPORT_DYNAMICALLY .
This will activate a definition of ___EXT that does not go through a ___local_gstate variable. Then you can call ___make_pair and friends without errors. Alternatively, don't use ___EXT (it was there to explicitly mark dynamically linked functions so that on platforms with no native dynamic linking the appropriate magic would happen).
Marc