Suggest we're implementing a very specific Go application like data
migrator (for example, the one that transfers data from old database to new
database with different data types). Therefore, this application must be
compiled with two different versions of one library (e.g. v1 and v2). It
seems to be impossible in terms of Go modules (see this ticket
<https://github.com/golang/go/issues/31578>), but can we do this trick with
C shared libraries?
Minimal example:
v1/lib.h
#ifndef LIBCGO_MULTIVERSION_V1
#define LIBCGO_MULTIVERSION_V1
int add(int a, int b);
#endif
v1/lib.c
#include "lib.h"
int add(int a, int b) {
return a + b;
}
v1/lib.go
package cgomultiversion
// #cgo LDFLAGS: -l:libcgomultiversion.so.1
// #include <cgomultiversion_v1/lib.h>
import "C"
func Add(a, b int) int {
return int(C.add(C.int(a), C.int(b)))
}
v2/lib.h
#ifndef LIBCGO_MULTIVERSION_V2
#define LIBCGO_MULTIVERSION_V2
int add(int a, int b);
#endif
v2/lib.c
#include "lib.h"
int add(int a, int b) {
// for tests purposes addition is replaced with multiplication in v2
return a * b;
}
v2/lib.go
package cgomultiversion
// #cgo LDFLAGS: -l:libcgomultiversion.so.2
// #include <cgomultiversion_v2/lib.h>
import "C"
func Add(a, b int) int {
return int(C.add(C.int(a), C.int(b)))
}
Finally we have a test that tries to utilize both versions of C library:
package cgomultiversion
import (
"testing"
"github.com/stretchr/testify/assert"
cgomultiversion1 "github.com/vitalyisaev2/cgo_multiversion_go_lib/v1"
cgomultiversion2 "github.com/vitalyisaev2/cgo_multiversion_go_lib/v2"
)
func TestAdd(t *testing.T) {
assert.Equal(t, 10, cgomultiversion1.Add(5, 5))
assert.Equal(t, 25, cgomultiversion2.Add(5, 5))
}
This won't compile because of naming conflict on the C side:
go test -count=1 -v
# github.com/vitalyisaev2/cgo_multiversion_go_lib.test
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-218143790/000005.o: in function `add':
/home/isaev/go/src/github.com/vitalyisaev2/cgo_multiversion_go_lib/v2/lib.c:6:
multiple definition of `add';
/tmp/go-link-218143790/000002.o:/home/isaev/go/src/github.com/vitalyisaev2/cgo_multiversion_go_lib/v1/lib.c:5:
first defined here
collect2: error: ld returned 1 exit status
Full example is available at:
https://github.com/vitalyisaev2/cgo_multiversion_go_lib
Is it possible to achieve this with some other methods? Thanks a lot.
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/1778392c-d0d6-4ff9-9385-380483078626%40googlegroups.com.