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

go/build: does not support examples that use cgo #20381

Open
bcmills opened this issue May 16, 2017 · 4 comments
Open

go/build: does not support examples that use cgo #20381

bcmills opened this issue May 16, 2017 · 4 comments
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@bcmills
Copy link
Contributor

bcmills commented May 16, 2017

While prototyping a library to work around #13656, I ran in to a pretty major issue with the godoc tool. It doesn't generate any documentation at all for packages whose tests use cgo, which implies that packages designed for use with cgo cannot contain idiomatic examples.

bcmills:~/src$ go version
go version devel +b53acd89db Tue May 16 17:15:11 2017 +0000 linux/amd64
bcmills:~/src$ go tool doc cslice
doc: use of cgo in test /usr/local/google/home/bcmills/src/cslice/cslice_test.go not supported

cslice/cslice_test.go:

package cslice_test

/*
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
*/
import "C"

import (
	"fmt"
	"reflect"
	"testing"
	"unsafe"

	"cslice"
)

func ExampleSetAt() {
	var (
		original *C.char  = C.CString("Hello, world!")
		sz       C.size_t = C.strlen(original)
	)
	defer C.free(unsafe.Pointer(original))

	var alias []byte
	cslice.SetAt(&alias, unsafe.Pointer(original), int(sz))

	fmt.Println("original:", C.GoString(original))
	fmt.Println("alias:", string(alias))
	copy(alias, "Adios")
	fmt.Println("original:", C.GoString(original))
	fmt.Println("alias:", string(alias))

	// Output:
	// original: Hello, world!
	// alias: Hello, world!
	// original: Adios, world!
	// alias: Adios, world!
}

func ExampleReflectAt() {
	var (
		original *C.char  = C.CString("Hello, world!")
		sz       C.size_t = C.strlen(original)
	)
	defer C.free(unsafe.Pointer(original))

	alias := cslice.ReflectAt(reflect.TypeOf(byte(0)), unsafe.Pointer(original), int(sz))

	fmt.Println("original:", C.GoString(original))
	fmt.Println("alias:", string(alias.Bytes()))
	reflect.Copy(alias, reflect.ValueOf([]byte("Adios")))
	fmt.Println("original:", C.GoString(original))
	fmt.Println("alias:", string(alias.Bytes()))

	// Output:
	// original: Hello, world!
	// alias: Hello, world!
	// original: Adios, world!
	// alias: Adios, world!
}
@bcmills
Copy link
Contributor Author

bcmills commented May 16, 2017

(CC: @alandonovan @ianlancetaylor)

@bradfitz bradfitz added this to the Go1.10 milestone May 16, 2017
@rsc rsc modified the milestones: Go1.10, Go1.11 Nov 22, 2017
@ianlancetaylor
Copy link
Contributor

The error use of cgo in test ... not supported is not coming from go tool doc, it's coming from the go/build package.

@ianlancetaylor ianlancetaylor changed the title cmd/doc: no documentation at all for packages with cgo examples go/build: does not support examples that use cgo Jun 14, 2018
@ianlancetaylor ianlancetaylor added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jun 14, 2018
@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Unplanned Jun 14, 2018
@dpifke
Copy link
Contributor

dpifke commented Aug 30, 2018

I did some preliminary investigation on this since I was curious. The commit that introduced the error message is from 2011, here:

https://go.googlesource.com/go/+/66bedf82210220e45ca2eb4919fe764e6a022630%5E%21/#F2

(the check now lives in src/go/build/build.go)

I tried removing the check. Go builds and all of the tests pass. Building an example with CGo still fails, however, due to being unable to import anything from the stdlib:

./cgo_test.go:10:2: can't find import: "fmt"

So it appears that there's more to this issue than just removing the check. Something about CGo confuses the importer when building tests.

@dpifke
Copy link
Contributor

dpifke commented Aug 30, 2018

So the root problem, which is implied by the build.Package documentation, seems to be that a file is expected to appear in exactly one of GoFiles, CgoFiles, TestGoFiles, XTestGoFiles, or IgnoredGoFiles.

Adding support for Cgo in tests appears to involve adding TestCgoFiles and XTestCgoFiles to build.Package, and then teaching src/cmd/go/internal/load/test.go about these fields. I'm going to take a stab at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants