The Wayback Machine - https://web.archive.org/web/20201204231858/https://github.com/go-python/gopy/issues/195
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined reference to `__imp_PyComplex_AsCComplex' on windows #195

Open
fluhus opened this issue Sep 12, 2019 · 4 comments
Open

Undefined reference to `__imp_PyComplex_AsCComplex' on windows #195

fluhus opened this issue Sep 12, 2019 · 4 comments

Comments

@fluhus
Copy link
Contributor

@fluhus fluhus commented Sep 12, 2019

Using go1.11, anaconda 3 and mingw-w64 gcc.

gopy pkg github.com/go-python/gopy/_examples/hi

Got:

--- Processing package: github.com/go-python/gopy/_examples/hi ---

--- building package ---
gopy pkg github.com/go-python/gopy/_examples/hi
goimports -w hi.go
go build -buildmode=c-shared -o hi_go.dll .
cmd had error: exit status 2  output:
# _/C_/Users/amit/Desktop/cgo/hi
C:\Users\amit\AppData\Local\Temp\go-build150779158\b001\_cgo_main.o:/tmp/go-build/cgo-generated-wrappers:2: undefined reference to `PyExc_RuntimeError'
C:\Users\amit\AppData\Local\Temp\go-build150779158\b001\_x002.o: In function `_cgo_5aac6852b843_Cfunc_PyComplex_AsCComplex':
/tmp/go-build/cgo-gcc-prolog:43: undefined reference to `__imp_PyComplex_AsCComplex'
C:\Users\amit\AppData\Local\Temp\go-build150779158\b001\_x002.o: In function `_cgo_5aac6852b843_Cfunc_PyComplex_FromDoubles':
/tmp/go-build/cgo-gcc-prolog:62: undefined reference to `__imp_PyComplex_FromDoubles'
C:\Users\amit\AppData\Local\Temp\go-build150779158\b001\_x002.o: In function `_cgo_5aac6852b843_Cfunc_PyErr_SetString':
/tmp/go-build/cgo-gcc-prolog:78: undefined reference to `__imp_PyErr_SetString'
collect2.exe: error: ld returned 1 exit status

2019/09/12 19:22:48 error dispatching command: exit status 2

I am not sure how to debug this. Happy to look into it if you have any leads for me.

@sbinet
Copy link
Member

@sbinet sbinet commented Sep 13, 2019

the first error being undefined reference to PyExc_RuntimeError'`, I suspect the link options are astray (or pointing to "the wrong" library).

you should look into the generated link options (the #cgo LDFLAGS part) to fix that.

@mrbbot
Copy link

@mrbbot mrbbot commented Sep 13, 2019

I was having the same issue but I've managed to get something working.

I first ran gopy gen -output=out github.com/go-python/gopy/_examples/hi and then editted the following files:

In out/Makefile, I changed LDFLAGS to -L<python_root>/libs -lpython37 (the 37 will depend on the Python version you're using). I also changed LIBEXT to .pyd as Python didn't recognise the .dll outputs as valid imports. For reference, my Makefile looks like this:

# Makefile for python interface for package hi.
# File is generated by gopy. Do not edit.
# gopy gen -output=out github.com/go-python/gopy/_examples/hi

GOCMD=go
GOBUILD=$(GOCMD) build
GOIMPORTS=goimports
PYTHON=C:\Users\MrBBot\AppData\Local\Programs\Python\Python37\python.exe
LIBEXT=.pyd

# get the CC and flags used to build python:
GCC = $(shell $(GOCMD) env CC)
CFLAGS = -IC:/Users/MrBBot/AppData/Local/Programs/Python/Python37/include
LDFLAGS = -LC:/Users/MrBBot/AppData/Local/Programs/Python/Python37/libs -lpython37

all: gen build

gen:
	gopy gen github.com/go-python/gopy/_examples/hi

build:
	# build target builds the generated files -- this is what gopy build does..
	# this will otherwise be built during go build and may be out of date
	- rm hi.c
	# goimports is needed to ensure that the imports list is valid
	$(GOIMPORTS) -w hi.go
	# generate hi_go$(LIBEXT) from hi.go -- the cgo wrappers to go functions
	$(GOBUILD) -buildmode=c-shared -o hi_go$(LIBEXT) hi.go
	# use pybindgen to build the hi.c file which are the CPython wrappers to cgo wrappers..
	# note: pip install pybindgen to get pybindgen if this fails
	$(PYTHON) build.py
	# build the _hi$(LIBEXT) library that contains the cgo and CPython wrappers
	# generated hi.py python wrapper imports this c-code package
	$(GCC) hi.c  hi_go$(LIBEXT) -o _hi$(LIBEXT) $(CFLAGS) $(LDFLAGS) -fPIC --shared -w

I also changed the LDFLAGS in out/hi.go to match those in the Makefile:

/*
cgo stubs for package hi.
File is generated by gopy. Do not edit.
gopy gen -output=out github.com/go-python/gopy/_examples/hi
*/

package main

/*

#cgo CFLAGS: -IC:/Users/MrBBot/AppData/Local/Programs/Python/Python37/include
#cgo LDFLAGS: -LC:/Users/MrBBot/AppData/Local/Programs/Python/Python37/libs -lpython37

...
*/

Then I ran make build in the out directory. After this finished, I just started a python shell in the out directory and was able to import hi. Something like hi.Hello("MrBBot") then worked.

A fix shouldn't be too hard but I'm not sure if adding these specific relatives paths for the linker flags would break anything on platforms other than Windows.

@fluhus
Copy link
Contributor Author

@fluhus fluhus commented Sep 13, 2019

Thanks guys!

@mrbbot, your local fix worked. It gave me a clue on where to look for the problem.

@sbinet you were right. Originally I got LDFLAGS = -L -l in both makefile and #cgo comment. I found the problem here. ds.get_config_vars() doesn't have the required information on windows (at least on my installation). On linux with anaconda3 I do get all the information.

This is what I get from ds.get_config_vars() on windows with anaconda:

{
  "LIBDEST": "C:\\dev\\tools\\anaconda3\\Lib",
  "BINLIBDEST": "C:\\dev\\tools\\anaconda3\\Lib",
  "INCLUDEPY": "C:\\dev\\tools\\anaconda3\\include",
  "EXT_SUFFIX": ".cp36-win_amd64.pyd",
  "EXE": ".exe",
  "VERSION": "36",
  "BINDIR": "C:\\dev\\tools\\anaconda3",
  "prefix": "C:\\dev\\tools\\anaconda3",
  "exec_prefix": "C:\\dev\\tools\\anaconda3",
  "SO": ".cp36-win_amd64.pyd",
  "srcdir": "C:\\dev\\tools\\anaconda3"
}

With pypy even less:

{
  "LIBDEST": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32\\lib-python\\3",
  "BINLIBDEST": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32\\lib-python\\3",
  "INCLUDEPY": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32\\include",
  "EXT_SUFFIX": ".pypy3-71-win32.pyd",
  "EXE": ".exe",
  "VERSION": "36",
  "BINDIR": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32",
  "prefix": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32",
  "exec_prefix": "C:\\Users\\amit\\Desktop\\pypy3.6-v7.1.1-win32"
}

One possible solution is to craft those values manually on windows. Something like:

if raw.LibDir == "" {
    raw.LibDir = prefix + "libs"
}
if raw.LibPy == "" {
    raw.LibPy = "python" + versionWithMinor
}

What do you think?

@SeanTolstoyevski
Copy link

@SeanTolstoyevski SeanTolstoyevski commented Nov 5, 2019

Hello,

@mrbbot fixes compilation errors in Windows.

But making them manually is exhausting. There may be common mistakes for a developer,
nightmare for the beginning level.

I think these errors need to be fixed for Windows. The project is not actively developed,
but it would be great to get rid of this trouble.

#201 . There also seems to be these errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants
You can’t perform that action at this time.