ld: duplicate symbol at tip

354 views
Skip to first unread message

gta

unread,
Feb 22, 2012, 2:56:24 PM2/22/12
to golan...@googlegroups.com
Hi,
I tried out tip and got this:

$ hg identify
71e92f075ee7 tip

ld: duplicate symbol _setCharCB in $WORK/github.com/jteeuwen/glfw/_obj/callback.cgo2.o and $WORK/github.com/jteeuwen/glfw/_obj/_cgo_export.o for architecture x86_64
collect2: ld returned 1 exit status

$ uname -rs
Darwin 11.3.0

It works with the last weekly.

Can someone reproduce? Should I file an issue?

Ciao.





Andrew Gerrand

unread,
Feb 22, 2012, 4:46:47 PM2/22/12
to gta, golan...@googlegroups.com
Did you rebuild the tree after updating to tip? ('go version')

gta

unread,
Feb 22, 2012, 4:56:35 PM2/22/12
to golan...@googlegroups.com, gta
I'm pretty sure I did, but just in case I did it again :)

$ go version
go version weekly.2012-02-14 +71e92f075ee7

gta

unread,
Feb 23, 2012, 9:07:04 AM2/23/12
to golan...@googlegroups.com, gta
followup

$ go version
go version weekly.2012-02-22 +96bd78e7d35e
$ go tool cgo glfw.go
$ ls _obj/
_cgo_.o         _cgo_defun.c    _cgo_export.c   _cgo_export.h   _cgo_flags      _cgo_gotypes.go _cgo_main.c     glfw.cgo1.go    glfw.cgo2.c

At this point  _cgo_export.h is:

/* Created by cgo - DO NOT EDIT. */


typedef unsigned int uint;
typedef signed char schar;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef long long int64;
typedef unsigned long long uint64;
typedef __SIZE_TYPE__ uintptr;

typedef struct { char *p; int n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;

$ go tool cgo callback.go
$ ls _obj/
_cgo_.o          _cgo_export.c    _cgo_flags       _cgo_main.c      callback.cgo2.c  glfw.cgo2.c
_cgo_defun.c     _cgo_export.h    _cgo_gotypes.go  callback.cgo1.go glfw.cgo1.go

_cgo_export.h now looks like:

/* Created by cgo - DO NOT EDIT. */

#line 7 "callback.go"
#include "glue.h"

extern void goWindowSizeCB(int, int);
extern int  goWindowCloseCB(void);
extern void goWindowRefreshCB(void);
extern void goMouseButtonCB(int, int);
extern void goMousePosCB(int, int);
extern void goMouseWheelCB(int);
extern void goKeyCB(int, int);
extern void goCharCB(int, int);

void setWindowSizeCB()    { glfwSetWindowSizeCallback(goWindowSizeCB); }
void setWindowCloseCB()   { glfwSetWindowCloseCallback(goWindowCloseCB); }
void setWindowRefreshCB() { glfwSetWindowRefreshCallback(goWindowRefreshCB); }
void setMouseButtonCB()   { glfwSetMouseButtonCallback(goMouseButtonCB); }
void setMousePosCB()      { glfwSetMousePosCallback(goMousePosCB); }
void setMouseWheelCB()    { glfwSetMouseWheelCallback(goMouseWheelCB); }
void setKeyCB()           { glfwSetKeyCallback(goKeyCB); }
void setCharCB()          { glfwSetCharCallback(goCharCB); }



typedef unsigned int uint;
typedef signed char schar;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef long long int64;
typedef unsigned long long uint64;
typedef __SIZE_TYPE__ uintptr;

typedef struct { char *p; int n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;


extern void goWindowSizeCB(int p0, int p1);

extern int goWindowCloseCB();

extern void goWindowRefreshCB();

extern void goMouseButtonCB(int p0, int p1);

extern void goMousePosCB(int p0, int p1);

extern void goMouseWheelCB(int p0);

extern void goKeyCB(int p0, int p1);

extern void goCharCB(int p0, int p1);

and the first 20 lines of callback.cgo2.c are:


#line 7 "callback.go"
#include "glue.h"

extern void goWindowSizeCB(int, int);
extern int  goWindowCloseCB(void);
extern void goWindowRefreshCB(void);
extern void goMouseButtonCB(int, int);
extern void goMousePosCB(int, int);
extern void goMouseWheelCB(int);
extern void goKeyCB(int, int);
extern void goCharCB(int, int);

void setWindowSizeCB()    { glfwSetWindowSizeCallback(goWindowSizeCB); }
void setWindowCloseCB()   { glfwSetWindowCloseCallback(goWindowCloseCB); }
void setWindowRefreshCB() { glfwSetWindowRefreshCallback(goWindowRefreshCB); }
void setMouseButtonCB()   { glfwSetMouseButtonCallback(goMouseButtonCB); }
void setMousePosCB()      { glfwSetMousePosCallback(goMousePosCB); }
void setMouseWheelCB()    { glfwSetMouseWheelCallback(goMouseWheelCB); }
void setKeyCB()           { glfwSetKeyCallback(goKeyCB); }
void setCharCB()          { glfwSetCharCallback(goCharCB); }


Any idea for a quick fix?

Ciao.


Jim Teeuwen

unread,
Feb 23, 2012, 10:57:02 AM2/23/12
to golan...@googlegroups.com, gta
I've found the same issues myself. This seems to happen with all my cgo packages.
I have not had time to dive into it yet, so I can't say why this happens.

Agon filed a bug report on this issue: https://github.com/jteeuwen/glfw/issues/4

gta

unread,
Feb 23, 2012, 11:05:48 AM2/23/12
to golan...@googlegroups.com, gta
I also filed this issue http://code.google.com/p/go/issues/detail?id=3116&colspec=ID%20Status%20Stars%20Priority%20Owner%20Reporter%20Summary

P.S. I hoep you don't mind using your code as example

gwenn

unread,
Feb 23, 2012, 2:12:04 PM2/23/12
to golang-nuts
Maybe change 00a19a04b13e:
"If people are using //export and
putting non-header information in the preamble, they will need to
refactor their code."

On Feb 23, 5:05 pm, gta <giacomo.tart...@gmail.com> wrote:
> I also filed this
> issuehttp://code.google.com/p/go/issues/detail?id=3116&colspec=ID%20Status...

Dorival Pedroso

unread,
Feb 23, 2012, 8:05:59 PM2/23/12
to golan...@googlegroups.com, gta
same problem here (with another package of mine)... 

Dorival Pedroso

unread,
Feb 23, 2012, 9:05:25 PM2/23/12
to golan...@googlegroups.com
Hi, I can confirm that the inferface(.h) files must be 'code-free' now; otherwise cgo produces 'multiple definition' s ...

I'm posting below an example code (calling Fortran <-> Go):

notes:
1) the code commented out in blue must be put in a c file;
2) I'm using global variables to communicate between Fortran and go because I'm still learning how to pass float64 arrays around ...;
3) I wonder if this code could be pretty coloured automatically here... ;-)

cheers.
dorival.

fortrancode.f
      subroutine FORTRANCODE(FCN,N,X,Y)
          ! FCN callback function: FCN(N,X,Y)
          ! N   size of arrays X and Y
          ! X   input array
          ! Y   output array = X**2.0D0
          implicit none
          external FCN
          integer N,I
          double precision X,Y
          dimension Y(N)
          call FCN(N,X,Y)
          write(6,'(a)') 'FORTRANCODE has finished'
      end subroutine

fcallback.h
#ifndef FCALLBACK_H
#define FCALLBACK_H

typedef void (*CFunction) (int *N, double *X, double *Y);

void fortrancode_(CFunction, int *N, double *X, double *Y);

int    *CC_N; // dimension
double *CC_X; // input vector (size=N)
double *CC_Y; // output vector (size=N)

/*
void cc_fcn(int *N, double *X, double *Y) {
    int i;
    for (i=0; i<(*N); ++i) { CC_X[i] = X[i]; }
    extern void go_fcn();
    go_fcn();
    for (i=0; i<(*N); ++i) { CC_Y[i] = Y[i]; }
}

void call_fortrancode() {
    fortrancode_(cc_fcn, CC_N, CC_X, CC_Y);
}
*/
void cc_fcn(int *N, double *X, double *Y);
void call_fortrancode();

#endif // FCALLBACK_H

fcallback.c
#include "fcallback.h"

void cc_fcn(int *N, double *X, double *Y) {
    int i;
    for (i=0; i<(*N); ++i) { CC_X[i] = X[i]; }
    extern void go_fcn();
    go_fcn();
    for (i=0; i<(*N); ++i) { CC_Y[i] = Y[i]; }
}

void call_fortrancode() {
    fortrancode_(cc_fcn, CC_N, CC_X, CC_Y);
}

gocallback.go
package main

/*
#cgo LDFLAGS: libfortrancode.so
#include "fcallback.h"
*/
import "C"

import (
"fmt"
"unsafe"
)

type Function func(n int, x, y []float64)

var (
GO_N   int       // dimension
GO_X   []float64 // input vector (size=N)
GO_Y   []float64 // output vector (size=N)
GO_FCN Function  // callback function
)

//export go_fcn
func go_fcn() {
GO_FCN(GO_N, GO_X, GO_X)
}

func powfcn(n int, x, y []float64) {
for i := 0; i < n; i++ {
y[i] = x[i] * x[i]
}
}

func main() {
// data
var n int = 10
x := make([]float64, n)
y := make([]float64, n)
for k, _ := range x {
x[k] = float64(k + 1)
}

// connect Go
GO_N, GO_X, GO_Y, GO_FCN = n, x, y, powfcn

// connect C
C.CC_N = (*C.int)(unsafe.Pointer(&GO_N))
C.CC_X = (*C.double)(unsafe.Pointer(&GO_X[0]))
C.CC_Y = (*C.double)(unsafe.Pointer(&GO_Y[0]))

// before: output
fmt.Printf("x(before) = %v\n", x)
fmt.Printf("y(before) = %v\n", x)

// call fortran code
C.call_fortrancode()

// after: output
fmt.Printf("x(after) = %v\n", x)
fmt.Printf("y(after) = %v\n", x)
}

CMakeLists.txt (for compiling a dynamic library with the Fortran code)
PROJECT(FORTRANCODE)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ENABLE_LANGUAGE(Fortran)
ADD_LIBRARY(fortrancode SHARED fortrancode.f)

test_callback-2012-02-24.tar.gz

Dorival Pedroso

unread,
Feb 23, 2012, 9:13:29 PM2/23/12
to golan...@googlegroups.com
hi, just to fix some typos:
this is correct => GO_FCN(GO_N, GO_X, GO_Y)
this is correct => fmt.Printf("y(before) = %v\n", y)
this is correct => fmt.Printf("y(after) = %v\n", y)
cheers.
dorival

Jim Teeuwen

unread,
Feb 24, 2012, 4:49:13 AM2/24/12
to golan...@googlegroups.com, gta
The glfw repository has been updated with a fix.
Reply all
Reply to author
Forward
0 new messages