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), 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 (
)
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:
Is it possible to achieve this with some other methods? Thanks a lot.