Trying to wrap C library with Cgo: undefined function

232 views
Skip to first unread message

buu700

unread,
May 23, 2011, 9:44:49 PM5/23/11
to golang-nuts
I'm trying to wrap the Discount Markdown implementation with Cgo so I
can have a high-performance Markdown-to-HTML function.

My source code tree is as follows:

--src/
------cmd/
----------discount.go
----------gohelper.c
----------Makefile
------pkg/
----------discount/ (Discount tree + compiled code)


discount.go
---
package discount


// #cgo LDFLAGS: -lmarkdown
// #include "gohelper.c"
import "C"

func Markdownify (md string) string {
var length C.int = (C.int)(len (md))
doc := C.mdtos (C.mkd_string ((C.CString(md)), length, 0))
var html string = string (C.GoString (doc))
return html
}
---


gohelper.c
---
#include "../pkg/discount/mkdio.h"


// Converts Discount type to a format usable within Go
static char* mdtos(MMIOT *md) {
char** mdc = (char**) md;
return *mdc;
}
---


Makefile
---
include $(GOROOT)/src/Make.inc

TARG=discount
CGOFILES=discount.go

include $(GOROOT)/src/Make.pkg
---



When I run make, this compiles correctly, giving the following output:
---
buu700@Canada:~/workspace/discount/src/cmd$ make
CGOPKGPATH= cgo -- discount.go
touch _obj/_cgo_run
6g -o _go_.6 _obj/discount.cgo1.go _obj/_cgo_gotypes.go
6c -FVw -I/usr/lib/go/pkg/linux_amd64 -I . -o "_cgo_defun.6" _obj/
_cgo_defun.c
gcc -m64 -I . -g -fPIC -O2 -o _cgo_main.o -c _obj/_cgo_main.c
gcc -m64 -I . -g -fPIC -O2 -o discount.cgo2.o -c _obj/
discount.cgo2.c
gcc -m64 -I . -g -fPIC -O2 -o _cgo_export.o -c _obj/_cgo_export.c
gcc -m64 -g -fPIC -O2 -o _cgo1_.o _cgo_main.o discount.cgo2.o
_cgo_export.o -lmarkdown
cgo -dynimport _cgo1_.o >_obj/_cgo_import.c_ && mv -f _obj/
_cgo_import.c_ _obj/_cgo_import.c
6c -FVw -I . -o "_cgo_import.6" _obj/_cgo_import.c
rm -f _obj/discount.a
gopack grc _obj/discount.a _go_.6 _cgo_defun.6 _cgo_import.6
discount.cgo2.o _cgo_export.o
---


I then copied _obj/discount.a to $GOROOT/pkg/linux_amd64/


To test the library, I wrote the following code:
---
package main

import "discount"
import "fmt"


func main() {
fmt.Printf (discount.Markdownify ("**hi**"))
}
---


However, when I try to use this, I get the following result:
---
buu700@Canada:~/workspace/discount$ 6g test.go
buu700@Canada:~/workspace/discount$ 6l test.6
/usr/lib/go/pkg/linux_amd64/discount.a(discount.cgo2.o)(.text):
mkd_string: not defined
mkd_string(0): not defined
---


Anyone have any idea what's up with this and/or what I should change?

I do have Discount installed, if that is at all relevant. Here is an
archive of my code: http://buu700.com/discount.tar.gz

buu700

unread,
May 23, 2011, 10:11:45 PM5/23/11
to golang-nuts
I should also add: changing the #include in gohelper.c to <mkdio.h>
gives the same results.

Jeremy Cowgar

unread,
May 23, 2011, 10:44:17 PM5/23/11
to golang-nuts
Is markdown a static library? I had the same problem recently and
found out Cgo only works with dynamic libraries.

Jeremy

buu700

unread,
May 23, 2011, 10:47:18 PM5/23/11
to golang-nuts
I'm not sure. How can I tell?

Evan Shaw

unread,
May 23, 2011, 11:00:35 PM5/23/11
to buu700, golang-nuts
On Tue, May 24, 2011 at 2:47 PM, buu700 <buu...@gmail.com> wrote:
> I'm not sure. How can I tell?

Judging from the archive you attached, you're using a static library.
The binary has a .a extension instead of a .so extension.

It looks like when building discount, you need to run configure.sh
with the --shared flag.

- Evan

buu700

unread,
May 23, 2011, 11:09:42 PM5/23/11
to golang-nuts
I just reinstalled Discount after configuring with the --shared flag,
but the output seems to be exactly the same. :/

Thanks.

Evan Shaw

unread,
May 24, 2011, 2:10:25 AM5/24/11
to buu700, golang-nuts
On Tue, May 24, 2011 at 3:09 PM, buu700 <buu...@gmail.com> wrote:
> I just reinstalled Discount after configuring with the --shared flag,
> but the output seems to be exactly the same. :/

Are you sure you're not still linking against the static library? I
downloaded your archive and did this:

cd discount/src/pkg/discount
make clean
./configure.sh --shared
make
sudo make install
cd ../../cmd
make install

After that, I'm able to compile and link test.go. It crashes, but
maybe you can debug it.

- Evan

buu700

unread,
May 24, 2011, 4:51:22 AM5/24/11
to golang-nuts
Thanks Evan. I never figured out quite what was going wrong with
Discount, so I decided to use Upskirt (as you suggested to me at Stack
Overflow), which was a lot simpler and seems to really nice.

If anyone else happens to have any use for this, here's my repository:
https://github.com/buu700/upskirt.go


Ryan

Jukka-Pekka Kekkonen

unread,
May 24, 2011, 12:20:35 PM5/24/11
to golan...@googlegroups.com
Hehe, I happened to write bindings for Upskirt too last weekend :)

buu700

unread,
May 25, 2011, 4:17:50 AM5/25/11
to golang-nuts
Haha, yeah, funny coincidence; turns out you wrote yours one day
before mine, and I had no idea because ours were added to the Upskirt
readme at the same time :P. I wouldn't call it a waste of effort,
though, because our two sets of bindings serve different purposes
(mine being to make rendering Markdown dead simple with no hassles and
yours being to expose the full functionality of Upskirt).


Ryan

On May 24, 12:20 pm, Jukka-Pekka Kekkonen <karatepe...@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages