Skip to content

cmd/go: -buildmode=c-shared without specifying output file fails does not add .dll extension on Windows and .so extension on linux #38244

Open
@Sebi2020

Description

@Sebi2020

What version of Go are you using (go version)?

go version go1.14.1 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
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

What did you do?

I tried to build a c-shared library

package main
import "fmt"
import "C"

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

func main() {

}

The archive is linked against a C which just calls test() with:

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

Executing test.exe does not produce any output.

What did you expect to see?

A valid dll file (standard dynamic library format on windows)

What did you see instead?

The call go build -buildmode=c-shareddoes not yield a valid dll (I think; it does not have any extension by default). It produces a [folder name] file without any extension.

I'm not sure what happens, but if you try to link it against a C mainthe main function does not get executed. The linker does not produce any warnings or errors about the file (after renaming [name] to [name].dll).

If you produce the archive with go build -buildmode=c-shared -o <name>.dll everything works as expected, but go build -buildmode=c-shared should be sufficient, but it isn't.

Activity

changed the title [-]Building c-shared and c-archive on windows fails[/-] [+]Building c-shared without specifying output file fails[/+] on Apr 4, 2020
changed the title [-]Building c-shared without specifying output file fails[/-] [+]cmd/go: -buildmode=c-shared without specifying output file fails does not add .dll extension on Windows[/+] on Apr 4, 2020
added this to the Backlog milestone on Apr 4, 2020
Sebi2020

Sebi2020 commented on Apr 11, 2020

@Sebi2020
Author

I tested this on linux too. The same behaviour applys to linux. The command generates a extension-less output file.

changed the title [-]cmd/go: -buildmode=c-shared without specifying output file fails does not add .dll extension on Windows[/-] [+]cmd/go: -buildmode=c-shared without specifying output file fails does not add .dll extension on Windows and .so extension on linux[/+] on Apr 11, 2020
alexbrainman

alexbrainman commented on Apr 16, 2020

@alexbrainman
Member

@Sebi2020 I think this is working as expected.

If you running

go build -buildmode=c-shared

command, it creates output file without extension.

If you want some particular file name, just use -o parameter. Like so

go build -buildmode=c-shared -o a.dll

Alex

Sebi2020

Sebi2020 commented on Apr 16, 2020

@Sebi2020
Author

@alexbrainman that was the point of the bug report, because it should output a file with an extension. It's not common for shared objects or dynamic linked libraries to have no extension. On linux the should end with .so and on windows they should (per default) end with .dll.

Apart from this, if you don't specify the name with the -o flag, the compiler does not create a valid .dll on windows (Later linkage fails).

alexbrainman

alexbrainman commented on Apr 19, 2020

@alexbrainman
Member

@Sebi2020 I don't disagree with your arguments. But I suggest you use -o flag to solve your problem, instead of letting go command pick file name for your output file.

I haven't used -buildmode=c-shared mode for many years, and I could be wrong. But, I suspect, you will discover, that you cannot rename output files anyway. So you argument is pointless.

Alex

Sebi2020

Sebi2020 commented on Apr 20, 2020

@Sebi2020
Author

@alexbrainman What do you mean with you cannot rename output files? I think it's a simple code line of the go tool, which must be changed to get file extensions. -o for example could default to [packagename].so instead of [packagename]. on linux and [packagename].dll on windows.

alexbrainman

alexbrainman commented on May 3, 2020

@alexbrainman
Member

What do you mean with you cannot rename output files?

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>

Running last command brings this box

image

Alex

Sebi2020

Sebi2020 commented on May 12, 2020

@Sebi2020
Author

Yes this occures,because as far as I know the file name is encoded in dlls. You have to use the -o option. But I mean, the command should generate the file with a .dll or .so extension by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoCommandcmd/goNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Windowshelp wanted

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Sebi2020@ianlancetaylor@bcmills@alexbrainman

        Issue actions

          cmd/go: -buildmode=c-shared without specifying output file fails does not add .dll extension on Windows and .so extension on linux · Issue #38244 · golang/go