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

Comments

Projects
None yet
6 participants
@tahirhassan10p
Copy link

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

This comment has been minimized.

Copy link
Member

commented Dec 28, 2017

@hirochachacha

This comment has been minimized.

Copy link
Contributor

commented Dec 28, 2017

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

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Dec 28, 2017

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

This comment has been minimized.

Copy link
Contributor

commented Dec 28, 2017

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

This comment has been minimized.

Copy link
Contributor

commented Dec 28, 2017

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

@tahirhassan10p

This comment has been minimized.

Copy link
Author

commented Dec 29, 2017

@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

This comment has been minimized.

Copy link
Contributor

commented Dec 29, 2017

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 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

This comment has been minimized.

Copy link
Member

commented Dec 30, 2017

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

This comment has been minimized.

Copy link
Contributor

commented Dec 30, 2017

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

This comment has been minimized.

Copy link
Contributor

commented Dec 30, 2017

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.

@alexbrainman

This comment has been minimized.

Copy link
Member

commented Dec 31, 2017

@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

This comment has been minimized.

Copy link

commented Jan 30, 2018

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.)

@gopherbot gopherbot closed this Jan 30, 2018

@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.
You can’t perform that action at this time.