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/link: Windows errors with internal linking with C objects #23268

Closed
tahirhassan10p opened this issue Dec 28, 2017 · 12 comments
Closed

cmd/link: Windows errors with internal linking with C objects #23268

tahirhassan10p opened this issue Dec 28, 2017 · 12 comments
Labels
FrozenDueToAge OS-Windows WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@tahirhassan10p
Copy link

tahirhassan10p commented Dec 28, 2017

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

go version go1.9.2 windows/amd64

Does this issue reproduce with the latest release?

Yes

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

GOARCH=amd64
GOBIN=
GOEXE=.exe
GOHOSTARCH=amd64
GOHOSTOS=windows
GOOS=windows
GOPATH=C:\gopath
GORACE=
GOROOT=C:\go
GOTOOLDIR=C:\go\pkg\tool\windows_amd64
GCCGO=gccgo
CC=C:/scripts/fips.bat
GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\ContainerAdministrator\AppData\Local\Temp\go-build167486487=/tmp/go-build -gno-record-gcc-switches
CXX=g++
CGO_ENABLED=1
CGO_CFLAGS=-g -O2
CGO_CPPFLAGS=
CGO_CXXFLAGS=-g -O2
CGO_FFLAGS=-g -O2
CGO_LDFLAGS=-g -O2
PKG_CONFIG=pkg-config

What did you do?

I want to run golang code which is importing C archive code with -ldflags "-linkmode=internal" flag.

addition.c
int addition(int a,int b) { int result; result = a + b; return result; }

multiplication.c
int multiplication(int a, int b) { int result; result = a * b; return result; }

header.h
#include <stdio.h> int addition(int a,int b); int multiplication(int a,int b);

program.go
`package main
/*
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#cgo CFLAGS: -I./
#cgo LDFLAGS: ./libarith.a

void myprint() {
int result;
result = addition(1,2);
printf("addition result is : %d\n",result);
result = multiplication(3,2);
printf("multiplication result is : %d\n",result);
}
*/
import "C"

import "fmt"

func main() {
fmt.Println("Hello world from archive")
C.myprint()
}`

Codebase is also available on (https://github.com/tahirhassan10p/GoLangInternalFlag.git).

Steps to reproduce

  • Step 1: gcc -c addition.c
  • Step 2: gcc -c multiplication.c
  • Step 3: ar cr libarith.a addition.o multiplication.o
  • Step 4: go run -ldflags "-linkmode=internal" tahir.go

What did you expect to see?

Hello world from archive
addition result is : 3
multiplication result is : 6

What did you see instead?

C:\go\pkg\tool\windows_amd64\link.exe: cannot open file "-m64 --print-libgcc-file-name"
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/6.2.0/libgcc.a: open "-m64 --print-libgcc-file-name"
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/6.2.0/libgcc.a: The filename, directory name, or volume label syntax is incorrect.

@odeke-em odeke-em changed the title cgo: Getting compile time error when passing -ldflags "-linkmode=internal" with C archive file cmd/cgo: compile time error when passing -ldflags "-linkmode=internal" with C archive file Dec 28, 2017
@odeke-em
Copy link
Member

/cc @ianlancetaylor @alexbrainman

@hirochachacha
Copy link
Contributor

Does external linking mode work for you?
Why do you need to use internal linking mode in the first place?

@ianlancetaylor
Copy link
Contributor

That error doesn't make any sense. Can anybody recreate it? I haven't been able to, but I'm not using WIndows.

We don't promise that internal linking mode works for anything other than Go code. It's nice when it works with arbitrary C code, but there are no guarantees. Still, I don't see why or how it would fail in this way.

@hirochachacha
Copy link
Contributor

On tip and go1.8, I can see

$ go run -ldflags "-linkmode=internal" program.go
# command-line-arguments
main(.text): relocation target addition not defined
main(.text): relocation target multiplication not defined
main(.text): undefined: "addition"
main(.text): undefined: "multiplication"
$ go run program.go
Hello world from archive
addition result is : 3
multiplication result is :  6

@hirochachacha
Copy link
Contributor

Okay, go version go1.9.2 windows/amd64 also have the same result for me.

@tahirhassan10p
Copy link
Author

@hirochachacha

  1. Does external linking mode work for you?
    yes its working with external flag
  2. Why do you need to use internal linking mode in the first place?
    actually we are working on existing application and added a dependency which is C archive file, now we are facing an error with internal flag.

Note: we are using msys2

I have also modify the git repository (https://github.com/tahirhassan10p/GoLangInternalFlag.git) and added a dockerfile.win file to make it easy to replicate the error.

@ianlancetaylor
Copy link
Contributor

Why do you want to use internal linking mode?

@ianlancetaylor ianlancetaylor changed the title cmd/cgo: compile time error when passing -ldflags "-linkmode=internal" with C archive file cmd/link: errors with internal linking mode on Windows Dec 29, 2017
@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 29, 2017
@ianlancetaylor ianlancetaylor changed the title cmd/link: errors with internal linking mode on Windows cmd/link: Windows errors with internal linking with C objects Dec 29, 2017
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Dec 29, 2017
@alexbrainman
Copy link
Member

I can confirm this works with external linker, but does not work with internal linker. I think the problem is the ldflag #cgo LDFLAGS: ./libarith.a line that is used here. If I add -v linker flag, I can see "libarith.a" passed to external linker as a parameter. The LDFLAGS is stored in "ldflag" variable in cmd/link/internal/ld, but it is only used to pass data to external linker. I think we want it passed to internal linker too.

I will try and fix this when I have some time. I have very little free time now days, so hopefully someone will beat me to it.

Alex

@hirochachacha
Copy link
Contributor

If #cgo LDFLAGS: ./libarith.a is valid, #cgo LDFLAGS: -L./ -larith also be valid.
That means we need to implement library search algorithm ourselves (on top of gcc -print-search-dirs?). It could be, but is it good enough? Someone might want to use -static, other one want to use -Wl, ... etc. I cannot understand the goal.

@ianlancetaylor
Copy link
Contributor

Good point about LDFLAGS. Right now LDFLAGS is clearly for the external linker. Since the external linker and the internal linker do not take the same flags, LDFLAGS can not be for both. We shouldn't try to make it work; although we could in principle support -L, we can not support all the options that can appear there.

@tahirhassan10p Unless there is a good reason that we need to support internal linking here, I'm inclined to close this issue.

@ianlancetaylor ianlancetaylor added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Dec 30, 2017
@alexbrainman
Copy link
Member

@hirochachacha and @ianlancetaylor you are correct about LDFLAGS containing all external linker flags, not just the library list. I was too quick to post my incorrect answer, and did not think properly.

I agree, it would be too hard to parse LDFLAGS value to find libraries in there. Perhaps we could introduce new cgo variable specifically for that. Something like:

#cgo LDLIB: ./libarith.a

But maybe I am overthinking this too much. Perhaps we could just document that this is not supported with internal linker.

Leaving it for @ianlancetaylor to decide what to do here.

Alex

@gopherbot
Copy link

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@golang golang locked and limited conversation to collaborators Jan 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge OS-Windows WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

6 participants