Static linking vs Dynamic linking in linux

I have setup a very simple project. the directory structure is as below

experiment
    demo
        main.odin
    libsb 
        root.odin

the content is:
main.odin:

package demo
import "core:fmt"

foreign import sb "../libsb.o"
foreign sb {
	Add :: proc(a: int, b: int) -> int ---
}


main :: proc() {
	fmt.println(Add(1, 2))
}

root.odin:

package libsb

@(export)
Add :: proc(a: int, b: int) -> int {
	return a + b
}

Im building the libsb as object file as the static mode doesnt work on linux…

odin build libsb -build-mode=obj  -show-system-calls

then building the executable…

odin build demo -out:exp.out -show-system-calls

its giving me error as follows:

clang -Wno-unused-command-line-argument "/home/biswas08433/dev/odin/experiments/exp.o"  -o "/home/biswas08433/dev/odin/experiments/exp.out"  -lm -lc   -L/ -l:"/home/biswas08433/dev/odin/experiments/libsb.o"        -no-pie -Wl,-rpath,\$ORIGIN

/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__$startup_runtime':
odin_package:(.text+0x0): multiple definition of `__$startup_runtime'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x0): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__$cleanup_runtime':
odin_package:(.text+0x10): multiple definition of `__$cleanup_runtime'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x370): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `main':
odin_package:(.text+0xce0): multiple definition of `main'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x3bb0): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__truncsfhf2':
odin_package:(.text+0x2220): multiple definition of `__truncsfhf2'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x1b460): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__truncdfhf2':
odin_package:(.text+0x2450): multiple definition of `__truncdfhf2'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x1bc10): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__gnu_h2f_ieee':
odin_package:(.text+0x2470): multiple definition of `__gnu_h2f_ieee'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x1bd50): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__gnu_f2h_ieee':
odin_package:(.text+0x2540): multiple definition of `__gnu_f2h_ieee'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x1c430): first defined here
/usr/bin/ld: ///home/biswas08433/dev/odin/experiments/libsb.o: in function `__extendhfsf2':
odin_package:(.text+0x2560): multiple definition of `__extendhfsf2'; /home/biswas08433/dev/odin/experiments/exp.o:odin_package:(.text+0x1c450): first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)

In the same way the dynamic linking works fine. Any help?

1 Like

I have had this same problem before. When I first started using Odin I played around with the foreign import system for a time. I was able to link against objects compiled in C just fine, but with Odin it redefines all these symbols like you’re showing.

I have found no flags that fix this issue, at least not ones displayed in odin build -help, so I don’t really know if there’s a way to fix it.

I didn’t think of it at the time, as I had just started using Odin, but it’s probably worth filing an issue. I can’t see any other mentions of this in the issues on the Github.

Also worth mentioning that foreign procedure declarations have the “cdecl” calling convention by default, so you should probably pop a @(default_calling_convention="odin") at the top of your foreign block if you’re importing odin code, unless something else is more useful.