xlab / c-for-go

Automatic C-Go Bindings Generator for Go Programming Language
https://c.for-go.com
MIT License
1.5k stars 120 forks source link

[Help] Sundials #67

Open mantielero opened 5 years ago

mantielero commented 5 years ago

Hello I am trying to create some bindings with Sundials. I have little clue about C/C++ and I have just started with Go a couple of weeks ago.

After this disclaimer, I am trying to start little by little with the bindings. What I have now is:

---
GENERATOR:
  PackageName: test
  PackageDescription: "Sundial's nvector-serial"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  #PkgConfigOpts: []
  Includes:
    #- "../sundials-master/build/include/sundials/sundials_config.h"
    - "../sundials-master/include/sundials/sundials_types.h" # This gets included in cgo_helpers.go
    - "../sundials-master/include/sundials/sundials_math.h"
  Options:
    SafeStrings: true

PARSER:
  IncludePaths: ["sundials-master/build/include/", "sundials-master/include/", "/usr/include",  "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/include/"]
  #SourcesPaths: [ "./sundials-master/include/nvector/nvector_serial.h"]
  SourcesPaths:
    #- "./sundials-master/build/include/sundials/sundials_config.h"
    - "./sundials-master/include/sundials/sundials_types.h"
    - "./sundials-master/include/sundials/sundials_math.h"

TRANSLATOR:
  ConstRules:
    defines: eval
    enums: eval
  Defines:
    SUNDIALS_MPI_COMM_F2C: 1
    SUNDIALS_DOUBLE_PRECISION: yes
  #TypeTips:
  #  function:
  #    - {target: "^opus_", self: plain, tips: [plain,plain,plain,plain,plain]}
  #PtrTips:
  #  function:
  #    - {target: "^fmi2_set_debug_logging", tips: [0,0,size,arr] }
      #- {target: "_encoder_create$", tips: [0,0,0,ref]}
      #- {target: "_decoder_create$", tips: [0,0,ref]}
      #- {target: "_multistream_packet_unpad$", tips: [0,size,0]}
      #- {target: "_multistream_packet_pad$", tips: [0,size,size,0]}
      #- {target: "_packet_unpad$", tips: [0,size]}
      #- {target: "_packet_pad$", tips: [0,size,size]}
      #- {target: "_pcm_soft_clip$", tips: [arr,0,0,arr]}
      #- {target: ^opus_, tips: [ref]}
  Rules:
    global:
      - {transform: title}
      - {action: accept, from: "^N_V"}
      #- {action: accept, from: "^C"}
      #- {action: accept, from: "^SUNMatrix"}
      - {action: accept, from: "^SUNDIALS"}
      - {action: accept, from: "^SUN"}      
      - {action: accept, from: "^RCONST"}
      - {transform: export}
    #function:
    #  - {action: ignore, from: "fmi2_default_callback_logger"} #variadic
    #  - {action: ignore, from: "fmi2_log_forwarding"}  # variadic
    #  - {action: ignore, from: "jm_log"} # variadic
    #  - {action: ignore, from: "_encoder_ctl"} # variadic
    #  - {action: ignore, from: "_decoder_ctl"} # variadic
    #  - {action: ignore, from: "_packet_parse"} # internal

    const:
      - {action: accept, from: "^SUN"}
      - {action: ignore, from: "^SUNDIALS_MPI_COMM_F2C"}
      - {action: accept, from: "^BIG"}
      - {action: accept, from: "^SMALL"}
      - {action: accept, from: "^UNIT"}
      - {action: accept, from: "^_SUNDIALSMATH"}
      - {transform: export}
    type:
      #- {action: accept, from: "^_N"}
      - {action: accept, from: "^FILE"}
      - {action: accept, from: "^N_V"}
      - {action: accept, from: "^sunindextype"}
      - {action: accept, from: "^realtype"}
      - {action: accept, from: "^booleantype"}
      #- {action: accept, from: "^C"}
      #- {action: accept, from: "^SUNMatrix"}
      #- {action: replace, from: "_t$"}
    private:
      - {transform: unexport}
    post-global:
      - {action: replace, from: _$}
      - {load: snakecase}

When I run go build, I get:

# _/home/jose/src/golang/sundials/test
/usr/bin/ld: $WORK/b001/_x004.o: en la función `_cgo_f88c58d04f65_Cfunc_SUNRpowerI':
/tmp/go-build/cgo-gcc-prolog:53: referencia a `SUNRpowerI' sin definir
/usr/bin/ld: $WORK/b001/_x004.o: en la función `_cgo_f88c58d04f65_Cfunc_SUNRpowerR':
/tmp/go-build/cgo-gcc-prolog:72: referencia a `SUNRpowerR' sin definir
collect2: error: ld devolvió el estado de salida 1

meaning something like: reference to 'SUNRpowerI' not defined.

xlab commented 5 years ago

Looks like headers are there, but you missed couple of shared libraries from including in LDFLAGS. So function SUNRpowerI is referenced, but not linked.

Put a file that is hand written that will include libs for each platforms correctly. Example: https://github.com/go-gl/glfw/blob/master/v3.2/glfw/build.go

Official doc on cgo directives: https://golang.org/cmd/cgo/

mantielero commented 5 years ago

I am trying with a different bit of sundials to see if I have better success. I am trying to bind with libsundials_nvecserial.so.

I have Sundials installed in Archlinux. The libraries available are:

/usr/lib/libsundials_arkode.so
/usr/lib/libsundials_cvode.so
/usr/lib/libsundials_cvodes.so
/usr/lib/libsundials_fnvecopenmp.so
/usr/lib/libsundials_fnvecparallel.so
/usr/lib/libsundials_fnvecserial.so
/usr/lib/libsundials_fsunlinsolband.so
/usr/lib/libsundials_fsunlinsoldense.so
/usr/lib/libsundials_fsunlinsolklu.so
/usr/lib/libsundials_fsunlinsolpcg.so
/usr/lib/libsundials_fsunlinsolspbcgs.so
/usr/lib/libsundials_fsunlinsolspfgmr.so
/usr/lib/libsundials_fsunlinsolspgmr.so
/usr/lib/libsundials_fsunlinsolsptfqmr.so
/usr/lib/libsundials_fsunmatrixband.so
/usr/lib/libsundials_fsunmatrixdense.so
/usr/lib/libsundials_fsunmatrixsparse.so
/usr/lib/libsundials_fsunnonlinsolfixedpoint.so
/usr/lib/libsundials_fsunnonlinsolnewton.so
/usr/lib/libsundials_ida.so
/usr/lib/libsundials_idas.so
/usr/lib/libsundials_kinsol.so
/usr/lib/libsundials_nvecopenmp.so
/usr/lib/libsundials_nvecparallel.so
/usr/lib/libsundials_nvecserial.so
/usr/lib/libsundials_sunlinsolband.so
/usr/lib/libsundials_sunlinsoldense.so
/usr/lib/libsundials_sunlinsolklu.so
/usr/lib/libsundials_sunlinsolpcg.so
/usr/lib/libsundials_sunlinsolspbcgs.so
/usr/lib/libsundials_sunlinsolspfgmr.so
/usr/lib/libsundials_sunlinsolspgmr.so
/usr/lib/libsundials_sunlinsolsptfqmr.so
/usr/lib/libsundials_sunmatrixband.so
/usr/lib/libsundials_sunmatrixdense.so
/usr/lib/libsundials_sunmatrixsparse.so
/usr/lib/libsundials_sunnonlinsolfixedpoint.so
/usr/lib/libsundials_sunnonlinsolnewton.so

The file that I am using now is:

---
GENERATOR:
  PackageName: nvector
  PackageDescription: "Sundial's nvector-serial"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  #PkgConfigOpts:
  #  - sundials
  FlagGroups:
    - {name: "LDFLAGS", flags: ["-lsundials_nvecserial", "-L/usr/lib"]}
  SysIncludes: #["../sundials-master/include/nvector/nvector_serial.h", "../sundials-master/include/sundials/sundials_nvector.h"] # This gets included in cgo_helpers.go
    - stdio.h
    - sundials/sundials_types.h
    - nvector/nvector_serial.h
    - sundials/sundials_math.h
  Options:
    SafeStrings: true

PARSER:
  IncludePaths: ["/usr/include", "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/include/"]
  SourcesPaths:
    - "/usr/include/sundials/sundials_types.h"
    - "/usr/include/nvector/nvector_serial.h"
    - "/usr/include/sundials/sundials_math.h"
    #- "<sundials/sundials_types.h>"
    #- "<nvector/nvector_serial.h>"
    #- "<sundials/sundials_math.h>"

  #SourcesPaths: [ "./sundials-master/include/nvector/nvector_serial.h", "./sundials-master/include/sundials/sundials_nvector.h"] #"sundials-master/include/nvector/nvector_mpiraja.h", "sundials-master/include/nvector/nvector_openmpdev.h", "sundials-master/include/nvector/nvector_openmp.h",]

TRANSLATOR:
  ConstRules:
    defines: eval
    enums: eval

  #TypeTips:
  #  function:
  #    - {target: "^opus_", self: plain, tips: [plain,plain,plain,plain,plain]}
  #PtrTips:
  #  function:
  #    - {target: "^fmi2_set_debug_logging", tips: [0,0,size,arr] }
      #- {target: "_encoder_create$", tips: [0,0,0,ref]}
      #- {target: "_decoder_create$", tips: [0,0,ref]}
      #- {target: "_multistream_packet_unpad$", tips: [0,size,0]}
      #- {target: "_multistream_packet_pad$", tips: [0,size,size,0]}
      #- {target: "_packet_unpad$", tips: [0,size]}
      #- {target: "_packet_pad$", tips: [0,size,size]}
      #- {target: "_pcm_soft_clip$", tips: [arr,0,0,arr]}
      #- {target: ^opus_, tips: [ref]}
  Rules:
    global:
      #- {transform: title}
      - {action: accept, from: "^N_V"}
      - {action: accept, from: "^SUNDIALS"}
      - {action: accept, from: "^SUN"}
      - {action: accept, from: "^RCONST"}
      - {transform: export}
    #function:
    #  - {action: ignore, from: "fmi2_default_callback_logger"} #variadic
    #  - {action: ignore, from: "fmi2_log_forwarding"}  # variadic
    #  - {action: ignore, from: "jm_log"} # variadic
    #  - {action: ignore, from: "_encoder_ctl"} # variadic
    #  - {action: ignore, from: "_decoder_ctl"} # variadic
    #  - {action: ignore, from: "_packet_parse"} # internal

    const:
      - {action: accept, from: "^SUN"}
      - {action: ignore, from: "^SUNDIALS_MPI_COMM_F2C"}
      - {action: accept, from: "^BIG"}
      - {action: accept, from: "^NV"}
      - {action: accept, from: "^SMALL"}
      - {action: accept, from: "^UNIT"}
      - {action: accept, from: "^_SUNDIALSMATH"}
      - {transform: export}

    type:
      - {action: accept, from: "^_N"}
      - {action: accept, from: "^FILE"}
      - {action: accept, from: "^N_V"}
      - {action: accept, from: "^sunindextype"}
      - {action: accept, from: "^realtype"}
      - {action: accept, from: "^booleantype"}
      #- {action: accept, from: "^C"}
      #- {action: accept, from: "^SUNMatrix"}
      #- {action: replace, from: "_t$"}
    private:
      - {transform: unexport}
    post-global:
      - {action: replace, from: _$}
      - {load: snakecase}

When I run go build, I have similar failures as before:

# _/home/jose/src/golang/sundials/nvector
/usr/bin/ld: $WORK/b001/_x004.o: en la función `_cgo_59e8d818a059_Cfunc_N_VClone':
/tmp/go-build/cgo-gcc-prolog:105: referencia a `N_VClone' sin definir
/usr/bin/ld: $WORK/b001/_x004.o: en la función `_cgo_59e8d818a059_Cfunc_N_VCloneEmpty':

(in the function .... reference to N_VClone undefined.

I have :

  FlagGroups:
    - {name: "LDFLAGS", flags: ["-lsundials_nvecserial", "-L/usr/lib"]}

given that I am aiming to link against libsundials_nvecserial.so.

Is this what you where suggesting? Any other clue?

Regards and thanks for your help.

xlab commented 5 years ago

@mantielero these flags look correct, could you check if they are there after generation? Please give me some head (10 lines) of some of the resulting files.

Also, make sure that libraries are from the same version. If headers are newer, some functions referenced may not yet exist in .so libs that are distributed. This is a common issue.

mantielero commented 5 years ago

I have uploaded to a repository my experiments:

mantielero commented 5 years ago

I have compiled one of the examples that comes with the library as follows:

[jose@mountain tmp]$ make
/usr/bin/cc -O3 -DNDEBUG -O3 -DNDEBUG -I/usr/include -I/usr/include -c test_nvector.c
/usr/bin/cc -O3 -DNDEBUG -O3 -DNDEBUG -I/usr/include -I/usr/include -c sundials_nvector.c
/usr/bin/cc -O3 -DNDEBUG -O3 -DNDEBUG -I/usr/include -I/usr/include -c test_nvector_serial.c
/usr/bin/cc -o test_nvector_serial test_nvector_serial.o test_nvector.o sundials_nvector.o -O3 -DNDEBUG  -I/usr/include -I/usr/include -L/usr/lib -lsundials_nvecserial -lsundials_nvecserial -lm /usr/lib/librt.so -Wl,-rpath,/usr/lib

being the Makefile:

# -*- mode: makefile -*-
# -----------------------------------------------------------------
# Programmer(s): Radu Serban @ LLNL
#                David J. Gardner @ LLNL
# -----------------------------------------------------------------
# SUNDIALS Copyright Start
# Copyright (c) 2002-2019, Lawrence Livermore National Security
# and Southern Methodist University.
# All rights reserved.
#
# See the top-level LICENSE and NOTICE files for details.
#
# SPDX-License-Identifier: BSD-3-Clause
# SUNDIALS Copyright End
# -----------------------------------------------------------------
# Makefile for  serial examples
#
# This file is generated from a template using variables
# set at configuration time. It can be used as a template for
# other user Makefiles.
# -----------------------------------------------------------------

SHELL = sh

prefix       = /usr
exec_prefix  = /usr
includedir   = /usr/include
libdir       = /usr/lib

CPP      = /usr/bin/cc
CPPFLAGS = -O3 -DNDEBUG
CC       = /usr/bin/cc
CFLAGS   = -O3 -DNDEBUG
LDFLAGS  = 
LIBS     =  -lm /usr/lib/librt.so

LINKFLAGS = -Wl,-rpath,/usr/lib

# -----------------------------------------------------------------------------------------

LIBRARIES_LAPACK = -lsundials_sunlinsollapackdense -lsundials_sunlinsollapackband  
LINKFLAGS_LAPACK = ${LINKFLAGS}::

INCLUDES_KLU  = /usr/include
LIBRARIES_KLU = -lsundials_sunlinsolklu   /usr/lib/libklu.so /usr/lib/libamd.so /usr/lib/libcolamd.so /usr/lib/libbtf.so /usr/lib/libsuitesparseconfig.so
LINKFLAGS_KLU = ${LINKFLAGS}:/usr/lib

INCLUDES_SLUMT  = 
LIBRARIES_SLUMT = -lsundials_sunlinsolsuperlumt  
LINKFLAGS_SLUMT = ${LINKFLAGS}::

TMP_INCS  = ${includedir} ${INCLUDES_SLUMT} ${INCLUDES_KLU}
INCLUDES  = $(addprefix -I, ${TMP_INCS})
LIBRARIES = -lsundials_nvecserial -lsundials_nvecserial ${LIBS}

# -----------------------------------------------------------------------------------------

EXAMPLES =  test_nvector_serial
EXAMPLES_DEPENDENCIES =  test_nvector sundials_nvector

OBJECTS = ${EXAMPLES:=.o}
OBJECTS_DEPENDENCIES = ${EXAMPLES_DEPENDENCIES:=.o}

# LAPACK Examples
EXAMPLES_BL = 
EXAMPLES_DEPENDENCIES_BL = 

OBJECTS_BL = ${EXAMPLES_BL:=.o}
OBJECTS_DEPENDENCIES_BL = ${EXAMPLES_DEPENDENCIES_BL:=.o}

# KLU Examples
EXAMPLES_KLU = 
EXAMPLES_DEPENDENCIES_KLU = 

OBJECTS_KLU = ${EXAMPLES_KLU:=.o}
OBJECTS_DEPENDENCIES_KLU = ${EXAMPLES_DEPENDENCIES_KLU:=.o}

# SuperLU_MT Examples
EXAMPLES_SLUMT = 
EXAMPLES_DEPENDENCIES_SLUMT = 

OBJECTS_SLUMT = ${EXAMPLES_SLUMT:=.o}
OBJECTS_DEPENDENCIES_SLUMT = ${EXAMPLES_DEPENDENCIES_SLUMT:=.o}

# -----------------------------------------------------------------------------------------

.SUFFIXES : .o .c

.c.o :
    ${CC} ${CPPFLAGS} ${CFLAGS} ${INCLUDES} -c $<

# -----------------------------------------------------------------------------------------

all: examples examples_bl examples_klu examples_slumt

examples: ${OBJECTS}
    @for i in ${EXAMPLES} ; do \
      echo "${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LINKFLAGS}" ; \
      ${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LINKFLAGS} ; \
    done

examples_bl: ${OBJECTS_BL}
    @for i in ${EXAMPLES_BL} ; do \
      echo "${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_BL} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_LAPACK} ${LINKFLAGS_LAPACK}" ; \
      ${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_BL} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_LAPACK} ${LINKFLAGS_LAPACK} ; \
    done

examples_klu: ${OBJECTS_KLU}
    @for i in ${EXAMPLES_KLU} ; do \
      echo "${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_KLU} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_KLU} ${LINKFLAGS_KLU}" ; \
      ${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_KLU} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_KLU} ${LINKFLAGS_KLU} ; \
    done

examples_slumt: ${OBJECTS_SLUMT}
    @for i in ${EXAMPLES_SLUMT} ; do \
      echo "${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_SLUMT} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_SLUMT} ${LINKFLAGS_SLUMT}" ; \
      ${CC} -o $${i} $${i}.o ${OBJECTS_DEPENDENCIES_SLUMT} ${CFLAGS} ${LDFLAGS} ${INCLUDES} -L${libdir} ${LIBRARIES} ${LIBRARIES_SLUMT} ${LINKFLAGS_SLUMT} ; \
    done

${OBJECTS}: ${OBJECTS_DEPENDENCIES}

${OBJECTS_BL}: ${OBJECTS_DEPENDENCIES_BL}

${OBJECTS_KLU}: ${OBJECTS_DEPENDENCIES_KLU}

${OBJECTS_SLUMT}: ${OBJECTS_DEPENDENCIES_SLUMT}

clean:
    rm -f ${OBJECTS_DEPENDENCIES} ${OBJECTS_DEPENDENCIES_BL} ${OBJECTS_DEPENDENCIES_KLU} ${OBJECTS_DEPENDENCIES_SLUMT}
    rm -f ${OBJECTS} ${OBJECTS_BL} ${OBJECTS_KLU} ${OBJECTS_SLUMT}
    rm -f ${EXAMPLES} ${EXAMPLES_BL} ${EXAMPLES_KLU} ${EXAMPLES_SLUMT}

# -----------------------------------------------------------------------------------------

I am not sure if this helps.

xlab commented 5 years ago

I have #cgo LDFLAGS: -L/usr/local/lib -lsundials_nvecserial -lsundials_cvodes -lm and it worked for me, you can try to include all other libs to find missing symbols. Also, instead of using distro version (from /usr/lib) I used cmake to build and install master version from your repo.

You can check if files in your system contain those symbols:

grep -r "SUNRpowerI" /usr/lib
mantielero commented 5 years ago

Yes. It looks like -lsundials_cvodes was missing. Please, keep this issue opened since I am pretty sure I will keep facing issues.