Cgo generated sources fail to compile on MVC
Asked Answered
E

2

2

I have a shared library made with CGo and it links fine on Linux and Android. But when compiling on Windows 10 with Microsoft Visual Studio 2017, I get these errors:

Microsoft (R) Program Maintenance Utility Version 14.16.27024.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_QUICKCONTROLS2_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -I. -Irelease -I..\..\Qt\5.12.0\msvc2017_64\include -I..\..\Qt\5.12.0\msvc2017_64\include\QtQuickControls2 -I..\..\Qt\5.12.0\msvc2017_64\include\QtQuick -I..\..\Qt\5.12.0\msvc2017_64\include\QtGui -I..\..\Qt\5.12.0\msvc2017_64\include\QtANGLE -I..\..\Qt\5.12.0\msvc2017_64\include\QtQml -I..\..\Qt\5.12.0\msvc2017_64\include\QtNetwork -I..\..\Qt\5.12.0\msvc2017_64\include\QtCore -Irelease -I\include -I..\..\Qt\5.12.0\msvc2017_64\mkspecs\win32-msvc -Forelease\ @C:\Users\Nick\AppData\Local\Temp\nm2B40.tmp
connekt.cpp
c2.cpp
cgo-gcc-export-header-prolog(15): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
cgo-gcc-export-header-prolog(15): error C2146: syntax error: missing ';' before identifier 'GoUintptr'
cgo-gcc-export-header-prolog(18): error C2146: syntax error: missing ';' before identifier 'GoComplex64'
cgo-gcc-export-header-prolog(18): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
cgo-gcc-export-header-prolog(19): error C2371: '_Complex': redefinition; different basic types
cgo-gcc-export-header-prolog(18): note: see declaration of '_Complex'
cgo-gcc-export-header-prolog(19): error C2146: syntax error: missing ';' before identifier 'GoComplex128'
cgo-gcc-export-header-prolog(19): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Generating Code...
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.EXE"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x86\nmake.exe"' : return code '0x2'
Stop.

The header (.h) of the library is generated by Cgo, and it contains these lines:

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
//typedef __SIZE_TYPE__ GoUintptr;
typedef size_t GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

For example, one of the errors is reported at this line:

typedef float _Complex GoComplex64;

But float _Complex is an already defined type , why can't it be aliased to GoComplex64?

To fix the GoUintptr I commented the SIZE_TYPE line and replaced it by size_t, but it doesn't compile either:

//typedef __SIZE_TYPE__ GoUintptr;
typedef size_t GoUintptr;

What could be done here to fix these compilation errors? Maybe there are some flags to make Visual C++ not so strict ? (because on other platforms I don't have any problems)

Ensign answered 30/11, 2018 at 20:20 Comment(9)
You can't use Visual C++ with cgo.Italian
_Complex is a C99 language feature, and is invalid in C++. For typedef size_t GoUintptr; you will need to include <stddef.h>Britanybritches
@Italian , I am not, I have a library compiled with CGo, and now I am using it inside Visual C++ projectEnsign
@VTT , but why does this code compile fine on Linux (GCC) and Android ?Ensign
Most likely you are compiling using gcc with non-conforming extensions. It is quite tolerant to mixing C99 stuff into C and / or C++ code.Britanybritches
@Nulik: you said the the library is generated by cgo and you're compiling with Visual C++, which you can't do, because cgo is targeted specifically for C (and really only used with gcc).Italian
@Italian but isn't gcc following standards ? like the ABI and DLL format standards ? If cgo produces a .DLL on windows, which is shared object, this shared object in theory, must be suitable for inclusion by any other compiler, provided that header exists. Actually, I only have problems with some types, in the header.Ensign
I think if you remove _Complex and whatever other C99 stuff is in there it should work fine (unless that stuff is used for exposed functions). Also there is no "ABI and DLL format standards", compilers typically stick with whatever platform-default format is (at least for C).Britanybritches
@Nulik: yes, it follows C standards, but AFAIK (I don't use Windows at all) Visual C++ doesn't fully support C99. There doesn't seem to be anyone offering to do the work in cgo to accommodate MSVC (assuming it's feasible)Italian
S
1

Had the same issue - I ended up commenting out the _Complex types (GoComplex..) as well as the __SIZE_TYPE__ (GoUintPtr) - this way, the .h compiles

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
//typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
//typedef float _Complex GoComplex64;
//typedef double _Complex GoComplex128;

However, I still haven't got it to link using cl:

> cl /EHsc /I ..\libBleveIndexTest main.cpp ..\libBleveIndexTest\libBleveIndexTest.a
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27024.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9024 : unrecognized source file type '..\libBleveIndexTest\libBleveIndexTest.a', object file assumed
main.cpp
Microsoft (R) Incremental Linker Version 14.16.27024.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
main.obj
..\libBleveIndexTest\libBleveIndexTest.a
libBleveIndexTest.a(go.o) : warning LNK4078: multiple '.text' sections found with different attributes (60600060)
libBleveIndexTest.a(000005.o) : warning LNK4217: locally defined symbol _errno imported in function x_cgo_sys_thread_create
libBleveIndexTest.a(000007.o) : warning LNK4049: locally defined symbol _errno imported
libBleveIndexTest.a(000005.o) : error LNK2019: unresolved external symbol __imp___iob_func referenced in function _cgo_preinit_init
libBleveIndexTest.a(000006.o) : error LNK2001: unresolved external symbol __imp___iob_func
libBleveIndexTest.a(000007.o) : error LNK2001: unresolved external symbol __imp___iob_func
libBleveIndexTest.a(000005.o) : error LNK2019: unresolved external symbol __imp__beginthread referenced in function x_cgo_sys_thread_create
libBleveIndexTest.a(000007.o) : error LNK2001: unresolved external symbol __imp__beginthread
main.exe : fatal error LNK1120: 2 unresolved externals

The __imp__iob... I can fix by adding:

extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; }

to the main C source. However, the "__imp__beginthread" I wasn't able to fix.

Shannan answered 22/4, 2019 at 9:26 Comment(1)
because cgo uses gcc, the code it builds depends on some internal functions in the gcc runtime library. Hence the problem using them from msvc, which has its own C library. You need to compile the wrapper functions in gcc as well.Charlatanry
J
0

had same issue.
my old complie way:

cmake ../ && MSBuild xxx.sln

new compile way:

cmake -G "MinGW Makefiles" ../ && mingw32-make

reason is compile go source to c library use MinGW which contains gcc, but compile program use visual studio(my cmake environment default generator, find from "cmake --help")

Jujutsu answered 7/1, 2022 at 3:19 Comment(1)
This answer might be correct, however, do you know why MinGW works and MSVC doesn't, do you have a link to the go code documentation that explains that MSVC is not supported?Dominy

© 2022 - 2024 — McMap. All rights reserved.