Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about static linking #116

Open
eatonphil opened this issue Aug 20, 2023 · 3 comments
Open

Question about static linking #116

eatonphil opened this issue Aug 20, 2023 · 3 comments

Comments

@eatonphil
Copy link

Hey Marc! I am taking a look at this repo for the first time in a bit. Here's the sample code I'm trying.

package main

import (
        "database/sql"
        "fmt"

        _ "github.com/marcboeker/go-duckdb"
)

func main() {
        db, err := sql.Open("duckdb", "")
        if err != nil {
                panic(err)
        }

        _, err = db.Exec("CREATE TABLE x (name TEXT, age INT)")
        if err != nil {
                panic(err)
        }

        _, err = db.Exec("INSERT INTO x VALUES ('Terry', 12), ('Marge', 14)")
        if err != nil {
                panic(err)
        }

        rows, err := db.Query("SELECT name, age FROM x")
        for rows.Next() {
                var name string
                var age int
                err = rows.Scan(&name, &age)
                if err != nil {
                        panic(err)
                }

                fmt.Println(name, age)
        }

        if err := rows.Err(); err != nil {
                panic(err)
        }
}

While based on the file size, it seems like static linking worked, when I run ldd it seems to show dynamically linked libraries (though not necessarily duckdb).

$ go build
$ ldd duckdb-tests
        linux-vdso.so.1 (0x00007ffd273bf000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f70ebc00000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f70ebeb4000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f70ebb1f000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f70ebe90000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f70eb941000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f70ebed7000)
$ ls -lah duckdb-tests
-rwxr-xr-x 1 phil phil  31M Aug 20 14:23 duckdb-tests

Whereas when I build a basic Go program:

$ cat test.go
package main

import "fmt"

func main() {
        fmt.Println("hey")
}
$ go build
$ ldd test
        not a dynamic executable
$ ls -lah test
-rwxr-xr-x 1 phil phil 1.8M Aug 20 14:16 test

So is there a way to build with go-duckdb that actually produces a static binary? Thanks!

@javierhonduco
Copy link

javierhonduco commented Aug 20, 2023

On a Fedora box, your code above compiles to a static executable:

CGO_ENABLED=1 CGO_LDFLAGS="-L/usr/lib" go build --ldflags="-extldflags=-static" -tags osusergo,netgo .
$ ldd ./hello
	not a dynamic executable

That being said, there is a warning as dlopen seems to be used by duckdb:

# hello
/usr/bin/ld: /home/javierhonduco/go/pkg/mod/github.com/marcboeker/[email protected]/deps/linux_amd64/libduckdb.a(duckdb.o): in function `AdbcLoadDriver':
duckdb.cpp:(.text+0x35671): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /home/javierhonduco/go/pkg/mod/github.com/marcboeker/[email protected]/deps/linux_amd64/libduckdb.a(duckdb.o): in function `int duckdb_httplib::detail::create_socket<duckdb_httplib::detail::create_client_socket(char const*, char const*, int, int, bool, std::function<void (int)>, long, long, long, long, long, long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, duckdb_httplib::Error&)::{lambda(int, addrinfo&)#1}>(char const*, char const*, int, int, int, bool, std::function<void (int)>, duckdb_httplib::detail::create_client_socket(char const*, char const*, int, int, bool, std::function<void (int)>, long, long, long, long, long, long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, duckdb_httplib::Error&)::{lambda(int, addrinfo&)#1})':
duckdb.cpp:(.text._ZN14duckdb_httplib6detail13create_socketIZNS0_20create_client_socketEPKcS3_iibSt8functionIFviEEllllllRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ErrorEEUliR8addrinfoE_EEiS3_S3_iiibS6_T_[_ZN14duckdb_httplib6detail13create_socketIZNS0_20create_client_socketEPKcS3_iibSt8functionIFviEEllllllRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ErrorEEUliR8addrinfoE_EEiS3_S3_iiibS6_T_]+0xb3): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

Perhaps it would be useful to bring this up to the duckdb devs?

@eatonphil
Copy link
Author

Thank you for the incantation! (Also, for Marc, assuming we get the DuckDB devs to help out with the dlopen warning, can we get this incantation to be the default build mode?)

I'll ping someone from DuckDB to see.

@marcboeker
Copy link
Owner

Yes, there is by default a glibc dependency from DuckDB. We also have another discussion around this going on in #54. If someone wants to discuss this with the DuckDB devs would be great, as I do not have much free time at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants