go 在Windows上,如果没有指定输出文件,使用`-buildmode=c-shared`命令会失败,不会添加`.dll`扩展名;在Linux上,如果没有指定输出文件,使用`-buildmode=c-shared`命令会失败,不会添加`.so`扩展名,

cx6n0qe3  于 6个月前  发布在  Go
关注(0)|答案(7)|浏览(45)

你正在使用哪个版本的Go( go version )?

go version go1.14.1 windows/amd64

这个问题在最新版本中是否重现?

是的

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

set GO111MODULE=auto
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\anon\AppData\Local\go-build
set GOENV=C:\Users\anon\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\anon\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\anon\AppData\Local\Temp\go-build481521658=/tmp/go-build -gno-record-gcc-switches

你做了什么?

我尝试构建一个c共享库

package main
import "fmt"
import "C"

//export test
func test() {
	fmt.Println("Hello World!")
}

func main() {

}

该存档与一个C链接,该C只是调用 test() ,如下所示:

gcc main.c -L<path to dll folder> -l<dll name without extension> -o test.exe

执行 test.exe 不会产生任何输出。

你期望看到什么?

一个有效的dll文件(Windows上的标准动态库格式)

你看到了什么?

调用 go build -buildmode=c-shared 没有产生一个有效的dll(我认为;默认情况下它没有任何扩展名)。它产生了一个没有扩展名的 [folder name] 文件。
我不确定发生了什么,但是如果你尝试将其链接到一个C main,那么 main 函数不会被执行。链接器不会对文件(将[name]重命名为[name].dll)产生任何警告或错误。
如果你用 go build -buildmode=c-shared -o <name>.dll 生成存档,一切都按预期工作,但 go build -buildmode=c-shared 应该足够了,但它并没有。

biswetbf

biswetbf1#

我在Linux上也测试了这个。在Linux上也有相同的行为。该命令生成一个没有扩展名的输出文件。

ut6juiuv

ut6juiuv2#

@Sebi2020 我认为这正如预期的那样工作。
如果你运行
go build -buildmode=c-shared
命令,它会创建一个没有扩展名的输出文件。
如果你想要特定的文件名,只需使用 -o 参数。例如:
go build -buildmode=c-shared -o a.dll

7eumitmz

7eumitmz3#

@alexbrainman,这就是bug报告的重点,因为它应该输出一个带有扩展名的文件。对于共享对象或动态链接库来说,没有扩展名的情况并不常见。在Linux上,它们应该以.so结尾,而在Windows上,它们(默认情况下)应该以.dll结尾。
除此之外,如果你没有使用-o标志指定名称,那么在Windows上编译器将不会创建一个有效的.dll文件(后续链接失败)。

628mspwn

628mspwn4#

@Sebi2020 我并不反对你的论点。但我建议你使用 -o 标志来解决你的问题,而不是让 go 命令为你输出文件选择文件名。
我已经很多年没有使用 -buildmode=c-shared 模式了,而且我可能错了。但是,我怀疑你会发现,无论如何都不能重命名输出文件。所以你的论点是没有意义的。
Alex

3vpjnl9f

3vpjnl9f5#

@alexbrainman 什么意思是你不能重命名输出文件?我认为这是go工具的简单代码行,必须更改以获取文件扩展名。例如,-o可以默认为[packagename].so而不是[packagename]在linux上和[packagename].dll在windows上。

jtw3ybtb

jtw3ybtb6#

你的意思是你不能重命名输出文件?

c:\Users\Alex\dev\src\issue\go\38244>dir
 Volume in drive C has no label.
 Volume Serial Number is 9012-A870

 Directory of c:\Users\Alex\dev\src\issue\go\38244

03/05/2020  06:41 PM    <DIR>          .
03/05/2020  06:41 PM    <DIR>          ..
03/05/2020  06:34 PM               129 main.go
               1 File(s)            129 bytes
               2 Dir(s)  10,984,325,120 bytes free

c:\Users\Alex\dev\src\issue\go\38244>type main.go
package main

import "fmt"
import "C"

//export Test
func Test() {
        fmt.Println("Hello World!")
}

func main() {

}

c:\Users\Alex\dev\src\issue\go\38244>go build -buildmode=c-shared

c:\Users\Alex\dev\src\issue\go\38244>dir
 Volume in drive C has no label.
 Volume Serial Number is 9012-A870

 Directory of c:\Users\Alex\dev\src\issue\go\38244

03/05/2020  06:41 PM    <DIR>          .
03/05/2020  06:41 PM    <DIR>          ..
03/05/2020  06:41 PM         3,651,068 38244
03/05/2020  06:41 PM             1,578 38244.h
03/05/2020  06:34 PM               129 main.go
               3 File(s)      3,652,775 bytes
               2 Dir(s)  10,980,343,808 bytes free

c:\Users\Alex\dev\src\issue\go\38244>copy con main.c
#include "38244.h"
#include <stdio.h>

int main() {
  printf("This is a C Application.\n");
  Test();
  return 0;
}
^Z
        1 file(s) copied.

c:\Users\Alex\dev\src\issue\go\38244>gcc -o a main.c 38244

c:\Users\Alex\dev\src\issue\go\38244>a
This is a C Application.
Hello World!

c:\Users\Alex\dev\src\issue\go\38244>ren 38244 38244.dll

c:\Users\Alex\dev\src\issue\go\38244>gcc -o a main.c 38244.dll

c:\Users\Alex\dev\src\issue\go\38244>a

c:\Users\Alex\dev\src\issue\go\38244>

运行上一条命令会弹出这个框

Alex

ukqbszuj

ukqbszuj7#

是的,这种情况确实发生过。因为我了解到,文件名是在dlls中编码的。你需要使用-o选项。但我的意思是,命令应该默认生成一个带有.dll或.so扩展名的文件。

相关问题