Navigation Menu

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

cmd/go: Support C/C++ compiler flags when using SWIG through the build tool #6696

Closed
ane opened this issue Oct 31, 2013 · 19 comments
Closed

Comments

@ane
Copy link

ane commented Oct 31, 2013

In tip, there's support for using SWIG through the build tool. This works actually
really well now, but one problem is that if one wishes to pass compiler options to the
C/C++ compiler, none of the flags supported by the build tool seem to support that. 

An example workaround is to run:

    "CC=gcc <flag1> <flag2> <flag3>" go build

but it's rather awkward. Something similar how Cgo handles compiler flags, perhaps.
@gopherbot
Copy link

Comment 1 by travis.cline:

Might this be added via a -swigflags ?

Attachments:

  1. addswigflags.diff (1889 bytes)

@gopherbot
Copy link

Comment 2 by travis.cline:

Updated with go test support

Attachments:

  1. addswigflags.diff (2595 bytes)

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 3:

Labels changed: added go1.3maybe.

@dsymonds
Copy link
Contributor

Comment 4:

Labels changed: added toolchange.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 5:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 6:

Labels changed: added repo-main.

@slimsag
Copy link

slimsag commented Dec 24, 2013

Comment 7:

Travis,
I don't think -swigflags is a good choice. Consider that a application depends on
multiple packages that use swig to each wrap an external C++ library; when building the
application you would have to specify -swigflags and pass in each package's
header/library dependencies?
I think a better approach might be to use something like CGO does with it's 'magic'
"#cgo CFLAGS: foo" and "#cgo LDFLAGS: foo" (only adapted for swig) because then compiler
and linker flags could be set per-package and it would be less tedius.
I'm not sure that -swigflags would really have any benifits over the example workaround
from the OP.
Stephen

@alberts
Copy link
Contributor

alberts commented Apr 7, 2014

Comment 8:

Also just ran into this. I would like the ability to set something like CGO_CFLAGS and
CGO_LDFLAGS when building my SWIG package.

@slimsag
Copy link

slimsag commented May 13, 2014

Comment 9:

My proposed CL is at:
https://golang.org/cl/96320043

@gopherbot
Copy link

Comment 10:

CL https://golang.org/cl/96320043 mentions this issue.

@gopherbot
Copy link

Comment 11 by ivar.gaitan:

I also struggled a bit with this.
Then I found out that the swig build chain uses the flags set by cgo. So by adding a
dummy file alongside the .swigcxx with only #cgo directives and import "C", cgo will be
invoked prior to swig, and the flags you set with #cgo will be passed on to your swig
build.

@steeve
Copy link
Contributor

steeve commented Nov 12, 2014

Comment 12:

Not all of them though, only -I

@ane ane added new labels Nov 12, 2014
@bradfitz bradfitz removed the new label Dec 18, 2014
@michael-schaller
Copy link
Contributor

@slimsag
Stephen, do you think you can update the patch for the Go 1.5 release?
FYI: The Go master seems to have currently issues with SWIG only packages. See issue #9410 for details.

@slimsag
Copy link

slimsag commented Dec 22, 2014

@michael-schaller

Yes, I'll do my best to get it in ASAP and before the Go 1.5 feature freeze. I will prioritize it and hopefully have it in before (or around) Jan, 1st.

@michael-schaller
Copy link
Contributor

@slimsag
Awesome. I'm happy to test it. Could you also add swigopts so that one can pass custom options like -Wall -Werror to SWIG?

@michael-schaller
Copy link
Contributor

@slimsag
Stephen, do you still have plans to get this in before the Go 1.5 feature freeze?

@slimsag
Copy link

slimsag commented Apr 2, 2015

@michael-schaller apologies for my latency on this issue.

I've just checked and we do not need to do anything to support this use case anymore.

Since SWIG code is now built using CGO instead of the old plan-9 C compilers, you can simply use a build.go file containing import "C" and #cgo key: value directives as part of your package containing the .swig file. I've put together a simple example to demonstrate this (see below).

At this point, unless there is opposition to using the #cgo directives in combination with SWIG code for some reason, we can close this issue.

$ tree
.
├── main.go
├── mylib
│   ├── build.sh
│   ├── mylib.c
└── mypkg
    ├── code.c
    ├── mypkg.go
    └── mypkg.swig

2 directories, 6 files

The main.go program is very simple (and external from the SWIG wrapper package):

$ cat main.go
package main

import "cflags/mypkg"

func main() {
  mypkg.DoStuff()
}

mylib is a simple C dynamic library I built:

$ cat mylib/build.sh 
gcc -c -Wall -Werror -fPIC mylib.c
gcc -shared -o libmylib.so mylib.o
$ cat mylib/mylib.c
int mylib_add(int a, int b) {
    return a + b;
}

Then I declared a simple C function in the SWIG package to retrieve a preprocessor-defined value (see -DGENERIC_VALUE=32 below):

$ cat mypkg/code.c 
int generic_value = GENERIC_VALUE;

int get_generic_value(void) {
    return generic_value;
}

The SWIG package has the grunt of the code and our #cgo build directives:

$ cat mypkg/mypkg.go
package mypkg

// #cgo CFLAGS: -DGENERIC_VALUE=32
// #cgo LDFLAGS: -L${SRCDIR}/../mylib/ -lmylib
import "C"

import "log"

func DoStuff() {
    // Test that the GENERIC_VALUE defined in the C compiler flags is correct.
    v := Get_generic_value()
    if v != 32 {
        log.Fatal("got unexpected value")
    }
    log.Println("got the right value", v)
    log.Println("mylib_add(2, 2):", Mylib_add(2, 2))
}
$ cat mypkg/mypkg.swig 
/* A trivial example of using CGO compiler flags with SWIG.  */

int get_generic_value(void);

int mylib_add(int a, int b);

Build and run it:

cd mylib/
./build.sh # builds libmylib.so
cd ..
go build # builds the main program binary named 'cflags'

# run the program with libmylib.so on LD_LIBRARY_PATH:
LD_LIBRARY_PATH=mylib/ ./cflags

which produces:

2015/04/02 12:22:27 got the right value 32
2015/04/02 12:22:27 mylib_add(2, 2): 4

@ianlancetaylor
Copy link
Contributor

Thanks for the worked example.

@michael-schaller
Copy link
Contributor

@slimsag
Stephen, thank you for testing this. I gave my code also a test run and I confirm that it works fine with current Go 1.5 and SWIG 3.0.6 snapshots. In the past I still needed a dummy .cpp file for cgo to properly link against a C++ library wrapped with SWIG. With the current code this workaround is no longer necessary. Awesome! :-D

@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants