-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/go: 'go build' of a SWIG only package fails with 'C source files not supported without cgo' #9410
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
Comments
I think there is an issue for this already somewhere.. but I can't find it. AFAIK you can throw an empty file like this one into your package directory as a workaround:
|
@slimsag I couldn't find an issue for this bug either. Thanks for adding the missing workaround. |
If the question is "how to stop go considering a directory containing only If this was not the question, ignore me.
|
@davecheney Clarification: |
It's more complicated than that. The current version of SWIG generates code that is expected to be compiled by 6c, but 6c no longer exists. Simply fixing gcToolchain.cc won't help. |
I see. So the C compilers have been already removed for Go 1.5. Unfortunately the doc http://golang.org/s/dev.cc doesn't mention what needs to happen to support SWIG again. Ian, what is the plan for SWIG? Is there a bug to follow other than this bug? |
I know of three possible approaches to fix SWIG (there is no tracking bug). The first approach is to change SWIG to generate cgo input rather than doing the same thing as cgo. This is the best approach because it should fix most SWIG issues for all time. It is probably also more complicated. The second approach is for the go tool to convert the _gc.c file generated by SWIG into Go. This is a mechanical translation, and will not require a new SWIG release. It's very ugly. The third approach is to change SWIG to add the _gc.c information to the .go file. This is not very satisfactory as the result will not work with versions of Go before 1.4. |
Hmm.... The second approach doesn't really sound like a viable solution to me. Letting the go tool parse the '_gc.c' file just to generate a Go source file does sound wrong to me as SWIG should generate working wrapper source out of the box. The third approach might be a viable solution but I'm not sold on the idea. I'm sure that SWIG could be changed to support pre-1.4 and post-1.3 simultaneously. In the worst case a SWIG command line switch like -py3 for Python 3 could switch between the versions. It looks relatively straight-forward to generate a Go source file similarly to the '_gc.c' file as 'runtime.h' and 'cgocall.h' have been replaced with / converted to Go equivalents. Maintaining two code paths in SWIG doesn't sound like a good idea though. The first approach does sound good to me and relatively straight-forward. If I'm not mistaken then SWIG has to generate a header file for cgo instead of a '_gc.c' file and the '.go' source file needs to make cgo calls (C. calls) instead of using _cgo_runtime_cgocall. In any case the go tool will need to be changed though. |
The point of the second approach is that it works for all versions of Go.
Using cgo, yes; otherwise, no. I'm really pretty sure I'm right about this. A command line option is painful for users, but it is true that we could have the go tool pass it. The first approach should work for all versions of Go when SWIG is invoked manually. It would not work for older versions of Go when using the older go tool. The main benefit of this approach is that it would work for all foreseeable versions of Go going forward, unlike the other approaches. Go is not going to break existing cgo programs. |
I propose this stop-gap solution before we switch swig to generate cgo We make swig generate two files x_gc.c for older pre 1.5 Go releases, The older Go release don't know about x_gc.go file, so it will continue to cmd/go from Go 1.5+ explicitly ignore x_gc.c and use x_gc.go. Go 1.5 What do you think? As long as people are only using cmd/go to build If people are using custom makefiles to build swig package, they will |
Based on my proposal, I've hacked a proof-of-concept: The patches don't fully work yet, but I believe there is no fundamental (Only one minor issue: because the wrapper variable are declared in |
@minux Regarding your init trick: |
That will be too incompatible with current cmd/go code: I don't think init trick is too big a problem. Actually, current cmd/gc |
OK, my POC implementation is working now. both misc/swig/stdio and misc/swig/callback are working. Most of the swig's Go examples are working fine, but these 3 I will investigate more tomorrow. |
OK, all these failing tests have one thing in common, Suggestions? |
Generating both files sounds like an interesting stopgap solution. Having SWIG generate cgo code can work with the Go tool by having the Go tool check the SWIG version, as indeed it already does. If SWIG is sufficiently new, the go tool can pass an option selecting cgo mode. (If SWIG is not sufficiently new, it won't work anyhow.) This is far less than ideal but I don't see another way to do it. The main advantage of the cgo approach is future proofing, as otherwise we are going to wind up doing this dance with every foreseeable Go release. It was a mistake of mine to not do this in the first place. Are you running the SWIG testsuite as well as the examples? (make check-go-test-suite). Instead of using an init function, you can use a real function that initializes everything once, and have every generated function call it. But in the long run we're going to want to do the cgo approach anyhow. |
The cgo approach would allow package maintainers to utilize swig from a That would be neat. On Tue, Jan 6, 2015 at 7:41 AM, Ian Lance Taylor notifications@github.com
Follow me on twitter @slimsag https://twitter.com/slimsag. |
If I use a real function, then I will need to declare that function in main If we will need to add a new switch to swig for the cgo approach, could we Running the SWIG Go test suite showed that a lot of C++ tests cases are |
Now I fixed the Makefile for the test-suite, and most of the tsets |
I found a way around the problem of the need to This solution used the fact that //go:linkname is The idea is that in the main Go file, we use //go:linkname In real swig implementations, we will need to rename A simple demo program: import ( var _swig_once sync.Once var A uintptr // to be initialized in swig_init //go:linkname swig_init_c swig_init_go func init() { func main() { // b_gc.c, file compiled by pre 1.5 go tool #include "runtime.h" // b_gc.go, file compiled by Go 1.5+ go tool package main import _ "unsafe" //go:linkname swig_init swig_init_go and we need a dummy c.s file to make sure go tool Then both @ianlancetaylor, what do you think about this solution? |
That is clever. That seems like a good temporary workaround. Please go ahead. You mention a dummy c.s file, but I assume that is only for the unusual case of running SWIG yourself (as the SWIG testsuite does). In the normal case SWIG will be run by the go tool, and the build tag and the dummy file are unnecessary. |
Yes. the dummy .s file and build tag is only needed to |
Done, all examples and tests have passed for Go 1.5 (tip). (Ian, do you mind me making the misc/swig/* tests a little more swig: https://github.com/minux/swig/tree/go1.5 (beware force updates) One question: I'm naming the global swig_init_go_PACKAGENAME, Please provide review comments, thanks! |
The -go-pkgpath option is really a gccgo concept, I'm worried that it might be confusing to use it with gc. Since the name can be anything, and doesn't have to be consistent, I would suggest sticking on the mangled absolute path of the swig file. If you can figure out how to get that. |
While it's easy to get the input file name (through Getattr(n, "infile")), Is there any predefined hash algorithms in SWIG? MD5 is probably My current code uses SipHash-2-4, with hardcoded key. It adds The changes are ready. Fully tested on Go 1.1.2, 1.2.1, 1.3.3, 1.4 |
I don't know if it's a good idea to introduce stdint.h into SWIG, nothing else seems to use it. SWIG actually uses pull requests. Can you send a pull request to the main SWIG repo? |
Sent swig/swig#301. The only concern for stdint.h is that MSVC used to not provide it, but |
This bug has been fixed with commit swig/swig@9ad497c. |
What version of Go are you using (go version)?
go version devel +f34964e Sun Dec 21 00:24:39 2014 +0000 linux/amd64
What operating system and processor architecture are you using?
linux/amd64 (Ubuntu 14.04 amd64)
What did you do?
Run 'go build' on this example: https://gist.github.com/michael-schaller/94a2ee39bde248c83742
What did you expect to see?
That 'go build' or 'go test' work as previously under Go 1.4 and earlier.
What did you see instead?
The error message 'C source files not supported without cgo'.
What else?
SWIG version: 3.0.3 (commit 93d58cd3ed1cc2cf0490e95d43eed4e8de62763d; master on 2014-12-21)
The text was updated successfully, but these errors were encountered: