Re: Trying to link in modules

2021-06-20 Thread T. Kurt Bond
Thanks!

On Sun, Jun 20, 2021 at 6:42 AM  wrote:

> > I've got a module mymod in mymod.scm:
> >
> >[...]
> >
> >  However, I can't figure out how to do the same thing with mymod as
> > non-shared objects.   I tried
> >
> > csc -c -J mymod.scm
> > csc -c mymod.import.scm
> > csc -static -o trymod.static mymod.o mymod.import.o trymod.scm
> >
> > but I got
> >
> > Undefined symbols for architecture x86_64:
> >
> >   "_C_mymod_toplevel", referenced from:
> >   _f_138 in trymod.o
> > ld: symbol(s) not found for architecture x86_64
> > clang: error: linker command failed with exit code 1 (use -v to see
> > invocation)
> > Error: shell command terminated with non-zero exit status 256: 'clang'
> > 'mymod.import.o' 'mymod.o' 'trymod.o' -o 'trymod.static' -m64
> > -L/usr/local/Cellar/chicken/5.2.0/lib
> > /usr/local/Cellar/chicken/5.2.0/lib/libchicken.a -lm
>
> When loading a shared object, the CHICKEN runtime uses the libld API
> to obtain the entry point ("C_toplevel") to invoke top-level
> initialization code
> of the module (which also sets up global bindings, etc.). But in a
> statically
> linked executable, all entry points of linked modules must be available
> under
> a separate name, so that they can be distinguished from each other.
>
> What we do is to give the module (the binary *.o module) a name, which is
> called "unit", so mymod would have, for example, the unit name "mymod",
> which produces the entry point "C_mymod_toplevel". So you can link any
> number of separately compiled binary objects (containing modules) and
> their names don't clash.
>
> So, to make it work:
>
> csc -c -J mymod.scm -unit mymod
> # compiling the import library is not needed
> csc -static -o trymod.static -uses mymod mymod.o trymod.scm
>
> The main file (trymod) doesn't need to resolve the imports, so you can omit
> linking the import library. "-unit" gives the module a unit name, "-uses"
> tells
> the main module to invoke the toplevel of the linked module.
>
> This mechanism is a source of great confusion, but this mainly comes from
> the fact that static linking uses a facility for resolving module toplevel
> and
> initialization code from the whole module and namespacing machinery.
>
> ---
> BTW, the "csm" utility, provided by the egg of the same name, figures this
> out
> automatically, just put trymod.scm and mymod.scm into an empty directory
> and enter
>
> csm -program trymod
>
> or
>
> csm -program trymod -static
>
> Add -d and -v to see what the program is doing and how things are compiled.
>
>
> felix
>
>

-- 
T. Kurt Bond, tkurtb...@gmail.com, https://tkurtbond.github.io


Re: Trying to link in modules

2021-06-20 Thread felix . winkelmann
> I've got a module mymod in mymod.scm:
>
>[...]
>
>  However, I can't figure out how to do the same thing with mymod as
> non-shared objects.   I tried
>
> csc -c -J mymod.scm
> csc -c mymod.import.scm
> csc -static -o trymod.static mymod.o mymod.import.o trymod.scm
>
> but I got
>
> Undefined symbols for architecture x86_64:
>
>   "_C_mymod_toplevel", referenced from:
>   _f_138 in trymod.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see
> invocation)
> Error: shell command terminated with non-zero exit status 256: 'clang'
> 'mymod.import.o' 'mymod.o' 'trymod.o' -o 'trymod.static' -m64
> -L/usr/local/Cellar/chicken/5.2.0/lib
> /usr/local/Cellar/chicken/5.2.0/lib/libchicken.a -lm

When loading a shared object, the CHICKEN runtime uses the libld API
to obtain the entry point ("C_toplevel") to invoke top-level initialization code
of the module (which also sets up global bindings, etc.). But in a statically
linked executable, all entry points of linked modules must be available under
a separate name, so that they can be distinguished from each other.

What we do is to give the module (the binary *.o module) a name, which is
called "unit", so mymod would have, for example, the unit name "mymod",
which produces the entry point "C_mymod_toplevel". So you can link any
number of separately compiled binary objects (containing modules) and
their names don't clash.

So, to make it work:

csc -c -J mymod.scm -unit mymod
# compiling the import library is not needed
csc -static -o trymod.static -uses mymod mymod.o trymod.scm

The main file (trymod) doesn't need to resolve the imports, so you can omit
linking the import library. "-unit" gives the module a unit name, "-uses" tells
the main module to invoke the toplevel of the linked module.

This mechanism is a source of great confusion, but this mainly comes from
the fact that static linking uses a facility for resolving module toplevel and
initialization code from the whole module and namespacing machinery.

---
BTW, the "csm" utility, provided by the egg of the same name, figures this out
automatically, just put trymod.scm and mymod.scm into an empty directory
and enter

csm -program trymod

or

csm -program trymod -static

Add -d and -v to see what the program is doing and how things are compiled.


felix




Re: Trying to link in modules

2021-06-20 Thread Kristian Lein-Mathisen
Hi Kurt,

I think the problem is missing flags and parameters when fuilding a static
extension. I'm afraid I don't know exactly what they are, but hopefully I
can give some pointers to how you can find them.

chicken-install will extensions first as a shared object, and then as a
static one by default.

~/p/t/chicken-mtest > cat mymod.egg
((components
(extension mymod)))
~/p/t/chicken-mtest > chicken-install -v

/data/data/com.termux/files/home/prj/tmp/chicken-mtest/mymod.link -host -D
compiling-extension -c -unit mymod -D compiling-static-extension -C
-I/data/data/com.termux/files/home/prj/tmp/chicken-mtest -O2 -d1 mymod.scm
-o
/data/data/com.termux/files/home/prj/tmp/chicken-mtest/mymod.static.o


That gives a lot of output, but notice it installs a mymod.o file that
trymod can use when compiled statically. Let's see how trymod behaves as
normally:

~/p/t/chicken-mtest > csc trymod.scm
~/p/t/chicken-mtest > strace ./trymod ^&1 |grep mymod
newfstatat(AT_FDCWD,
"/data/data/com.termux/files/usr/lib/chicken/11/mymod.so",
{st_mode=S_IFREG|0755, st_size=13232, ...}, 0) = 0
newfstatat(AT_FDCWD,
"/data/data/com.termux/files/usr/lib/chicken/11/mymod.so",
{st_mode=S_IFREG|0755, st_size=13232, ...}, 0) = 0
openat(AT_FDCWD, "/data/data/com.termux/files/usr/lib/chicken/11/mymod.so",
O_RDONLY|O_CLOEXEC) = 3
 openat(AT_FDCWD,
"/data/data/com.termux/files/usr/lib/chicken/11/mymod.so",
O_RDONLY|O_CLOEXEC) = 3
 write(1, "Hello, World, I'm in mymod!\n", 28Hello, World, I'm in mymod!


And now with static compilation:

~/p/t/chicken-mtest > csc -static trymod.scm
~/p/t/chicken-mtest > strace ./trymod ^&1 |grep mymod
write(1, "Hello, World, I'm in mymod!\n", 28Hello, World, I'm in mymod!


I hope that is what you're after. Note this uses the installed version of
mymod (chicken-status), not the one in PWD. You can inspect the *.build.sh
files that chicken-install produces for inspiration, or tweak the .egg-file
to suit your needs.

Cheers,
Kris

On Sun, Jun 20, 2021, 09:57 T. Kurt Bond  wrote:

> I've got a module mymod in mymod.scm:
>
> (module mymod (hello)
>   (import scheme)
>   (define (hello)
> (display "Hello, World, I'm in mymod!")
> (newline)))
>
> and I've got a module trymod in trymod.scm:
>
> (module trymod ()
>   (import scheme)
>   (import mymod)
>   (hello)
>   )
>
> and when I compile them like this:
>
> csc -s -J mymod.scm
> csc -s mymod.import.scm
> csc trymod.scm
>
> it produces an executable trymod that runs and dynamically loads mymod.so,
> unloads it, and loads it again, then produces the expected output, calling
> the function hello in mymod as running it on macOS with 
> DYLD_PRINT_LIBRARIES=YES
> ./trymod shows.
>
> ...
> dyld: loaded: <59A8239F-C28A-3B59-B8FA-11340DC85EDC>
> /usr/lib/libc++.1.dylib
> dyld: loaded:  ./mymod.so
> dyld: unloaded:  ./mymod.so
> dyld: loaded:  ./mymod.so
> Hello, World, I'm in mymod!
>
>  However, I can't figure out how to do the same thing with mymod as
> non-shared objects.   I tried
>
> csc -c -J mymod.scm
> csc -c mymod.import.scm
> csc -static -o trymod.static mymod.o mymod.import.o trymod.scm
>
> but I got
>
> Undefined symbols for architecture x86_64:
>
>   "_C_mymod_toplevel", referenced from:
>   _f_138 in trymod.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see
> invocation)
> Error: shell command terminated with non-zero exit status 256: 'clang'
> 'mymod.import.o' 'mymod.o' 'trymod.o' -o 'trymod.static' -m64
> -L/usr/local/Cellar/chicken/5.2.0/lib
> /usr/local/Cellar/chicken/5.2.0/lib/libchicken.a -lm
>
>
> What am I doing wrong?
> --
> T. Kurt Bond, tkurtb...@gmail.com, https://tkurtbond.github.io
>


Trying to link in modules

2021-06-20 Thread T. Kurt Bond
I've got a module mymod in mymod.scm:

(module mymod (hello)
  (import scheme)
  (define (hello)
(display "Hello, World, I'm in mymod!")
(newline)))

and I've got a module trymod in trymod.scm:

(module trymod ()
  (import scheme)
  (import mymod)
  (hello)
  )

and when I compile them like this:

csc -s -J mymod.scm
csc -s mymod.import.scm
csc trymod.scm

it produces an executable trymod that runs and dynamically loads mymod.so,
unloads it, and loads it again, then produces the expected output, calling
the function hello in mymod as running it on macOS with
DYLD_PRINT_LIBRARIES=YES
./trymod shows.

...
dyld: loaded: <59A8239F-C28A-3B59-B8FA-11340DC85EDC> /usr/lib/libc++.1.dylib
dyld: loaded:  ./mymod.so
dyld: unloaded:  ./mymod.so
dyld: loaded:  ./mymod.so
Hello, World, I'm in mymod!

 However, I can't figure out how to do the same thing with mymod as
non-shared objects.   I tried

csc -c -J mymod.scm
csc -c mymod.import.scm
csc -static -o trymod.static mymod.o mymod.import.o trymod.scm

but I got

Undefined symbols for architecture x86_64:

  "_C_mymod_toplevel", referenced from:
  _f_138 in trymod.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
Error: shell command terminated with non-zero exit status 256: 'clang'
'mymod.import.o' 'mymod.o' 'trymod.o' -o 'trymod.static' -m64
-L/usr/local/Cellar/chicken/5.2.0/lib
/usr/local/Cellar/chicken/5.2.0/lib/libchicken.a -lm


What am I doing wrong?
-- 
T. Kurt Bond, tkurtb...@gmail.com, https://tkurtbond.github.io