-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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: support msvc object files #20982
Comments
/cc @alexbrainman |
@xoviat what is the problem that you are having? I need to be able to reproduce it here. So, please, provide all steps I will need to follow to reproduce this. Thank you Alex PS: I won't have computer until end of July. I will have a look at this then. |
what is the problem that you are having? I haven't tried it yet, but I would like to specifically call c functions in msvc object files by linking them as .syso with the go linker. Everything that I have read indicates that this is not possible but I will create a procedure to reproduce the specific error that occurs. |
Have you tried building these into a DLL, and use them from inside of DLL?
Please, do. Thank you. Alex |
That was actually my original plan. I am using swig so it is not so convenient to compile the generated c code separately and then rewrite the functions as DLL exports. It's not difficult, but it is annoying when the workflow with gcc is just |
Alright, I have a procedure. Start with these files: hello.go: package main
/*
extern void hello();
*/
import "C"
func main() {
C.hello()
} hello.c: #include <stdio.h>
extern void hello()
{
printf("Hello World from C");
} then run these commands (with msvc on path):
Result: When running the produced file:
|
I do not have cl command installed on my pc. How do I install msvc? Thank you. Alex |
You need the "build tools 2017" here. Microsoft actually now allows anyone to use visual studio for free as long as it's not for commercial development. If it's too much trouble, I can just give you the object file if you want. |
If only c++ was not a thing, I wouldn't have to worry about this. But it is, so the pain continues... |
Got it. Thank you.
Yes, please, post hello.obj somewhere. Thinking about this some more. You are actually using gcc to link object file compiled with msvc compiler. Can you try and do your exercise, but replacing "go build" step with gcc linking hello.obj to a C program? Perhaps it has been done before. I suspect, if we know how to do that, we might be able to do similar with Go. Alex |
AFAIK lld https://github.com/llvm-mirror/lld supports msvc object files. Object file is here: https://github.com/xoviat/msvcgo/blob/master/hello.syso |
Go uses gcc linker (not lld) on Windows.
I will try it when I get home in August. thank you. Alex |
I know. But lld is the best open source documentation of msvc object format. |
I actually get same error from ld so the error is definitely coming from ld. |
Yes. We need to work out how to build C program by compiling part with msvc, and linking with gcc. Alex |
Forgive my ignorance, but what exactly gcc linking? Is it linking output of the go linker? |
Running objconv on the object files to convert to elf:
We now have these errors:
|
Possibly stdio is off limits? |
You use 2 programs to build your Go program:
Sometimes (when one of your packages uses Cgo), the Go linker calls external linker to find all bits that are implemented in C. Imagine you call printf from your C code. The C printf compiled code needs to be part of Go executable, but Go linker does not know where to get it. So Go linker calls external linker to include that code. Current Go uses gcc compiler/linker to compile and link C code (we use mingw gcc). If you are going to compile your C code with different compiler (by Microsoft), you would have to use correspondent linker (by Microsoft) to find all external C code that the compiler created. So, I guess, I was wrong about suggesting to use gcc linker. For general scenario, you would have to use both Microsoft compiler and linker. We would have to figure out what Microsoft linker requires as input and match that. You might get away without MC linker, if your C code does not have any external code. Please try some really simple C program (like the one that adds 2 integers or something). That might just work as you have described above. Alex |
I suspect you need to call Microsoft linker to find that code. Alex |
I don't make sure but
Maybe, you should try to do coff or omf instead of elf? |
@xoviat yes, you should not convert .obj files to elf, Windows version of gcc generates pe/coff files just like any other Windows compiler. Alex |
What is the specific command used? If I know the mingw command, then perhaps I can proceed down a file comparison path to try to get msvc to match what mingw is putting out. |
You can see the exact comment by running |
Okay, so from what I can tell:
Go appears to create a temporary directory with these files. Is there any way to preserve the temporary directory so that I can inspect its contents? |
Try
Object files are remaining in this directory. |
From memory, /EP /d1PP should emit something similar to -E -dM. |
If so that'd be excellent, I assume /d1PP is an undocumented flag? I've never seen it before. That would just leave getting equivalent type information out ahead of time. |
@cchamplin yeah, it’s undocumented. A lot of the /dXXX flags are, apparently. Using undocumented flags is unfortunate, but (IMO) it doesn’t seem to be that bad of a sin on Windows, at least. I saw MSVC STL devs talking about it on a reddit thread, but it’s also all over the Internet, too. |
Can someone give me a short summary of the current state of the MSVC-support? I do not understand very much of all this low-level-compiler-stuff. It's just that I have a go library I want to use from C#/UWP - and that is already working with go build and the buildmode c-shared. BUT: that app won't ever get accepted by the Windows Store as the generated DLL from go misses some compiler/linker-flags that (I assume) can only be set by the MSVC-toolchain. So: how could I test this here? Any advice is appreciated! Thank you! |
@TopperDEL does Windows Store tell you which compiler flags are missing? If mingw-64 support them you can always use |
@qmuntal Yes, they do: I already tried But that did not change anything regarding the store-submittion. And from my understanding at least SAFESEH is a MSVC-specific-thing, right? |
I don't know any easy way to enable SAFESEH nor APPCONTAINER flags in Mingw-w64, maybe this project https://github.com/status-im/mingw-windows10-uwp can give you some guidance. On the other hand DYNAMICBASE and NXCOMPAT will be enabled by default in go 1.16 (see #41421) but can already be used with |
@qmuntal Thanks! So at least my extldflags above should be right? |
Can some example be provided to demonstrate how to use MSVC linker for cgo , so that msvc dll/libs can be loaded into golang exe |
I understand that the go linker cannot currently link msvc object files and also recognize that this issue is likely to be a low priority. However, it would be nice to support this because it would somewhat simplify windows workflow. This issue is mainly to understand how much effort this would be and/or what would be required.
The text was updated successfully, but these errors were encountered: