Header files for -buildmode={c-archive,c-shared}

1,311 views
Skip to first unread message

Ian Lance Taylor

unread,
Apr 30, 2015, 5:02:56 PM4/30/15
to golan...@googlegroups.com
The new -buildmode=c-archive and -buildmode=c-shared options create an
archive or shared library that is callable from C code. The only
functions that are callable are those that are marked with //export in
files that import "C", as described in the cgo documentation.

The only purpose to using these options is to then write C (or C++,
etc.) code that will call these functions. The C code will need a
function declaration, implicit or explicit, to make the call. That
declaration will have to match the function in the Go code. Currently
there is no way to check that those declarations match.

The cgo tool already generates a header file that contains exactly the
declarations that we need. I propose that when the package a/b/c is
built for -buildmode=c-archive or -buildmode=c-shared, we install that
header file in $GOROOT/pkg/$GOOS_$GOARCH/a/b/c.h. That is, the header
file will appear right next to the .a file.

Then, the C code can #include "a/b/c.h" and be compiled with -I
$GOROOT/pkg/$GOOS_$GOARCH.

We should clean up the current header file slightly by adding some
more explanatory comments, and by copying and doc comments on the
//export function into the header file just before the declaration.

It is obviously very late in the cycle, but since c-archive and
c-shared are new in the 1.5 release, and this will make them more
usable, and since the change should not affect anything that does not
use the new options, I propose including this int the 1.5 release if
it can be completed in the next week.

Comments?

Ian

David Crawshaw

unread,
Apr 30, 2015, 6:06:43 PM4/30/15
to Ian Lance Taylor, golan...@googlegroups.com
On Thu, Apr 30, 2015 at 5:02 PM, Ian Lance Taylor <ia...@golang.org> wrote:
> The new -buildmode=c-archive and -buildmode=c-shared options create an
> archive or shared library that is callable from C code. The only
> functions that are callable are those that are marked with //export in
> files that import "C", as described in the cgo documentation.
>
> The only purpose to using these options is to then write C (or C++,
> etc.) code that will call these functions. The C code will need a
> function declaration, implicit or explicit, to make the call. That
> declaration will have to match the function in the Go code. Currently
> there is no way to check that those declarations match.
>
> The cgo tool already generates a header file that contains exactly the
> declarations that we need. I propose that when the package a/b/c is
> built for -buildmode=c-archive or -buildmode=c-shared, we install that
> header file in $GOROOT/pkg/$GOOS_$GOARCH/a/b/c.h. That is, the header
> file will appear right next to the .a file.

I guess you mean GOPATH, not GOROOT? If so, sounds reasonable.

But right now -buildmode=c-archive produces an archive file like the
go command does a binary. That is, it puts it in the current working
directory, not $GOPATH/pkg. Would you change it to put it in both? Or
just the pkg directory? And if just the pkg directory, what would be
the effect of -o?

> Then, the C code can #include "a/b/c.h" and be compiled with -I
> $GOROOT/pkg/$GOOS_$GOARCH.
>
> We should clean up the current header file slightly by adding some
> more explanatory comments, and by copying and doc comments on the
> //export function into the header file just before the declaration.
>
> It is obviously very late in the cycle, but since c-archive and
> c-shared are new in the 1.5 release, and this will make them more
> usable, and since the change should not affect anything that does not
> use the new options, I propose including this int the 1.5 release if
> it can be completed in the next week.
>
> Comments?
>
> Ian
>
> --
> You received this message because you are subscribed to the Google Groups "golang-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Matthew Dempsky

unread,
Apr 30, 2015, 6:20:05 PM4/30/15
to David Crawshaw, Ian Lance Taylor, golan...@googlegroups.com
On Thu, Apr 30, 2015 at 3:06 PM, David Crawshaw <craw...@golang.org> wrote:
I guess you mean GOPATH, not GOROOT? If so, sounds reasonable.

It seems like a lot of Makefiles will either assume $GOPATH is a single entry or need to duplicate logic for constructing multiple -I flags, one for each Go workspace.  Is it worth considering a standard pkg-config-like tool that could construct the appropriate compiler flags for users to avoid these difficulties?

David Crawshaw

unread,
Apr 30, 2015, 6:56:59 PM4/30/15
to Matthew Dempsky, Ian Lance Taylor, golan...@googlegroups.com
On Thu, Apr 30, 2015 at 6:19 PM, Matthew Dempsky <mdem...@google.com> wrote:
> It seems like a lot of Makefiles will either assume $GOPATH is a single
> entry or need to duplicate logic for constructing multiple -I flags, one for
> each Go workspace. Is it worth considering a standard pkg-config-like tool
> that could construct the appropriate compiler flags for users to avoid these
> difficulties?

Sounds like a topic that needs its own thread.

Ian Lance Taylor

unread,
May 1, 2015, 9:46:01 AM5/1/15
to David Crawshaw, golan...@googlegroups.com
On Thu, Apr 30, 2015 at 3:06 PM, David Crawshaw <craw...@golang.org> wrote:
> On Thu, Apr 30, 2015 at 5:02 PM, Ian Lance Taylor <ia...@golang.org> wrote:
>> The new -buildmode=c-archive and -buildmode=c-shared options create an
>> archive or shared library that is callable from C code. The only
>> functions that are callable are those that are marked with //export in
>> files that import "C", as described in the cgo documentation.
>>
>> The only purpose to using these options is to then write C (or C++,
>> etc.) code that will call these functions. The C code will need a
>> function declaration, implicit or explicit, to make the call. That
>> declaration will have to match the function in the Go code. Currently
>> there is no way to check that those declarations match.
>>
>> The cgo tool already generates a header file that contains exactly the
>> declarations that we need. I propose that when the package a/b/c is
>> built for -buildmode=c-archive or -buildmode=c-shared, we install that
>> header file in $GOROOT/pkg/$GOOS_$GOARCH/a/b/c.h. That is, the header
>> file will appear right next to the .a file.
>
> I guess you mean GOPATH, not GOROOT? If so, sounds reasonable.

Yes, GOPATH, sorry.

> But right now -buildmode=c-archive produces an archive file like the
> go command does a binary. That is, it puts it in the current working
> directory, not $GOPATH/pkg. Would you change it to put it in both? Or
> just the pkg directory? And if just the pkg directory, what would be
> the effect of -o?

Yes, I should have mentioned this issue. The problem is that if there
are multiple packages that export symbols, you can't reliably combine
the header files. The header files must contain the cgo preamble
comment, which will define types that the exported function may refer
to. There is no reason to expect that the preamble of multiple
packages is compatible. So you need one header file per package, so
you can't use the -o option to decide where to put them.

The header files can also depend on tags, which means they can depend
on GOOS/GOARCH. So they need to go in some directory heirarchy that
depends on GOOS/GOARCH, and we already have that under pkg.

Ian

Ian Lance Taylor

unread,
May 1, 2015, 9:47:11 AM5/1/15
to Matthew Dempsky, David Crawshaw, golan...@googlegroups.com
If such a facility seems useful, it could be part of "go env". We
don't need a new tool.

Ian

Russ Cox

unread,
May 5, 2015, 11:34:36 AM5/5/15
to Ian Lance Taylor, golan...@googlegroups.com
ok

Reply all
Reply to author
Forward
0 new messages