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/cgo: support clang on Windows #17014

Open
nadiasvertex opened this Issue Sep 7, 2016 · 21 comments

Comments

Projects
None yet
@nadiasvertex
Contributor

nadiasvertex commented Sep 7, 2016

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

go version devel +0cff219 Wed Sep 7 10:43:13 2016 +0000 windows/amd64

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

Windows 10 / AMD64

What did you do?

I used CGO with Clang for Windows 3.8.1 (http://llvm.org/releases/3.8.1/LLVM-3.8.1-win64.exe) like this:

set CC=clang
set CGO_CFLAGS="-m64 -Ipath/to/my/includes"
set CGO_LDFLAGS = "-v -Xlinker -libpath:path/to/libs -lwldap32 -ladvapi32 -lws2_32 -ldbghelp -luser32"

go build

What did you expect to see?

Expected to see nothing (ie, successful compile)

What did you see instead?

# editor/dom
clang version 3.8.1 (branches/release_38)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
 "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "-out:C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\_cgo_.o" -defaultlib:libcmt "-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10240.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x64" -nologo "C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\_cgo_main.o" "C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\_cgo_export.o" "C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\binding.cgo2.o" "-libpath:c:\\temp\\go\\src\\editor\\.mm\\windows\\amd64\\release\\lib" core-static.lib ssl-static.lib crypto-static.lib ssh2-static.lib c-ares-static.lib user32.lib ws2_32.lib wldap32.lib advapi32.lib dbghelp.lib
   Creating library $WORK\editor\dom\_obj\_cgo_.lib and object $WORK\editor\dom\_obj\_cgo_.exp
core-static.lib(node.obj) : warning LNK4049: locally defined symbol xmlFree imported
core-static.lib(xml.obj) : warning LNK4049: locally defined symbol xmlFree imported
# editor/dom
clang version 3.8.1 (branches/release_38)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
 "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "-out:C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\_all.o" "-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10240.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x64" -nologo "C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\_cgo_export.o" "C:\\Users\\CHRIST~1\\AppData\\Local\\Temp\\go-build406860094\\editor\\dom\\_obj\\binding.cgo2.o" -Wl,-r
LINK : warning LNK4044: unrecognized option '/Wl,-r'; ignored
LINK : fatal error LNK1561: entry point must be defined
clang.exe: error: linker command failed with exit code 1561 (use -v to see invocation)

@bradfitz bradfitz added the OS-Windows label Sep 7, 2016

@bradfitz

This comment has been minimized.

Member

bradfitz commented Sep 7, 2016

I don't believe clang is supported yet. Our installation docs only mention mingw.

That said, we should probably support clang on Windows at some point.

/cc @ianlancetaylor @alexbrainman @crawshaw

@quentinmit quentinmit added this to the Go1.8Maybe milestone Sep 7, 2016

@alexbrainman

This comment has been minimized.

Member

alexbrainman commented Sep 8, 2016

I have nothing against clang support. I have never had it installed on my computer. I will try install clang when I have some time.

Alex

@quentinmit quentinmit added the NeedsFix label Oct 10, 2016

@therecipe therecipe referenced this issue Oct 11, 2016

Closed

Web Engine #53

@rsc rsc modified the milestones: Go1.9, Go1.8Maybe Oct 20, 2016

@rsc rsc changed the title from build: cgo does not supply an entry point correctly when compiling with clang for windows to cmd/cgo: support clang on Windows Oct 20, 2016

@DmitriyMV

This comment has been minimized.

DmitriyMV commented Nov 3, 2016

I did some digging around and found out that with -Xlinker /subsystem:console it actually gets past entry point must be defined. But now I'm getting this error:

# runtime/cgo
clang version 3.9.0 (branches/release_39)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dmitry\LLVM_\bin
 "C:\\Program Files (x86)\\Microsoft Visual Studio\\VS15Preview\\Common7\\IDE\\VC\\bin\\amd64\\link.exe" "-out:C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\_cgo_.o" -defaultlib:libcmt -nologo "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\_cgo_main.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\_cgo_export.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\cgo.cgo2.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_context.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_libinit_windows.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_util.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_windows_amd64.o" "
subsystem:console wldap32.lib advapi32.lib ws2_32.lib dbghelp.lib user32.lib kernel32.lib winmm.lib ntdll.lib
cmd/go
# runtime/cgo
clang version 3.9.0 (branches/release_39)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dmitry\LLVM_\bin
 "C:\\Program Files (x86)\\Microsoft Visual Studio\\VS15Preview\\Common7\\IDE\\VC\\bin\\amd64\\link.exe" "-out:C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\_all.o" -nologo "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\_cgo_export.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\cgo.cgo2.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_context.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_libinit_windows.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_util.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_windows_amd64.o" "C:\\Users\\Dmitry\\AppData\\Local\\Temp\\go-build586540150\\runtime\\cgo\\_obj\\gcc_amd64.o" /subsystem:console -r
LINK : warning LNK4044: unrecognized option '/r'; ignored
gcc_context.o : error LNK2019: unresolved external symbol __stdio_common_vsprintf referenced in function _vsnprintf_l
gcc_libinit_windows.o : error LNK2001: unresolved external symbol __stdio_common_vsprintf
gcc_util.o : error LNK2001: unresolved external symbol __stdio_common_vsprintf
gcc_windows_amd64.o : error LNK2001: unresolved external symbol __stdio_common_vsprintf
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_CreateEventA referenced in function _cgo_preinit_init
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __acrt_iob_func referenced in function _cgo_preinit_init
gcc_util.o : error LNK2001: unresolved external symbol __acrt_iob_func
gcc_windows_amd64.o : error LNK2001: unresolved external symbol __acrt_iob_func
gcc_libinit_windows.o : error LNK2019: unresolved external symbol abort referenced in function _cgo_preinit_init
gcc_util.o : error LNK2001: unresolved external symbol abort
gcc_windows_amd64.o : error LNK2001: unresolved external symbol abort
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_InitializeCriticalSection referenced in function _cgo_preinit_init
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_Sleep referenced in function _cgo_maybe_run_preinit
gcc_libinit_windows.o : error LNK2019: unresolved external symbol _beginthread referenced in function x_cgo_sys_thread_create
gcc_windows_amd64.o : error LNK2001: unresolved external symbol _beginthread
gcc_libinit_windows.o : error LNK2019: unresolved external symbol _errno referenced in function x_cgo_sys_thread_create
gcc_windows_amd64.o : error LNK2001: unresolved external symbol _errno
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_EnterCriticalSection referenced in function _cgo_is_runtime_initialized
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_LeaveCriticalSection referenced in function _cgo_is_runtime_initialized
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_WaitForSingleObject referenced in function _cgo_wait_runtime_init_done
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __imp_SetEvent referenced in function x_cgo_notify_runtime_init_done
gcc_libinit_windows.o : error LNK2019: unresolved external symbol __stdio_common_vfprintf referenced in function _vfprintf_l
gcc_util.o : error LNK2001: unresolved external symbol __stdio_common_vfprintf
gcc_windows_amd64.o : error LNK2001: unresolved external symbol __stdio_common_vfprintf
gcc_util.o : error LNK2019: unresolved external symbol malloc referenced in function x_cgo_thread_start
gcc_windows_amd64.o : error LNK2019: unresolved external symbol free referenced in function threadentry
LINK : error LNK2001: unresolved external symbol mainCRTStartup
C:\Users\Dmitry\AppData\Local\Temp\go-build586540150\runtime\cgo\_obj\_all.o : fatal error LNK1120: 16 unresolved externals
clang.exe: error: linker command failed with exit code 1120 (use -v to see invocation)

With:
set CGO_LDFLAGS=-v -Xlinker /subsystem:console -lwldap32 -ladvapi32 -lws2_32 -ldbghelp -luser32 -lkernel32 -lwinmm -lntdll

I guess, it cannot find the C libs, but then when I tried to add -libpath:"C:\Program Files (x86)\Microsoft Visual Studio\VS15Preview\Common7\IDE\VC\lib\" I'm sure I did something wrong because it started to produce this:

# runtime/cgo
clang version 3.9.0 (branches/release_39)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dmitry\LLVM_\bin
clang.exe: error: no such file or directory: 'Files'
clang.exe: error: no such file or directory: '(x86)/Microsoft'
clang.exe: error: no such file or directory: 'Visual'
clang.exe: error: no such file or directory: 'Studio/VS15Preview/Common7/IDE/VC/lib"'

@nadiasvertex I would really appreciate an advice on proper libpath setting.

@mattn

This comment has been minimized.

Member

mattn commented Nov 3, 2016

Maybe it's related on #16455 ?

@DmitriyMV

This comment has been minimized.

DmitriyMV commented Nov 3, 2016

Yes - I created symlink because of that. It solved the second part of the problem, but the first(and main) remains.

@nadiasvertex

This comment has been minimized.

Contributor

nadiasvertex commented Nov 7, 2016

@DmitriyMV I don't have much to tell you. The fundamental problem is that clang for Windows uses Microsoft's LIB as its backend. You do not need to tell LIB where to find the C library, it already knows that. I believe that the problem is that Go does not currently pass paths to clang in a way that LIB knows how to consume. I have not had success getting clang to compile with Go by playing with the commands. I think that the Go backend needs to be modified to send different values in order to make this work.

Sorry. I haven't had much time to work on this, but it is something that I would like to get working, or see someone else get working. :-)

@minux

This comment has been minimized.

Member

minux commented Nov 8, 2016

@nadiasvertex

This comment has been minimized.

Contributor

nadiasvertex commented Nov 8, 2016

I prefer Clang's emulation. It makes the compiler part simpler since MSVC
is notoriously slow to get up to date with the standard, among other
frustrations. It would be really nice to be able to create MSVC-compatible
binaries without having to use MSVC. Not that I'm against also supporting
MSVC. We support a lot of C++ code that must compile under MSVC for now,
but we are very interested in dropping MSVC as soon as it is feasible.

On Tue, Nov 8, 2016, 2:48 AM Minux Ma notifications@github.com wrote:

I think core issue is that the target for clang is: x86_64-pc-windows-msvc
i.e. it's meant to be MSVC compatible.

However, Go on windows rely on mingw for cgo.

If we want to do anything here, it's probably to support msvc directly,
rather than clang's emulation of it.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#17014 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AB8JvBeiKJxeAx5mwRnS6oOx7G8k00lBks5q8Ck1gaJpZM4J2_91
.

@sbhushan87

This comment has been minimized.

sbhushan87 commented Jan 12, 2017

will this feature be available in GO1.8 release as I saw this issue has been linked to GO1.8Maybe issue list?

Any update will be helpful. thanks.

@minux

This comment has been minimized.

Member

minux commented Jan 12, 2017

@bradfitz bradfitz added the help wanted label Jun 7, 2017

@bradfitz bradfitz modified the milestones: Go1.10, Go1.9 Jun 7, 2017

@blizzardplus

This comment has been minimized.

blizzardplus commented Aug 30, 2017

I'd like to get an update on this? I might be able to push this forward, if there's interest.

@alexbrainman

This comment has been minimized.

Member

alexbrainman commented Aug 30, 2017

I'd like to get an update on this?

Nothing new to report here.

I might be able to push this forward, if there's interest.

Go ahead if you know what to do. Everyone will help, if we can.
Maybe related #20982.

Alex

@as

This comment has been minimized.

Contributor

as commented Aug 30, 2017

I guess, it cannot find the C libs, but then when I tried to add -libpath:"C:\Program Files (x86)\Microsoft Visual Studio\VS15Preview\Common7\IDE\VC\lib" I'm sure I did something wrong because it started to produce this:

# runtime/cgo
clang version 3.9.0 (branches/release_39)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dmitry\LLVM_\bin
clang.exe: error: no such file or directory: 'Files'
clang.exe: error: no such file or directory: '(x86)/Microsoft'
clang.exe: error: no such file or directory: 'Visual'
clang.exe: error: no such file or directory: 'Studio/VS15Preview/Common7/IDE/VC/lib"'

@DmitriyMV
It's splitting the path due to spaces, maybe try setting -libpath to a legacy 8.3 path to the same directory

-libpath C:\progra~2\microsoft\visual~1\VS15Preview\Common7\IDE\VC\lib

@blizzardplus

This comment has been minimized.

blizzardplus commented Sep 5, 2017

I found a bunch of issues. If you could tell me where in the code these things are processed, I might be able to fix them, unless someone else wants to take care of them:

  1. The Lib path in LDFLAGS should be passed as -L"path/to/libs"
  2. If there is space in the lib path, it does not compile for me. I don't know how spaces are handled by cgo, but when I copied my lib folder to "C:", it had no issue finding it.
  3. For some reason, the clang linker command is missing the _cgo_main.o object when linking objects.
  4. For me, the linker command is called with "-nostdlib" option and it causes this error: "LINK : error LNK2001: unresolved external symbol mainCRTStartup"

Note: I used the go build -x -work command to see the clang commands and keep the temp working directory.

@alexbrainman

This comment has been minimized.

Member

alexbrainman commented Sep 5, 2017

The Lib path in LDFLAGS should be passed as -L"path/to/libs"

OK. What is your question?

If there is space in the lib path, it does not compile for me. I don't know how spaces are handled by cgo, but when I copied my lib folder to "C:", it had no issue finding it.

I would copy all code into directories without spaces at the start. Once that works, we can deal with paths with spaces.

For some reason, the clang linker command is missing the _cgo_main.o object when linking objects.

According to $GOROOT/src/cmd/cgo/doc.go file:

the build process generates an object file using dynamic
linkage to the desired libraries. The main function is provided by
_cgo_main.c:
	int main() { return 0; }
	void crosscall2(void(*fn)(void*, int, uintptr_t), void *a, int c, uintptr_t ctxt) { }
	uintptr_t _cgo_wait_runtime_init_done() { return 0; }
	void _cgo_release_context(uintptr_t ctxt) { }
	char* _cgo_topofstack(void) { return (char*)0; }
	void _cgo_allocate(void *a, int c) { }
	void _cgo_panic(void *a, int c) { }
	void _cgo_reginit(void) { }
The extra functions here are stubs to satisfy the references in the C
code generated for gcc. The build process links this stub, along with
_cgo_export.c and *.cgo2.c, into a dynamic executable and then lets
cgo examine the executable. 

So it seems to me Go creates _cgo_main.c file and then uses gcc to compile it into _cgo_main.o. Does _cgo_main.c gets created? It should be compiled into _cgo_main.o by invoking gcc, but you do not have gcc. Do you use clang to compile _cgo_main.c? Does compilation succeeds or fails?

For me, the linker command is called with "-nostdlib" option and it causes this error: "LINK : error LNK2001: unresolved external symbol mainCRTStartup"

Searching for "-nostdlib", I find many instances in $GOROOT/src/cmd/go/internal/work/build.go. If clang does not accepts "-nostdlib", maybe try and adjust there?

Note: I used the go build -x -work command to see the clang commands and keep the temp working directory.

The "go build -x -work" only controls go command itself. You, probably, want to do the same for the cmd/link as well. See #20982 (comment) for how to access cmd/link temp files. You might also find -v cmd/link flag useful (or "-v -v").

I hope it helps.

Alex

@ghost

This comment has been minimized.

ghost commented Sep 6, 2017

The main issue that I received when using the MSVC linker is a segmentation fault that occurred while attempting to bind stdout. I can help to resolve the unresolved symbols but the segmentation fault issue is a bit trickier. My plan for that is to basically manually link everything with MinGW and then use DLL linking to factor out each object at a time until I receive the segmentation fault. I think then I will need to compare assembly to see what the problem is, although maybe there is someone more talented than I am that has a better idea? I am probably stretching the limits of my capability so I am open to as much help as I can get.

@alexbrainman

This comment has been minimized.

Member

alexbrainman commented Sep 6, 2017

The main issue that I received when using the MSVC linker is a segmentation fault that occurred while attempting to bind stdout.

@xoviat are you taking about issue #20982? Did you manage to build executable successfully? But the executable crashes when it runs? Perhaps if you can provide the steps, I will try and debug it too.

Maybe reply on #20982 so we don't confuse things.

Thank you.

Alex

@blizzardplus

This comment has been minimized.

blizzardplus commented Sep 6, 2017

Searching for "-nostdlib", I find many instances in $GOROOT/src/cmd/go/internal/work/build.go. If clang does not accepts "-nostdlib", maybe try and adjust there?

I tried to remove the -nostdlib option from the source file and build Go from source, but having some linking issues when building the source code, so stuck there! The problem is that the build.go seems to be appending the option at the end of LDFLAGS, so no matter what LDFLAG options user provides, -nostdlib will be appended. I'm wondering if there is a way to completely override the flags?

Note: I used the go build -x -work command to see the clang commands and keep the temp working directory.
The "go build -x -work" only controls go command itself. You, probably, want to do the same for the cmd/link as well. See #20982 (comment) for how to access cmd/link temp files. You might also find -v cmd/link flag useful (or "-v -v").

I can link the files, by manually adding missing object files and modifying linker options, but don't know the next step the build process takes, so I can't move further.

@ghost

This comment has been minimized.

ghost commented Sep 6, 2017

@blizzardplus Do you have libgo?

image

@alexbrainman

This comment has been minimized.

Member

alexbrainman commented Sep 6, 2017

I tried to remove the -nostdlib option from the source file and build Go from source, but having some linking issues when building the source code, so stuck there!

-nostdlib is a gcc flag. If you don't use gcc (that is what you are trying to do in this issue), then removing -nostdlib flag should not matter to you.

Can you see what gcc command go.exe runs to compile and link C code? Do you know what clang commands are needed to replace those? Can you try and adjust go.exe accordingly and see what happens?

I can link the files, by manually adding missing object files and modifying linker options, but don't know the next step the build process takes, so I can't move further.

You say you know about "go build -x -work" trick. That should tell you about what cgo.exe and compile.exe. do You also want to see how link.exe calls gcc linker - for that you should use "go build" -ldflags flag #20982 (comment) -ldflags also takes -v parameter which will print link.exe action list.

Alex

@ghost

This comment has been minimized.

ghost commented Sep 6, 2017

Alex, I replied on the other issue as requested.

@blizzardplus The build process links the following:

cl libgo.lib go.o hello.cgo2.o hello.c Ws2_32.lib Winmm.lib -link
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment