Go: cmd/link: unterstützt msvc-Objektdateien

Erstellt am 11. Juli 2017  ·  222Kommentare  ·  Quelle: golang/go

Ich verstehe, dass der Go-Linker derzeit keine msvc-Objektdateien verknüpfen kann, und erkenne auch an, dass dieses Problem wahrscheinlich eine niedrige Priorität hat. Es wäre jedoch schön, dies zu unterstützen, da dies den Windows-Workflow etwas vereinfachen würde. Dieses Problem besteht hauptsächlich darin, zu verstehen, wie viel Aufwand dies wäre und/oder was erforderlich wäre.

Builders FeatureRequest NeedsInvestigation OS-Windows

Hilfreichster Kommentar

Hey, am Ende dieses Threads sieht es so aus, dass Sie Ihre MSVC-Probleme gelöst haben. Aber wenn Sie irgendwelche Probleme haben, bin ich im MSVC-Team. Zögern Sie nicht, mich auf github oder per E-Mail anzupingen ([email protected])

Alle 222 Kommentare

/cc @alexbrainman

@xoviat, was ist das Problem, das du hast? Ich muss es hier reproduzieren können. Geben Sie also bitte alle Schritte an, die ich befolgen muss, um dies zu reproduzieren.

Dankeschön

Alex

PS: Ich werde bis Ende Juli keinen Computer haben. Das werde ich mir dann mal anschauen.

was ist das problem, das du hast?

Ich habe es noch nicht ausprobiert, aber ich möchte C-Funktionen in msvc-Objektdateien gezielt aufrufen, indem ich sie als .syso mit dem Go-Linker verlinke. Alles, was ich gelesen habe, deutet darauf hin, dass dies nicht möglich ist, aber ich werde ein Verfahren erstellen, um den spezifischen Fehler zu reproduzieren, der auftritt.

Rufen Sie speziell c-Funktionen in msvc-Objektdateien auf, indem Sie sie als .syso mit dem go-Linker verknüpfen

Haben Sie versucht, diese in eine DLL zu integrieren und sie innerhalb der DLL zu verwenden?

Ich werde eine Prozedur erstellen, um den spezifischen Fehler zu reproduzieren, der auftritt.

Bitte. Dankeschön.

Alex

Haben Sie versucht, diese in eine DLL zu integrieren und sie innerhalb der DLL zu verwenden?

Das war eigentlich mein ursprünglicher Plan. Ich verwende swig, daher ist es nicht so praktisch, den generierten C-Code separat zu kompilieren und dann die Funktionen als DLL-Exporte neu zu schreiben. Es ist nicht schwer, aber es ist ärgerlich, wenn der Workflow mit gcc nur go generate; go build .

Okay, ich habe ein Verfahren. Beginnen Sie mit diesen Dateien:

hallo.go:

package main

/*
    extern void hello();
*/
import "C"

func main() {
    C.hello()
}

Hallo c:

#include <stdio.h>

extern void hello()
{
    printf("Hello World from C");
}

Führen Sie dann diese Befehle aus (mit msvc im Pfad):

cl /c hello.c
mv hello.obj hello.syso
mv hello.c hello.c.bak
go build

Ergebnis:
Warning: corrupt .drectve at end of def file

Beim Ausführen der produzierten Datei:

Exception 0xc0000005 0x8 0x13 0x13
PC=0x13
signal arrived during external code execution

main._Cfunc_hello()
        _//_obj/_cgo_gotypes.go:41 +
main.main()
        C://hello.go:9 +0x27

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        C:/Program Files/Go/src/runtime/asm_amd64.s:2197 +0x1
rax     0x4a5960
rbx     0xc042045f78
rcx     0x4a9a20
rdi     0xc042045f78
rsi     0x4adc60
rbp     0xc042045f38
rsp     0x6dfd68
r8      0xc042016340
r9      0x0
r10     0xc04204faa0
r11     0x4783c2
r12     0x0
r13     0x6
r14     0x0
r15     0xf1
rip     0x13
rflags  0x10216
cs      0x33
fs      0x53
gs      0x2b

Ich habe keinen cl-Befehl auf meinem PC installiert. Wie installiere ich msvc?

Dankeschön.

Alex

Sie müssen die „Build - Tools 2017“ hier . Microsoft erlaubt jetzt tatsächlich jedem, Visual Studio kostenlos zu nutzen, solange es nicht für die kommerzielle Entwicklung bestimmt ist. Wenn es zu viel Aufwand ist, kann ich Ihnen die Objektdatei einfach geben, wenn Sie möchten.

Wenn nur c++ kein Ding wäre, müsste ich mir darüber keine Sorgen machen. Aber es ist so, also geht der Schmerz weiter...

Sie benötigen hier die "Buildtools 2017".

Ich habs. Dankeschön.

Wenn es zu viel Aufwand ist, kann ich Ihnen die Objektdatei einfach geben, wenn Sie möchten.

Ja, bitte poste hello.obj irgendwo.

Denke noch etwas darüber nach. Sie verwenden tatsächlich gcc, um eine mit dem msvc-Compiler kompilierte Objektdatei zu verknüpfen. Können Sie versuchen, Ihre Übung durchzuführen, aber den Schritt "go build" durch gcc ersetzen, der hello.obj mit einem C-Programm verknüpft? Vielleicht wurde es schon einmal gemacht. Ich vermute, wenn wir wissen, wie das geht, können wir mit Go vielleicht ähnliches machen.

Alex

AFAIK lld https://github.com/llvm-mirror/lld unterstützt msvc-Objektdateien.

Objektdatei ist hier: https://github.com/xoviat/msvcgo/blob/master/hello.syso

lld https://github.com/llvm-mirror/lld unterstützt msvc-Objektdateien

Go verwendet den gcc-Linker (nicht lld) unter Windows.

Objektdatei ist hier: https://github.com/xoviat/msvcgo/blob/master/hello.syso

Ich werde es versuchen, wenn ich im August zu Hause bin. Danke schön.

Alex

Go verwendet den gcc-Linker (nicht lld) unter Windows.

Ich kenne. Aber lld ist die beste Open-Source-Dokumentation des msvc-Objektformats.

Ich bekomme tatsächlich den gleichen Fehler von ld, also kommt der Fehler definitiv von ld.

Ich bekomme tatsächlich den gleichen Fehler von ld, also kommt der Fehler definitiv von ld.

Jawohl. Wir müssen herausfinden, wie man ein C-Programm erstellt, indem wir einen Teil mit msvc kompilieren und mit gcc verknüpfen.

Alex

Verzeihen Sie meine Unwissenheit, aber was genau GCC-Verknüpfung? Verknüpft es die Ausgabe des Go-Linkers?

Ausführen von objconv für die Objektdateien, um sie in elf zu konvertieren:

objconv -felf hello.obj hello.syso

Wir haben jetzt diese Fehler:

hello.syso: In function `__local_stdio_printf_options':
(.text$mn+0x3): undefined reference to `?_OptionsStorage@?1??__local_stdio_printf_options@@9<strong i="9">@9</strong>'
hello.syso: In function `_vfprintf_l':
(.text$mn+0x3a): undefined reference to `__stdio_common_vfprintf'
hello.syso: In function `printf':
(.text$mn+0x28): undefined reference to `__acrt_iob_func'
collect2.exe: error: ld returned 1 exit status

Möglicherweise ist stdio tabu?

Verzeihen Sie meine Unwissenheit, aber was genau GCC-Verknüpfung? Verknüpft es die Ausgabe des Go-Linkers?

Sie verwenden 2 Programme, um Ihr Go-Programm zu erstellen:

  • Compiler konvertiert Ihre .go-Dateien (jeweils 1 Paket) in eine Objektdatei, die im Verzeichnis %GOPATH%/pkg gespeichert ist;
  • Linker, der die endgültige .exe-Datei aus Objektdateien von unter %GOPATH%/pkg erstellt.

Manchmal (wenn eines Ihrer Pakete Cgo verwendet) ruft der Go-Linker den externen Linker auf, um alle Bits zu finden, die in C implementiert sind. Stellen Sie sich vor, Sie rufen printf aus Ihrem C-Code auf. Der in C printf kompilierte Code muss Teil der ausführbaren Go-Datei sein, aber der Go-Linker weiß nicht, wo er ihn herbekommt. Der Go-Linker ruft also den externen Linker auf, um diesen Code einzuschließen.

Current Go verwendet den gcc-Compiler/Linker, um C-Code zu kompilieren und zu verknüpfen (wir verwenden mingw gcc). Wenn Sie Ihren C-Code mit einem anderen Compiler (von Microsoft) kompilieren möchten, müssen Sie den entsprechenden Linker (von Microsoft) verwenden, um den gesamten externen C-Code zu finden, den der Compiler erstellt hat.

Ich schätze, ich lag falsch, als ich vorschlug, gcc-Linker zu verwenden. Für ein allgemeines Szenario müssten Sie sowohl den Microsoft-Compiler als auch den Linker verwenden. Wir müssten herausfinden, was der Microsoft-Linker als Eingabe benötigt und das abgleichen.

Sie könnten ohne MC-Linker auskommen, wenn Ihr C-Code keinen externen Code enthält. Bitte versuchen Sie es mit einem wirklich einfachen C-Programm (wie dem, das 2 Ganzzahlen hinzufügt oder so). Das könnte so funktionieren, wie du es oben beschrieben hast.

Alex

Möglicherweise ist stdio tabu?

Ich vermute, Sie müssen den Microsoft-Linker aufrufen, um diesen Code zu finden.

Alex

Ich bin mir nicht sicher, aber

objconv -felf hello.obj hello.syso

Vielleicht solltest du versuchen, Coff oder OMF anstelle von Elf zu machen?

Vielleicht solltest du versuchen, Coff oder OMF anstelle von Elf zu machen?

@xoviat ja, Sie sollten .obj-Dateien nicht in elf konvertieren. Die Windows-Version von gcc generiert pe/coff-Dateien wie jeder andere Windows-Compiler.

Alex

der Go-Linker ruft den externen Linker auf, um alle Bits zu finden, die in C implementiert sind.

Welcher spezifische Befehl wird verwendet? Wenn ich den Befehl mingw kenne, kann ich vielleicht einen Dateivergleichspfad durchlaufen, um zu versuchen, msvc an die Ausgabe von mingw anzupassen.

Sie können den genauen Kommentar anzeigen, indem Sie go build -ldflags=-v .

Okay, soweit ich das beurteilen kann:

ld (link -> go.obj) + (gcc -> obj files) ==> a.out.exe

Go scheint ein temporäres Verzeichnis mit diesen Dateien zu erstellen. Gibt es eine Möglichkeit, das temporäre Verzeichnis beizubehalten, damit ich seinen Inhalt überprüfen kann?

Versuchen Sie es mit go build -work

WORK=C:\Users\mattn\AppData\Local\Temp\go-build566171254

Objektdateien verbleiben in diesem Verzeichnis.

Die Option -work behält die temporären Dateien, die der Linker erstellt, tatsächlich nicht bei. Im Moment müssen Sie nur die Linker-Quellen bearbeiten, um das Verzeichnis nicht zu entfernen. Wir sollten wahrscheinlich so oder so eine Option dafür hinzufügen.

Im Moment müssen Sie nur die Linker-Quellen bearbeiten, um das Verzeichnis nicht zu entfernen.

Wenn es Ihnen nichts ausmacht, warte ich, bis dies in HEAD implementiert ist, damit ich mich nicht wiederholen muss.

Gibt es eine Möglichkeit, das temporäre Verzeichnis beizubehalten, damit ich seinen Inhalt überprüfen kann?

Das cmd/link-Programm hat dafür das Flag -tmpdir. Sie können es so verwenden:

c:\Users\Alex\dev\src\a>dir
 Volume in drive C has no label.
 Volume Serial Number is 9012-A870

 Directory of c:\Users\Alex\dev\src\a

06/08/2017  02:02 PM    <DIR>          .
06/08/2017  02:02 PM    <DIR>          ..
06/08/2017  02:02 PM                77 main.go
               1 File(s)             77 bytes
               2 Dir(s)  430,809,088,000 bytes free

c:\Users\Alex\dev\src\a>type main.go
package main

import "fmt"
import "C"

func main() {
        fmt.Println("Hello")
}

c:\Users\Alex\dev\src\a>go build -o a.exe -ldflags="-tmpdir=c:\Users\Alex\dev\src\a" main.go

c:\Users\Alex\dev\src\a>dir
 Volume in drive C has no label.
 Volume Serial Number is 9012-A870

 Directory of c:\Users\Alex\dev\src\a

06/08/2017  02:02 PM    <DIR>          .
06/08/2017  02:02 PM    <DIR>          ..
06/08/2017  02:02 PM             2,055 000000.o
06/08/2017  02:02 PM            22,376 000001.o
06/08/2017  02:02 PM         2,017,382 a.exe
06/08/2017  02:02 PM               135 fix_debug_gdb_scripts.ld
06/08/2017  02:02 PM         2,402,226 go.o
06/08/2017  02:02 PM                77 main.go
06/08/2017  02:02 PM                24 trivial.c
               7 File(s)      4,444,275 bytes
               2 Dir(s)  430,804,631,552 bytes free

c:\Users\Alex\dev\src\a>

Alex

Dies ist nur für meine eigene Referenz, aber dies muss auf msvc portiert werden:

_cgo_sys_thread_start(ThreadStart *ts)
{
    uintptr_t thandle;

    thandle = _beginthread(threadentry, 0, ts);
    if(thandle == -1) {
        fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
        abort();
    }
}

static void
threadentry(void *v)
{
    ThreadStart ts;

    ts = *(ThreadStart*)v;
    free(v);

    ts.g->stackhi = (uintptr)&ts;
    ts.g->stacklo = (uintptr)&ts - STACKSIZE + 8*1024;

    /*
     * Set specific keys in thread local storage.
     */
    __asm {
          "movq %0, %%gs:0x28\n"    // MOVL tls0, 0x28(GS)
          "movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp
          "movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
          :: "r"(ts.tls), "r"(ts.g) : "%rax"
    }

    crosscall_amd64(ts.fn);
}

Ich würde den Zeitaufwand für diese Aufgabe nicht unterschätzen, da ich mich mit Montage überhaupt nicht auskenne.

  • [x] Verstehen, was die Baugruppe macht
  • [x] Port zur MSVC-Assembly
  • [x] Verstehen Sie _beginthread vs CreateThread
  • [x] Zu CreateThread wechseln

Außerdem undefinierte Symbole:

  • [x] timeBeginPeriod --> winmm.lib
  • [x] timeBeginPeriod
  • [x] WSAGetOverlappedResult --> Ws2_32.lib
  • [x] WSAGetOverlappedResult
  • [x] _cgo_18b6f6fc815b_Cfunc_hello
  • [x] x_cgo_init --> msvc_windows_amd64.c
  • [x] x_cgo_thread_start --> msvc_windows_amd64.c
  • [x] x_cgo_sys_thread_create --> msvc_windows_amd64.c
  • [x] x_cgo_notify_runtime_init_done --> gcc_libinit_windows.c
  • [x] x_cgo_set_context_function --> gcc_libinit_windows.c

Okay, hier geht es schneller weiter als erwartet!

Alles: Wird asm_amd64.s vom go-Assembler (mit der ungeraden Assembly) oder vom gcc-Assembler assembliert?

Es scheint, dass gcc es nicht zusammenbauen wird, was bedeutet, dass es wahrscheinlich zusammengebaut wird. Und dann stellt sich die Frage, wie man es mit dem go-Assembler zu einem Objekt zusammenbaut.

Die Absicht ist, dass runtime/cgo/asm_amd64.s zu einem Go-Objekt assembliert wird, dann cmd/link es mit allen anderen Go-Objekten zu einem einzigen Systemobjekt verknüpft und dann der Systemlinker diese einzelnen Systemobjekte und alle anderen verknüpft cgo-Abhängigkeiten in das endgültige Programm.

Gibt es eine Möglichkeit, das Objekt jetzt zu Testzwecken zusammenzubauen? Wie gcc -c asm_amd64.s außer mit go?

Die Absicht ist, dass runtime/cgo/asm_amd64.s zu einem Go-Objekt assembliert wird, dann cmd/link es mit allen anderen Go-Objekten zu einem einzigen Systemobjekt verknüpft und dann der Systemlinker diese einzelnen Systemobjekte und alle anderen verknüpft cgo-Abhängigkeiten in das endgültige Programm.

Bisher habe ich diese Objekte gefunden:

  • go.o : offensichtlich von der Go-Toolchain
  • _cgo_.o : von gcc generiert, unbrauchbar
  • 000000.o : von gcc generiert, unbrauchbar
  • 000001.o : Update: wird tatsächlich vom go-Linker generiert, enthält aber gcc-Symbole. Unbrauchbar.

go.o ist das größte Objekt.

@ianlancetaylor

Ich glaube nicht, dass das richtig ist, was du gesagt hast. crosscall_amd64 befindet sich in 000001.o, aber diese Datei enthält nicht "den gesamten Go-Code":

000001.o:     file format pe-x86-64

SYMBOL TABLE:
[201](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x0000000000000440 crosscall_amd64
[206](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x0000000000000000 free

Diese Datei wurde offensichtlich von gcc generiert, was zu spät im Prozess ist.

Gibt es eine Möglichkeit, das Objekt jetzt zu Testzwecken zusammenzubauen? Wie gcc -c asm_amd64.s außer mit go?

asm_amd64.s ist Teil des Laufzeitpakets. Sie können sehen, wie der Befehl "go build" die Datei asm_amd64.s verwendet, wie zum Beispiel:

$ touch asm_amd64.s
$ GOOS=windows go build -x runtime 2>&1 | grep asm_amd64.s
/home/a/go/pkg/tool/linux_amd64/asm -trimpath $WORK -I $WORK/runtime/_obj/ -I /home/a/go/pkg/include -D GOOS_windows -D GOARCH_amd64 -o $WORK/runtime/_obj/asm_amd64.o ./asm_amd64.s
$

Alex

Vielen Dank.

Das Symbol crosscall_amd64 ist in der Datei runtime/cgo/gcc_amd64.s definiert. Diese Datei wird von GCC kompiliert (wie alle runtime/cgo/gcc_*-Dateien). Es wird also nicht in der einzigen go.o-Datei zusammengefasst, die den gesamten Go-Code enthält. Die Datei, über die wir zuvor gesprochen haben, runtime/cgo/asm_amd64.s, definiert das Symbol crosscall2 . Dieses Symbol finden Sie in go.o.

Vielen Dank.

Okay, ich habe es geschafft, eine ausführbare Datei zu verknüpfen, die bei einer Zugriffsverletzung abstürzt, während ich in
go.runtime.rt0_go+5F --> go.___acrt_stdio_initializer.

Das ist die ganze Zeit, die ich im Moment habe; Ich komme später darauf zurück.

@alexbrainman Das ist richtig.

@alexbrainman Sie benötigen MSVC, um fortzufahren. Lassen Sie mich wissen, ob Sie dabei Hilfe benötigen.

Sie benötigen MSVC, um fortzufahren.

Ich installiere das https://www.visualstudio.com/downloads/#build -tools-for-visual-studio-2017

Was soll ich nach der Installation tun?

Alex

Sobald Sie das installiert haben, müssen Sie "libgo" erstellen, die go-Bibliothek. Kopieren Sie die folgenden Dateien aus dem cgo-Ordner :

  • gcc_amd64.S
  • gcc_fatalf.c
  • gcc_libinit_windows.c
  • gcc_util.c
  • gcc_windows_amd64.c
  • libcgo.h

Wir müssen gcc_windows_amd64.c anpassen, damit es mit MSVC kompatibel ist. Ändern Sie die Funktion wie folgt:

static void
threadentry(void *v)
{
    fprintf(stderr, "threadentry: started");
    abort();

    ThreadStart ts;

    ts = *(ThreadStart*)v;
    free(v);

    ts.g->stackhi = (uintptr)&ts;
    ts.g->stacklo = (uintptr)&ts - STACKSIZE + 8*1024;

    /*
     * Set specific keys in thread local storage.
     */
    __writegsqword(0x28, (unsigned long long) ts.tls);
    *(void **)ts.tls = (void *) ts.g;

    crosscall_amd64(ts.fn);
}

Erstellen Sie eine neue Datei im Ordner mit all diesen Dateien namens "build.bat":

REM TMP use gcc for assmebly file, in future port to ml64
gcc -c gcc_amd64.S
cl -c gcc_fatalf.c
cl -c gcc_libinit_windows.c
cl -c gcc_windows_amd64.c
cl -c gcc_util.c

ren gcc_amd64.o gcc_amd64.obj

lib gcc_amd64.obj gcc_fatalf.obj gcc_libinit_windows.obj ^
    gcc_windows_amd64.obj gcc_util.obj ^
    /OUT:libgo.lib

Lassen Sie es mich wissen, wenn Sie den Ordner wie gewünscht strukturiert haben.

Übrigens, vielen Dank für die Arbeit daran und fürs Gehen. Ihr habt eine wahrhaft magische Sprache geschaffen.

Lassen Sie es mich wissen, wenn Sie den Ordner wie gewünscht strukturiert haben.

Ich habe es geschafft, libgo.lib zu erstellen, wie Sie hier beschrieben haben https://github.com/golang/go/issues/20982#issuecomment -327365063
Was soll ich als nächstes tun?

Alex

Okay, jetzt brauchen wir also die folgenden Dateien:

  • libgo.lib
  • Schmiere
  • hallo.cgo2.o
  • Hallo c

hallo.c ist folgendes:

#include <stdio.h>

extern void hello()
{
    printf("Hello World from C");
}

Um hello.cgo2.o und go.o , müssen Sie mit der folgenden Datei beginnen:

package main

/*
    extern void hello();
*/
import "C"
import "fmt"

func main() {
    fmt.Println("Hello from Go!")
    C.hello()
}

namens "hallo.go"

Richten Sie ein Powershell-Skript ein, das kontinuierlich Dateien von $ env:TMP kopiert:

while ($true) {  cp -r $env:TMP\go-* C:\Users\User\Downloads }

Führen Sie dann go build mit hello.c und hello.go im Ordner aus. Sie sollten in der Lage sein, die erforderlichen Dateien von dem Speicherort wiederherzustellen, an den sie kopiert wurden.

Sobald Sie über die oben angegebenen Dateien verfügen, können Sie Folgendes erstellen:

cl libgo.lib go.o hello.cgo2.o hello.c Ws2_32.lib Winmm.lib -link /DEBUG:FULL

Lassen Sie es mich wissen, wenn Sie Fragen haben.

cl libgo.lib go.o hello.cgo2.o hello.c Ws2_32.lib Winmm.lib -link / DEBUG:FULL

Dadurch wird die ausführbare Datei go.exe erstellt, die jedoch nicht ausgeführt wird. Ich sehe da keinen vernünftigen asm-Code. Erste Anweisung einfach ins Nirgendwo springen. Es ist nur ein Durcheinander.

Vielleicht solltest du mit etwas ganz Einfachem beginnen. Schreiben Sie eine asm-Datei (Go asm file) mit einer einzelnen asm-Funktion, die "INT $3" ausführt und nichts anderes hat. Und versuchen Sie, daraus ein ausführbares Programm zu bauen - das Programm sollte Ihre Funktion gleich beim Start ausführen.

Vielleicht bauen Sie es zuerst mit Go-Tools (und bei Bedarf auch mit gcc) und versuchen Sie dann dasselbe mit MSVC.

Alex

Alex, danke für deine Hilfe. Daran werde ich arbeiten.

Ich werde diese beiden Artikel hier für meine eigene Referenz anhängen. Ansonsten habe ich kein Update mehr.

Ich habe tatsächlich ein ziemlich komplexes Go-Programm zum Laufen gebracht, das nur die msvc-Bibliothek verwendet. Es stellte sich heraus, dass sowohl der Vanilla-msvc-Linker als auch llvm-lld den Abschnitt .bss nicht korrekt behandelten.

Sobald ich den Linker gepatcht habe, kann das Programm ausgeführt werden.

Leider bricht go build , wenn _cgo_.o / _all.o generiert wird. Ist es möglich, die Gründe für die Generierung dieser beiden Dateien in cgo zu beleuchten?

Sie können go tool cgo ausführen, um cgo direkt auszuführen. Die Quellen sind hier: https://github.com/golang/go/tree/master/src/cmd/cgo

Außerdem wäre es großartig, wenn Sie dies zum Laufen bringen könnten. Ich habe dem einfach keine Zeit gewidmet, also gab es keine Fortschritte. Das tut mir leid.

Ich habe bereits Programme, die durch eine Reihe von Handstitching korrekt ausgeführt werden können - was ich hier versuche, ist zu sehen, ob der Prozess wieder in go integriert werden kann, um es weniger schmerzhaft zu machen. :-)

Wenn Sie den Handstickprozess dokumentieren können, kann ich vielleicht helfen.

Allein vom Anschauen scheint _cgo_.o folgt erzeugt zu werden (vereinfacht):

gcc [*.c] [*.cxx] -o _cgo_.o

Von hier: https://github.com/golang/go/blob/b4c84a1b010f012668b5e3ccaf63f609cd11c5fe/src/cmd/go/internal/work/exec.go#L1975

Idealerweise würden wir ein go-Programm schreiben, das die Objektdateien so vorverarbeitet, dass sie mit link.exe für minimale Reibung kompatibel sind, aber das ist eine Art Stretch Goal.

Danke für den Hinweis - ich werde den Prozess gleich aufschreiben.

Leider glaube ich nicht, dass die Verlinkung über link.exe sei denn, wir ändern gcc so, dass nicht initialisierte Daten im Abschnitt .data anstelle des Abschnitts .bss ausgegeben werden – aber wir können auf jeden Fall llvm-lld , um den Abschnitt .bss (was ich getan habe).

Wir müssen _cgo_.o und _all.o separat angehen. Ich habe ein paar Fragen dazu:

(1) Es scheint, dass _cgo_.o nicht die letzte ausführbare Datei ist, da sie nicht die go-Laufzeit enthält. Es sieht so aus, als ob der Compiler seine DWARF-Symbole betrachtet, um die Definition der Struktur herauszufinden. Das Problem ist, dass es schwierig ist, eine ausführbare Datei zu generieren, wenn Sie extern mit einer Reihe von Bibliotheken verknüpfen möchten, insbesondere mit denen, die von msvc generiert werden.

Kann man diesen Schritt vermeiden?

(2) aktuell gehe GNU ld , um alle Objektdateien in _all.o heften, indem du das -Wl,-r in GCC übergibst. Dies ist problematisch, da (1) andere Linker diese Funktion anscheinend nicht haben und (2) der Befehl von CGO_LDFLAGS . Der folgende Befehl generiert beispielsweise falsche Ergebnisse:

CGO_LDFLAGS="-Wl,-T,my-linker-script"
gcc .... $CGO_LDFLAGS -Wl,-r,...

Es generiert eine ausführbare Datei anstelle einer gebündelten Objektdatei.

Ist es möglich, diesen Schritt überhaupt zu vermeiden, indem Sie einfach alle Objektdateien direkt in die generierten .a einfügen?

@zooba Wie stehen die Chancen, dass MSFT link.exe mit diesem Patch aktualisiert?

Leider glaube ich nicht, dass die Verlinkung über link.exe erfolgen kann, es sei denn, wir ändern gcc so, dass nicht initialisierte Daten im .data-Abschnitt anstelle des .bss-Abschnitts ausgegeben werden - aber wir können definitiv llvm-lld reparieren, um den .bss-Abschnitt zu erkennen (was ich gemacht habe).

Angenommen, MSFT aktualisiert link.exe (was wahrscheinlich ist), wäre es gut, die Objektdateien mit cl.exe statt mit gcc zu kompilieren.

Es scheint, dass _cgo_.o nicht die letzte ausführbare Datei ist, da sie nicht die go-Laufzeit enthält.

Das ist richtig, es gibt im Grunde zwei Sätze von Objektdateien (glaube ich), die am Ende miteinander verknüpft werden. Die Datei go.o (IIRC) enthält den gesamten Go-Code + Laufzeit, und die anderen Objekte enthalten den C-Code. Es gibt Assemblierungsroutinen, um zwischen den beiden Objektsätzen zu springen.

Außerdem benötigen wir clang , um die Unix-Assembly-Dateien zu kompilieren.

Für unsere Zwecke entspricht -Wl,-r dem Ausführen von lib.exe [object files] /OUT:obj . Die Option bedeutet "inkrementell verknüpfen", was bedeutet "Einige Eingabedateien nehmen, etwas arbeiten und dann eine andere Objektdatei ausspucken". Wenn wir uns vorerst nicht um den Teil "Arbeiten" kümmern, können wir die Anforderung einfach als "Einige Eingabedateien und / oder Objektdateien nehmen und eine andere Objektdatei ausspucken" annehmen, außer in unserem Fall wird die Objektdatei eine Bibliothek.

Sie können GCC mit der Option -fno-zero-initialized-in-bss anweisen, Variablen nicht in den .data-Abschnitt statt in den .bss-Abschnitt zu setzen.

Beachten Sie, dass wir beim Erstellen von cgo-Code nicht mehr -Wl,-r verwenden.

Es sollte nicht notwendig sein, dass cmd/link MSVC-Objektdateien versteht, um sie als .syso Dateien zu verwenden. Diese Dateien werden sowieso nur an den externen Linker übergeben. Ich denke, dass hier der MSVC-Linker als externer Linker aufgerufen werden muss, was Sie mit der Option -extld tun können sollten. Wenn Sie das bereits tun, bitte ich um Entschuldigung; Was ist in diesem Fall fehlgeschlagen?

Wenn Sie das bereits tun, bitte ich um Entschuldigung; Was ist in diesem Fall fehlgeschlagen?

IIRC, link.exe barfs auf den gcc-generierten Objekten.

Es stimmt, Sie müssten auch den Compiler von MSVC C verwenden, indem Sie die Umgebungsvariable CC entsprechend festlegen. Ich glaube nicht, dass es funktionieren wird, GCC-Objekte und MSVC-Objekte in einem einzigen Link zu kombinieren.

Aber dann stoßen Sie auf das Problem, dass die Laufzeit-C-Bibliotheken vorkompiliert sind. Und wenn Sie versuchen, sie neu zu kompilieren, stoßen Sie auf das Problem, dass cl die Unix-Assembly nicht kompilieren kann. Und so portiert man Teile der Laufzeitbibliotheken und versucht, sie zu verknüpfen, was ich getan habe und gescheitert bin.

Irgendwann kompiliert cl einen wichtigen Teil des Codes falsch. Meine Idee, dies zu beheben, wäre, den MSVC-Code in eine DLL mit einer flachen C-API auszugliedern und dann einfach mehr der Laufzeitbibliotheken inkrementell zu kompilieren, bis er nicht mehr funktioniert.

Die Idee von @haohui zur Behebung des Problems war eine andere. Anstatt die Wurzel des Problems zu beheben, arbeitete er daran, indem er den Linker patchte. Offensichtlich hatte er mehr Erfolg als ich, aber das liegt wahrscheinlich daran, dass sein Ansatz im Nachhinein wahrscheinlicher funktioniert als meiner.

Was ich an dieser Stelle (IMHO) empfehlen würde, ist, inkrementell mehr von der Laufzeitbibliothek mit cl zu kompilieren, bis sie nicht mehr funktioniert oder Sie keinen gcc-Code mehr haben. Dann wissen Sie genau, wo das Problem liegt.

Und mit dem Linker-Patch wird keine DLL benötigt.

Der Patch von llvm-lld ist verfügbar unter https://bugs.llvm.org/show_bug.cgi?id=35283

Ich werde einige Zeit damit verbringen, ein Beispiel zu liefern.

+1 @haohui Vielen Dank, dass

@haohui Für welche Version von llvm gilt dein Patch? Irgendwelche Anweisungen zur Verwendung Ihres Patches und zur Verknüpfung mit MSVC-Dateien?

In Bezug _cgo_.o Dateien _all.o hatte ich das gleiche Problem, also kann eine Lösung für dieses Problem möglicherweise auch eine Lösung für das andere Problem sein: https://github.com/golang/go /ausgaben/17014

Danke für die ganze Arbeit dazu. Klingt nach guten Fortschritten. Neue Funktionen sind bis Go 1.11 eingefroren, sodass sich der Meilenstein ändert.

Also habe ich mich gestern Abend darauf eingelassen. Es ist möglich, alles über msvc:cl zu erstellen und dann alles über msvc:link zu verknüpfen. Die Probleme sind jedoch Legion.

Abgesehen von den einfachen Problemen wie msvc:link bläst die .bss-Segmente weg (ich denke, es könnte diese Daten einfach in .data werfen), was ein Problem ist, da es so aussieht, als würde der Go-Assembler-SB (Pseudo-Reg) zu einer falschen Adressierung führen, wenn .bss verschoben wird .

Mein erster Gedanke wäre, zu versuchen, dass der Assembler die Dinge, die in .bss und .noptrbss gehen würden, in .data bzw. .noptrdata platziert. Ich bin mir nicht einmal sicher, ob dies möglich ist; mein Herumfummeln war nicht erfolgreich und die Adressierung wird komplett abgespritzt.

Ich glaube nicht, dass es derzeit möglich ist, link.exe zu verwenden. Ich denke, wir sollten mit lld-link.exe beginnen

Wenn der Gedanke dahinter ist, dass wir lld-link patchen können, um die .bss-Daten nicht zu verschieben, verstehe ich den Reiz. Realistischerweise, wenn das Ziel darin besteht, die eigentliche msvc-Toolkette zu unterstützen, muss die interne Kompilierung, die Daten in .bss/.noptrbss platziert, behandelt werden.

Können wir lld-link.exe nicht einfach mit go verteilen? Dies scheint der Pfad mit dem geringsten Risiko zur Unterstützung von MSVC-Objektdateien zu sein, solange LTCG nicht aktiviert ist. Ich verstehe, dass es nicht ideal ist, aber wir stehen vor einer Ressourcenbeschränkung.

Es ermöglicht auch inkrementellen Fortschritt, was die beste Strategie ist.

Okay, ein paar gute Folgenachrichten, ich konnte beim Mittagessen eine Stunde damit verbringen, daran zu arbeiten.

Im Moment habe ich das Beispiel von früher in der Ausgabe funktioniert:

- hello.go:
package main

/*
    extern void hello();
*/
import "C"

func main() {
    C.hello()
}

- extern.c
#include <stdio.h>

extern void hello()
{
    printf("Hello World from C");
}
>ac.out.exe
Hello World from C

Die Binärdatei wird vollständig mit der MSVC- und Go-Toolchain erstellt (kein GCC oder andere LLVM installiert).

Ergebnisse:

  • Es war letztendlich ziemlich trivial, dass die Go tools/link.exe .bss-Daten für interne Assemblys in .data ausgeben
  • Für msvc mussten mehrere ASM-Stücke angepasst werden
  • Ein paar GCC #defs wurden geshimmt
  • An einigen der von cgo generierten .c-Dateien mussten einige kleine Anpassungen vorgenommen werden
  • Komplexe Zahlen müssen geshimmt werden, im Moment werden sie nicht unterstützt
  • Es ist wahrscheinlich, dass zusätzliche Flags direkt zum Erstellen oder Verknüpfen für die msvc-Unterstützung hinzugefügt werden müssen, ldflags usw. reichen nicht aus

Nächste Schritte:
Wenn ich dieses Wochenende Zeit habe, werde ich daran arbeiten, meine Änderungen in einen Fork zu bringen und die Funktionalität hinter Flags in Build/Link. Danach lasse ich eine PR zur Überprüfung laufen, damit wir die Arten ausarbeiten können. Ich bin nicht 100% sicher, dass das Verschieben der .bss-Daten irgendwo keine Auswirkungen haben wird.

Der einzige Nachteil, den ich mir vorstellen kann, ist, dass es die Größe der Binärdatei sprengt, aber es sollte in Ordnung sein.

Okay!

Es tut mir leid, dass ich ein paar zusätzliche Tage gebraucht habe, um das zusammenzustellen. So findet sich der erste Entwurf eines Patches hier: https://github.com/cchamplin/go/commit/69a5cfc1dd0106fd8a2928a83e4c7001e81e89b8 :: https://github.com/cchamplin/go/tree/msvc_toolchain_support

Dies ist immer noch grob, aber ich habe es erfolgreich mit msvc Code erstellen können.

Es wäre großartig, wenn die Leute jetzt anfangen könnten, dies zu testen und mir Fehler zu melden, damit ich dies an einer besseren Stelle für den Upstream finden kann. Auch wenn jemand Tests schreiben möchte, wäre das großartig!

Verwendungszweck:

go build -compiler msvc [path]
  • Komplexe Zahlen werden derzeit nicht unterstützt, bis ich herausgefunden habe, ob wir sie zum Laufen bringen können.
  • Ich habe keine Ahnung, was passiert, wenn Sie versuchen, die go-Laufzeit mit dem msvc-Compiler zu erstellen.
  • gcc wird immer noch benötigt und von gco verwendet, um Definitionen und Typdaten zu erhalten, wenn es kompiliert wird , wird es nicht zum Erstellen

Der verlinkte Patch erzeugt ein Bootstrapping-Problem.

@alexbrainman Wie und wo wird festgelegt, welche Dateien während der Boostrapping-Phase von toolchain1 in pkg/boostrap/src/bootstrap toolchain1 kopiert werden?

cc @alexbrainman

Der verlinkte Patch erzeugt ein Bootstrapping-Problem.

Ich weiß nicht, wie Bootstrapping heutzutage funktioniert. Aber ich bin mir sicher, dass andere ( @rsc und @ianlancetaylor) helfen können.

Ich frage mich, wie @cchamplin make.bat ausführt, wenn das Bootstrapping nicht funktioniert.

Alex

@xoviat Ich weiß nicht, was das Problem ist, aber die Liste der Bootstrap-Verzeichnisse befindet sich in cmd/dist/buildtool.go.

Hey @alexbrainman , @ianlancetaylor , @xoviat Entschuldigung, ich denke, ich hätte es gründlicher überprüfen sollen.

Ich habe den Branch hier https://github.com/cchamplin/go/commit/69a5cfc1dd0106fd8a2928a83e4c7001e81e89b8 mit einem Fix für das Bootstrapping-Problem aktualisiert, ich denke, es sollte jetzt richtig booten.

Ich musste einige /src/internal/syscall-Verzeichnisse nach cmd/internal/msvc kopieren. Wird das ein riesiges Problem? Ich bin mir nicht sicher, wie ich auf die Registrierung zugreifen kann, ohne src/internal zu verwenden.

Ich musste einige /src/internal/syscall-Verzeichnisse nach cmd/internal/msvc kopieren. Wird das ein riesiges Problem? Ich bin mir nicht sicher, wie ich auf die Registrierung zugreifen kann, ohne src/internal zu verwenden.

Ich weiß nicht, wie es heutzutage gemacht wird, aber ich vermute, dass cmd/dist dies tun kann, ohne dass Sie Quelldateien manuell kopieren. Ich bin sicher, dass Russ oder Ian Ihnen helfen werden, wenn Sie bereit sind, Code einzureichen.

Ich denke, es ist an der Zeit, dass @bradfitz und @ianlancetaylor entscheiden, wie es hier weitergeht. Soll Go sowohl Microsoft-Buildtools als auch gcc unterstützen? Wir müssten entsprechende Microsoft-Tools auf unseren Buildern installieren (das müssten wir tun, bevor wir anfangen, CLs zu akzeptieren). Wir müssten wahrscheinlich neue Umgebungsvariablen einführen. Neue Dokumentation.

Wenn die Antwort ja ist, müsste @cchamplin seine Codeänderungen gemäß https://golang.org/doc/contribute.html einreichen. Wären Sie dazu bereit? Die Änderung ist ziemlich groß, daher muss sie in kleinere CLs unterteilt werden, damit sie überprüft und separat eingereicht werden können. Jede Änderung müsste all.bat PASS haben, bevor sie eingereicht werden kann. Es wäre schön, wenn wir alle CLs sehen könnten, bevor wir mit dem Einreichen der ersten CL beginnen.

Dankeschön.

Alex

Soll Go sowohl Microsoft-Buildtools als auch gcc unterstützen?

Nur eine Anmerkung, dass dieser Patch auch #17014 erleichtert, für den ich bereits einen Patch in Arbeit habe.

Wenn die Antwort ja ist, müsste @cchamplin seine Codeänderungen gemäß https://golang.org/doc/contribute.html einreichen. Wären Sie dazu bereit? Die Änderung ist ziemlich groß, daher muss sie in kleinere CLs unterteilt werden, damit sie überprüft und separat eingereicht werden können.

Ja, und das Aufbrechen sollte keine große Sache sein. Ich muss nur wissen, ob dies wahrscheinlich etwas ist oder nicht, bevor ich mir die Mühe mache, den gesamten Code zu bereinigen, die Dokumentation zu schreiben, Tests zu erstellen usw.

Soll Go sowohl Microsoft-Buildtools als auch gcc unterstützen?

In meinen Augen lautet die Antwort ja. Die Compiler selbst sind bei VS Community kostenlos, und es ist wirklich frustrierend, keine vollständige Windows-Unterstützung zu haben. Ich sollte keine Linux-Box aufstellen müssen, um github.com/Microsoft/hcsshim (zum Beispiel) zu kompilieren, da eine Windows-Toolchain nicht unterstützt wird.

Was wäre der Grund, eine Windows-Toolchain nicht zu unterstützen?

Ich denke, es ist im Prinzip in Ordnung, MSVC-Objektdateien zu unterstützen. Wir brauchen einen Baumeister.

Meine Hauptsorge ist, wie sehr sich das Format zwischen Windows- oder MSVC-Versionen ändern könnte. Das auf den meisten anderen Plattformen verwendete ELF-Format ist sehr stabil; Wir müssen die ELF-Unterstützung nur sehr selten auf andere Weise optimieren, als Unterstützung für neue Prozessoren hinzuzufügen. Ist das MSVC-Dateiformat ähnlich stabil?

Die mit der MSVC-Toolchain verbundenen Formate sind ziemlich stabil. Das größte Problem wird die Unterstützung der Tools selbst sein. Microsoft neigt dazu, Dinge (Dateien und Registrierungseinträge) zwischen Versionen von Visual Studio zu verschieben. Das meiste davon ist konfigurierbar (zumindest in dem von mir geschriebenen Patch), aber es besteht immer noch die Möglichkeit, dass eine neue Hauptversion von Visual Studio möglicherweise nicht als Build-Toolchain ohne Änderungen an Go kompatibel ist. Alle unterstützten früheren Versionen von Visual Studio würden jedoch weiterhin funktionieren.

Soweit ich weiß, hat das COFF-Format eine angemessene Stabilität, wenn Sie sich nur dem C ABI (nicht C++) aussetzen. Es ist auch ausführlich dokumentiert und LLVM bietet eine Referenzimplementierung.

@cchamplin Ich würde empfehlen, dass Benutzer vcvarsall.bat aufrufen, bevor sie eine Verknüpfung mit MSVC herstellen. Dadurch wird der Wartungsaufwand auf nahezu Null reduziert.

Wir brauchen einen Baumeister.

@ianlancetaylor Wenn sich herausgestellt hat, dass MSVC-Objekte wie beabsichtigt funktionieren, glauben Sie, dass sowohl ein msys/cygwin-Builder als auch ein MSVC-Builder benötigt werden, oder würde es nur einen MSVC-Builder geben?

Ich bin sicher, einige Leute werden es vorziehen, die Cygwin-Tools zu verwenden, und sie funktionieren bereits und wir möchten, dass sie weiterhin funktionieren, also denke ich, dass wir zwei Builder brauchen.

Hey, am Ende dieses Threads sieht es so aus, dass Sie Ihre MSVC-Probleme gelöst haben. Aber wenn Sie irgendwelche Probleme haben, bin ich im MSVC-Team. Zögern Sie nicht, mich auf github oder per E-Mail anzupingen ([email protected])

Wir brauchen einen Baumeister.

Jawohl. Und wir sollten wahrscheinlich damit beginnen, unsere bestehenden Builder so zu ändern, dass MS-Build-Tools installiert sind. Wir können sie also verwenden, da wir CLs für dieses Problem akzeptieren.

Wir können auf allen unseren Buildern sowohl gcc-Tools als auch Microsoft-Tools installieren. Können wir all.bat ausführen, das sowohl gcc- als auch Microsoft-Tools in einem Durchgang testet? Wenn nicht, müssten wir verschiedene Builder für verschiedene Tools konfigurieren. Welche Parameter steuern, welche externen Compiler und Linker verwendet werden?

Meine Hauptsorge ist, wie sehr sich das Format zwischen Windows- oder MSVC-Versionen ändern könnte.

Bei Windows wird kein Compiler installiert. Sie müssen es selbst installieren. Genau wie wir es mit gcc tun. Wir installieren jede gewünschte Version. Wir könnten sogar verschiedene gcc-Versionen auf verschiedenen Buildern ausführen.

Ist das MSVC-Dateiformat ähnlich stabil?

Darüber weiß ich nichts. Ich vermute, Sie verwenden nur die bereitgestellten Tools.

Alex

Meine Hauptsorge ist, wie sehr sich das Format zwischen Windows- oder MSVC-Versionen ändern könnte. Das auf den meisten anderen Plattformen verwendete ELF-Format ist sehr stabil; Wir müssen die ELF-Unterstützung nur sehr selten auf andere Weise optimieren, als Unterstützung für neue Prozessoren hinzuzufügen. Ist das MSVC-Dateiformat ähnlich stabil?

Ja, COFF ist sehr stabil.

@bradfitz und @ianlancetaylor, was brauchen wir, um einen Windows-Builder zum Testen von Änderungen für dieses Problem https://github.com/golang/go/issues/20982#issuecomment -370719472

Dankeschön

Alex

Ist Go jetzt MSVC-Objekt zu unterstützen?

Änderung https://golang.org/cl/110555 erwähnt dieses Problem: debug/pe: parse the import directory correctly

@alexbrainman @bradfitz @ianlancetaylor :

Ich habe die meiste Arbeit geleistet, die meiner Meinung nach erforderlich ist, um den Patch zu säubern und in leichter verdauliche Stücke aufzubrechen. Ich glaube, ich bin kurz davor, das Projekt tatsächlich einzureichen. Ich schätze, ich muss wissen, ob ich auf die Situation des Builders warten sollte, bevor ich den Code einreiche, oder es einfach so schnell wie möglich tun?

Sie können die CLs jederzeit senden, aber jemand muss einen Builder einrichten. Sonst haben wir keine Möglichkeit sie zu testen.

@johnsonj , könnten Sie die MSVC-Compiler-Tools zu unseren Windows-Images hinzufügen?

Ich möchte idealerweise keinen neuen Hosttyp hinzufügen und nur 1-3 unserer vorhandenen Windows-Hosttypen zusätzlich zu Cygwin die MSVC-Tools verwenden. Und dann können wir zusätzlich zu diesen geänderten Hosttypen weitere Builder-Konfiguration(en) hinzufügen.

/cc @andybons @bcmills als FYI (dafür, wie Windows-Zeug passiert ... wir bitten Jeff um Hilfe :))

@johnsonj , könnten Sie die MSVC-Compiler-Tools zu unseren Windows-Images hinzufügen?

@cchamplin Ich schlage vor, dass Sie versuchen, dem Builder alle erforderlichen Tools selbst hinzuzufügen. Niemand sonst, aber Sie wissen, was erforderlich ist. Eine vollständige Anleitung finden Sie im Verzeichnis golang.org/x/build/env/windows. Insbesondere möchten Sie wahrscheinlich mehr Zeilen in startup.ps1 hinzufügen. Sobald Sie wissen, was in diesem Director geändert werden muss, nehmen Sie die Änderungen vor und senden Sie Ihre Änderung zur Überprüfung über https://golang.org/doc/contribute.html Nach der Annahme können wir die Builder anhand dieser Anweisungen aktualisieren.

Ich möchte idealerweise keinen neuen Hosttyp hinzufügen und nur 1-3 unserer vorhandenen Windows-Hosttypen zusätzlich zu Cygwin die MSVC-Tools verwenden. Und dann können wir zusätzlich zu diesen geänderten Hosttypen weitere Builder-Konfiguration(en) hinzufügen.

Wir hatten immer Mingw (gcc) C-Compiler und -Linker unter Windows. Wir haben nie verschiedene C-Build-Tools. Wäre es möglich, sowohl Mingw- als auch Microsoft C-Funktionen mit einer einzigen Ausführung von all.bat testen zu lassen, sobald wir Unterstützung für den Microsoft C-Compiler hinzugefügt haben? Oder schließen sich Mingw oder Microsoft C aus? Müssten wir eine Umgebungsvariable so setzen, dass sie auf Mingw oder Microsoft zeigt, aber nie auf beides? Ich nehme an, ich versuche zu verstehen, wie der Code strukturiert und getestet werden muss. Dies wird auch bestimmen, wie viele verschiedene Builder wir benötigen.

Alex

Ich werde mir das Backen der Binärdateien im Bild ansehen

Änderung https://golang.org/cl/112036 erwähnt dieses Problem: env/windows: add visual studio tools to image

@johnsonj @bradfitz : Danke, dass aufgenommen hast .

@alexbrainman @bradfitz @ianlancetaylor : Was die Teststrategie dafür angeht, bin ich mir nicht sicher, was ich genau tun soll . Wir können den Weg nehmen, dist test für beide Toolchains auf Window auszuführen und jeden Test zweimal durchführen, oder sollten wir die cgo-Tests nur zweimal testen (einmal für gcc, einmal für msvc)?

Was die Teststrategie dafür angeht, bin ich mir nicht sicher, was ich tun soll. Wir können den Weg nehmen, dist test für beide Toolchains auf Window auszuführen und jeden Test zweimal durchführen, oder sollten wir die cgo-Tests nur zweimal testen (einmal für gcc, einmal für msvc)?

@cchamplin Ich habe keine Antwort auf Ihre Frage. Ich vermute, Ian kennt die Antwort.

Alex

Was kostet es, alle Tests zweimal statt nur cgo auszuführen?

@mxplusb , wir können einfach eine neue Build-Konfiguration für Windows ausführen und sie wird parallel zu unserer bestehenden 3 ausgeführt. Eine neue Builder-Konfiguration ist in Ordnung. Wir fügen sie regelmäßig hinzu.

Sagen Sie mir einfach, wie Sie es anders machen können: Legen Sie eine andere / neue Umgebungsvariable fest und dann wird etwas darauf eingehen, nehme ich an?

Es braucht wahrscheinlich ein paar Dinge, damit das funktioniert.

Entweder müssen wir in einer Shell/Umgebung laufen, in der der go-Test, den dist test ausführt, ausgeführt wird, nachdem die entsprechende vsvars.bat ausgeführt/aufgerufen wurde

Oder wir können dist die entsprechenden vsvars ausführen lassen und die benötigten Umgebungsvariablen extrahieren und diese dann setzen/übergeben, um zu testen.

Wir möchten wahrscheinlich auch eine Umgebungsvariable, die dist oder make.bat mitteilt, dass wir die Tests mit -compiler msvc set ausführen möchten.

Entweder müssen wir in einer Shell/Umgebung laufen, in der der go-Test, den dist test ausführt, ausgeführt wird, nachdem die entsprechende vsvars.bat ausgeführt/aufgerufen wurde

Oder wir können dist die entsprechenden vsvars ausführen lassen und die benötigten Umgebungsvariablen extrahieren und diese dann setzen/übergeben, um zu testen.

Ich würde es vorziehen, wenn wir keine Batch-Dateien von dist.exe oder go.exe ausführen. Es ist mühsam, mit Batch-Dateien umzugehen.

Wir möchten wahrscheinlich auch eine Umgebungsvariable, die dist oder make.bat mitteilt, dass wir die Tests mit -compiler msvc set ausführen möchten.

Ich hatte gehofft, Ian würde wissen, was hier der beste Ansatz ist. Soweit ich weiß, unterstützen wir auch verschiedene C-Compiler unter Unix (gcc oder clang). Unser Build-Prozess ermöglicht es uns sicherlich, für verschiedene C-Compiler zu testen.

Alex

Mir war vorher nicht aufgefallen, dass Sie planen, go build -compiler msvc . Das macht keinen Sinn. Die Option go build -compiler nimmt den Namen eines Go-Compilers an (derzeit entweder gc oder gccgo). Es nimmt nicht den Namen eines C-Compilers an. Der C-Compiler wird in der Umgebungsvariablen CC . Der Standard-C-Compiler wird durch Setzen der Umgebungsvariablen CC_FOR_TARGET beim Ausführen von make.bat festgelegt, wie in den Kommentaren in make.bat dokumentiert.

Ich würde erwarten, dass wir einen Builder haben, für den wir die Umgebungsvariable CC_FOR_TARGET auf msvc setzen, bevor wir all.bat ausführen. Ich verstehe nicht, warum wir etwas anderes tun sollten.

Der C-Compiler wird in der CC-Umgebungsvariablen übergeben. Der Standard-C-Compiler wird durch Setzen der Umgebungsvariablen CC_FOR_TARGET beim Ausführen von make.bat festgelegt, wie in den Kommentaren in make.bat dokumentiert.

Danke Jan für die Erklärung.

@cchamplin Ich hoffe, Sie können Ihre Änderungen an das vorhandene Modell anpassen. Lassen Sie es uns wissen, wenn Sie Probleme haben. Dankeschön.

Ich würde erwarten, dass wir einen Builder haben, für den wir die Umgebungsvariable CC_FOR_TARGET auf msvc setzen, bevor wir all.bat ausführen.

Wir haben 3 AMD64-Windows-Builder auf https://build.golang.org. Sollten wir einen durch MSVC ersetzen? Wollen wir 386 MSVC Builder?

Alex

@ianlancetaylor @alexbrainman Das Flag -compiler verstanden. Ich glaube nicht, dass es einen einfachen Weg gibt, nur CC="msvc" (oder wirklich CC="cl.exe" ) zum Laufen zu bringen. CC muss weiterhin auf einen GCC-Speicherort verweisen, damit MSVC-Builds funktionieren. Das msvc-Compiler-Toolset verfügt nicht über die Tools, die es CGO ermöglichen, die erforderliche Introspektion durchzuführen (Definitionssuche, Typauflösung), sodass GCC für MSVC-Builds weiterhin erforderlich ist.

Wäre es akzeptabel, ein neues Flag hinzuzufügen, um Build zu starten (Toolchain oder so)? Ich musste cgo bereits ein Toolchain-Flag hinzufügen, glaube ich.

Auch das Setzen von CC_FOR_TARGET vor all.bat scheint negative Konsequenzen zu haben, da es den beim Bootstrapping verwendeten Compiler beeinflussen würde. Ich glaube nicht, dass MSVC während des Bootstrapping-Prozesses verwendet werden kann (ich bin nicht 100% dabei, ich habe es nicht wirklich versucht, aber ich bezweifle stark, dass es funktionieren wird).

Ich sehe, für MSVC müssen wir sowohl GCC als auch MSVC haben? Wo wird GCC nur vom cgo-Tool verwendet? Das scheint etwas bedauerlich zu sein, da es bedeutet, dass wir uns absolut darauf verlassen würden, dass GCC und MSVC genau das gleiche ABI implementieren, aber ich denke, das ist ziemlich wahrscheinlich.

Ich denke, wir könnten eine weitere Umgebungsvariable CC_FOR_CGO hinzufügen, die auf GCC gesetzt werden könnte.

Die von make.bat verwendeten CC_FOR_TARGET werden verwendet, um Runtime/cgo zu erstellen. Es ist mir nicht klar, wie cgo überhaupt funktionieren könnte, wenn runtime/cgo nicht von dem von Ihnen verwendeten C-Compiler erstellt wird.

Vielleicht sollten wir damit beginnen, die Dinge zum Laufen zu bringen, wenn make.bat aufgerufen wird, indem wir CC_FOR_TARGET auf cl und CGO_ENABLED auf 0 .

Danke @ianlancetaylor :

Ich sehe, für MSVC müssen wir sowohl GCC als auch MSVC haben? Wo wird GCC nur vom cgo-Tool verwendet? Das scheint etwas bedauerlich zu sein, da es bedeutet, dass wir uns absolut darauf verlassen würden, dass GCC und MSVC genau das gleiche ABI implementieren, aber ich denke, das ist ziemlich wahrscheinlich.

Ich stimme zu, dass es bedauerlich ist, und würde mich freuen, von einer Alternative zu erfahren, ich habe noch keine gefunden. Es besteht sicherlich ein Risiko, auf diese Weise zu bauen (zB hat der zu bauende cgo-Code unterschiedliche Typ-Defs oder -Definitionen, je nachdem, von welchem ​​Compiler er denkt, dass er gebaut wird). Daher sind Builds möglicherweise nicht immer erfolgreich oder funktionieren ohne einige Optimierungen nicht richtig (in meiner Implementierung gibt es einen Mechanismus, um dies zu handhaben, aber es ist ein bisschen ein manueller Prozess). Leider denke ich, dass dies ein Risiko ist, das die Leute eingehen müssen, wenn sie die MSVC-Toolchain verwenden möchten, und alles, was wir tun können, ist es vorerst zu dokumentieren.

In ähnlicher Weise gibt es immer noch keinen wirklichen Weg zur Bereitstellung von Complex64- und Complex128-Unterstützung in MSVC-erstellten cgo-Programmen, nur weil der MSVC-Compiler nicht c99-kompatibel ist.

Ich denke, wir könnten eine weitere Umgebungsvariable CC_FOR_CGO hinzufügen, die auf GCC gesetzt werden könnte.

Die aktuelle Implementierung, die ich habe, ist, wenn go build angewiesen wird, mit MSVC zu erstellen, wird standardmäßig nach cl.exe im Pfad gesucht, aber dies kann mit der Umgebungsvariablen MSCC überschrieben werden. CGO wird weiterhin die CC-Umgebungsvariable verwenden, die auf gcc/was auch immer in der generierten zdefaultcc.go sitzt

Die von make.bat verwendeten CC_FOR_TARGET werden verwendet, um Runtime/cgo zu erstellen. Es ist mir nicht klar, wie cgo überhaupt funktionieren könnte, wenn runtime/cgo nicht von dem von Ihnen verwendeten C-Compiler erstellt wird.

In der aktuellen Implementierung funktioniert cgo problemlos für msvc-Binärdateien, auch wenn die gesamte go-Toolchain von gcc erstellt wurde. zB wird MSVC-Code zu go/src hinzugefügt. all.bat wird ausgeführt, um die go-Umgebung mit gcc aufzubauen. Danach kann go/bin/go.exe zum Erstellen mit der msvc-Toolchain verwendet werden (vorausgesetzt, dass Flags bereitgestellt werden). Vielleicht verstehe ich aber nicht, was du hier sagst.

Die Komplexität, weil wir mit msvc bauen wollen, ist komplizierter, als nur den Compiler auf cl umzustellen. Die MSVC-Toolchain unterscheidet sich stark von der gcc-Toolchain. In MSVC muss eine Umgebung eingerichtet werden, indem sie in einer vcvars.bat ausgeführt wird (oder das tut, was v8 z Prozess). Nachdem wir uns in einer MSVC-Umgebung befinden, besteht der Hauptunterschied darin, dass die Tools selbst cl.exe zum Kompilieren von C- und C++-Dateien verwendet werden, ml.exe und ml64.exe zum Assemblieren von Dateien verwendet werden, und schließlich wird link.exe (ms) verwendet, um alles miteinander verbinden. Es ist also mehr als nur CC=cl.exe und ihm die richtigen Flags zu übergeben. Ist das sinnvoll/hilft zur Klärung?

Zur weiteren Klärung auf

Das von make.bat verwendete CC_FOR_TARGET wird verwendet, um Runtime/cgo zu erstellen. Es ist mir nicht klar, wie cgo überhaupt funktionieren könnte, wenn runtime/cgo nicht von dem von Ihnen verwendeten C-Compiler erstellt wird.

go build wählt während des Build-Prozesses die entsprechenden Dateien aus Runtime/cgo aus (zB go build / go test / go run -- nicht der Builder-Prozess), wenn die msvc-Toolchain wurde ausgewählt.

Ich bin offen für Vorschläge, wie dies funktionieren sollte, aber es sollte keine neue Befehlszeilenoption für das Go-Tool erforderlich sein. Können wir ein reines Go-Programm schreiben, das sich in Bezug auf das Go-Tool wie GCC verhält, aber tatsächlich MSVC ausführt?

Können wir ein reines Go-Programm schreiben, das sich in Bezug auf das Go-Tool wie GCC verhält, aber tatsächlich MSVC ausführt?

Ich glaube, dass das praktikabel sein könnte, lassen Sie mich sehen, ob ich auf diesem Weg etwas in Gang bringen kann.

Außerdem muss ich wohl klären, ob das Hinzufügen von Befehlszeilen-Flags zu anderen Tools ebenfalls ein Problem darstellt. Im Moment erstellt der umfangreiche Patch dafür mehrere neue Kommandozeilen-Flags in verschiedenen Tools

  • cmd/cgo

    • -toolchain [gcc,msvc] (standardmäßig gcc) Toolchain zum Erstellen von cgo-Ausgabedateien

  • cmd/link

    • -rlocbss (standardmäßig false) Verschiebe .bss nach .data

    • -toolchain [gcc,msvc] (standardmäßig gcc) Toolchain für externes Verlinken

wir erstellen auch die folgenden Build-Optionen/cgo-Umgebungsvariablen:

  • MSCXX
  • MSCC
  • MSCFLAGS
  • MSCPPFLAGS
  • MSCXXFLAGS
  • MSLDFLAGS

Nach ein paar Minuten des Nachdenkens gibt es ein paar Hürden, die möglicherweise schwer zu überwinden sind, wenn wir nur die Compiler-Befehle als Proxy verwenden, dachten alle zusammen an ein anderes Programm

  1. go build muss wissen, was die externe Toolchain ist, um zu bestimmen, welche Runtime-/cgo-Dateien erstellt werden sollen, andernfalls würde es am Ende nur die inkompatiblen gcc-Versionen an unseren Proxy-Befehl übergeben. Wir könnten dies möglicherweise innerhalb des Proxys selbst hacken, aber es wäre brüchig und würde wahrscheinlich kaputt gehen, wenn jemals zusätzliche Dateien zu Runtime/cgo hinzugefügt würden.
  2. cmd/cgo muss wissen, welche Art von externer Toolchain verwendet wird, um die zu verwendende Version des C-Ausgabecodes auszuwählen
  3. Das Proxy-Programm müsste einen Mechanismus haben, um zu wissen, ob es gcc ausführen soll (wie beim Aufruf von cmd/cgo) oder cl.exe ausführen soll, was übergeben werden könnte, aber das bedeutet, dass der Aufrufer wissen muss, was die Toolchain ist ist oder wir hätten cmd/cgo nicht vorhandene Flags an gcc übergeben.
  4. go build ruft cmd/link auf, das auch wissen muss, was die Toolchain ist, damit es die .bss-zu-.data-Verlagerung durchführen und bestimmte Flags an den Linker übergeben kann (wir könnten letzteres möglicherweise handhaben) Teil im Proxy selbst)

Würde die Angabe einer Umgebungsvariable mit go build zum Bestimmen von msvc-Builds funktionieren? Obwohl ich denke, dass es die Messlatte für jemanden höher legt, der nur ein Programm mit msvc erstellen möchte, da er jetzt mehrere Umgebungsvariablen zusätzlich zur Ausführung in vsvars.bat setzen muss (mindestens CC und UNDECIDED_TURN_ON_MSVC_BUILD_VAR )

Eine andere Alternative wäre, go build einen gefälschten noop-Befehl für das angegebene CC ausführen zu lassen und dann das Logo/den Header zu analysieren, um zu erkennen, ob es sich um msvc oder gcc handelt, und an diesem Punkt mit den entsprechenden Toolchain-Anpassungen fortzufahren ...nicht sicher, wie spröde das ist oder wie es mit msvc-kompatiblen Toolchains wie clang funktionieren würde.

Habe diese Github-Ausgabe vor kurzem entdeckt und diese Arbeit ist für mich sehr spannend. Ich hoffe, das landet in naher Zukunft irgendwo.

Meine Absicht ist es, CGo unter Windows als Wrapper für Code von Drittanbietern zu verwenden, der mit MSVC erstellt wurde und den ich nicht einfach aus Quellen mit mingw-w64 neu erstellen kann. Ich habe einige relativ ernsthafte Testfälle, die ich durchlaufen muss, also kann ich es ziemlich gut validieren.

Wie auch immer, danke an

@cchamplin Ich weiß genug, um über die Compiler-Toolchains in Windows und cgo gefährlich zu sein, damit ich möglicherweise helfen kann. Könnten Sie mir etwas von dem erzählen, woran Sie gearbeitet haben? Ich werde sehen, was ich tun kann, um zu helfen. Ich weiß , dass der Anwendungsfall @deadprogram hat , damit ich einen guten fortgeschrittenen Prüfstand habe , wenn wir bereit zu testen sind.

Hey @mxplusb , der Patch ist eigentlich mehr oder weniger fertig. Wenn ich die Zeit finde, werde ich die Änderungen heute Abend oder morgen an gerrit übermitteln, was uns dazu bringt, alles zu überprüfen, zu aktualisieren und zu genehmigen.

Änderung https://golang.org/cl/133937 erwähnt dieses Problem: cmd/link: Add flag rlocbss to relocate .bss data to .data

Änderung https://golang.org/cl/133938 erwähnt dieses Problem: runtime/cgo: MSVC toolchain support in cgo native code

Änderung https://golang.org/cl/133939 erwähnt dieses Problem: cmd/cgo: Add toolchain flag to cgo command for MSVC support

Änderung https://golang.org/cl/133946 erwähnt dieses Problem: cmd/compile: Add support for MSVC toolchain to go build

Es sieht so aus, als hätte ich das Problem in einigen Commits getippt. Ich lasse den Überprüfungsprozess in Gang kommen und bestimme die beste Lösung.

Änderung https://golang.org/cl/133943 erwähnt dieses Problem: cmd/cgo: Add support for CC_FOR_CGO environment variable

Änderung https://golang.org/cl/133942 erwähnt dieses Problem: tests: Update various tests to prepare for MSVC compiler toolchain

Änderung https://golang.org/cl/133940 erwähnt dieses Problem: misc/cgo: Adjust tests to be compatible with MSVC toolchain support

Änderung https://golang.org/cl/133941 erwähnt dieses Problem: runtime: Add runtime.CompilerType to denote between host compiler type

Änderung https://golang.org/cl/133945 erwähnt dieses Problem: cmd/link: Add external toolchain support for MSVC

Änderung https://golang.org/cl/133944 erwähnt dieses Problem: cmd/compile, cgo: Add support for MSVC flags

@cchamplin kannst du beschreiben, was die endgültige Entscheidung war? Wie sieht die MSVC-Unterstützung aus? Welche Befehlszeilen-Flags werden hinzugefügt? Was muss ein Benutzer zusätzlich zum Herunterladen von MSVC mit seiner Umgebung tun? Vielen Dank

Und wie können wir diesen Patch ausprobieren? Ich konnte Ihre Commits im Repo nicht finden.

@rasky Es ist immer noch ein bisschen im Fluss, während die Änderungen überprüft werden. Es müssen wahrscheinlich keine spezifischen Befehlszeilen-Flags gesetzt werden, sondern einfach cgo-Anwendungen erstellen, bei denen die CC-Umgebungsvariable auf MSVC zeigt oder kein CC gesetzt ist und cl.exe im Pfad ist, gcc jedoch nicht.

@blizzardplus Ähnlich wie oben sind die Dinge gerade mit der Überprüfung stark im Fluss, daher ist es möglicherweise etwas früh, um mit dem Ausprobieren zu beginnen (obwohl es Ihnen

@cchamplin gibt es Unterstützung für Cross-Compilierung mit gcc oder clang ? Wenn ja, werden sie getestet?

@cchamplin Ich sehe seit 9/11 keine Aktivitäten in den CLs, gibt es diesbezüglich Fortschritte oder benötigt es zusätzliche Ressourcen?

@cchamplin damit dies für c-archive funktioniert, sollte der Abschnitt ctors in .CRT$XCU geändert werden (https://msdn.microsoft.com/en-us/library/bb918180.aspx) - Wenn dies nicht der Fall ist, dann golang-Laufzeit wird nicht initialisiert. Es stellt sich auch heraus, dass es auch für gcc gut funktioniert, wenn Sie dies einstellen - gcc nimmt diese Funktionen immer noch, verschiebt sie in einen Textabschnitt und modifiziert main, um sie vor dem echten main aufzurufen. Visual Studio kann .a-Archivdateien verstehen und da die Schnittstelle der vorkompilierten/assemblierten Dateien C ist, sollte es kein Problem sein, diese nur im Archiv zu haben. Es gibt eine Warnung zu 2 .text-Abschnitten, aber einfache Fälle scheinen gut zu funktionieren (erfordert weitere Tests zur Bestätigung, dass keine Probleme vorliegen).

Damit dies auch für c-shared funktioniert, müssen die zu exportierenden Funktionen mit __declspec(dllexport) dekoriert werden, aber ich kann nicht finden, wo diese Erweiterung von //export stattfindet.

@blizzardplus Es gibt einen

@kshelton Leider ist dies eine sehr arbeitsreiche Zeit des Jahres für mich, da ich andere Projekte in Arbeit und Konferenzen habe, auf denen ich präsentiere. Ich werde möglicherweise nicht vor Dezember wieder in der Lage sein, das erforderliche Refactoring in den Patch zu integrieren.

@kshelton Danke. Ich habe den Patch nicht doppelt überprüft, ich gehe davon aus, dass ich ihn mit der Annahme entwickelt habe, dass c-Archive auf MSVC nicht funktioniert, oder ihn speziell deaktiviert habe? Ich habe versucht, Exporte richtig zu dekorieren, als ich versuchte, Plugins / Shared unter Windows zum Laufen zu bringen. Ich glaube, es gibt noch andere Probleme, aber ich könnte zwei Probleme miteinander vermischen. Es gibt echte Probleme damit, wie go seinen gemeinsamen Code in PLT/GOT für ELF im Vergleich zu Windows .edata,idata und EAT platziert. Ich glaube, die meisten Probleme, mit denen ich konfrontiert war, waren Umzüge und die Unfähigkeit, sie zum Arbeiten zu bringen. Wenn hier jemand Einblick hat, wäre das wunderbar. Siehe #19282

@cchamplin Ich habe versucht zu sehen, ob ich Go auf deinem CL aufbauen kann

https://go-review.googlesource.com/c/go/+/133946/3

Ich habe diese Batch-Datei verwendet, um meine Umgebung einzustellen

set TERM=msys
set MYHOME=c:\users\alex\dev
set GOROOT=%MYHOME%\go
set GOROOT_BOOTSTRAP=%MYHOME%\go1.4.3
set GOPATH=%MYHOME%
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
set CC=cl
set PATH=%PATH%;%MYHOME%\my\bin\;%GOROOT%\bin
cd %GOROOT%\src
CMD

und ich erhalte diese Fehlermeldung, wenn ich make.bat ausführe

C:\Users\Alex\Desktop>set TERM=msys

C:\Users\Alex\Desktop>set MYHOME=c:\users\alex\dev

C:\Users\Alex\Desktop>set GOROOT=c:\users\alex\dev\go

C:\Users\Alex\Desktop>set GOROOT_BOOTSTRAP=c:\users\alex\dev\go1.4.3

C:\Users\Alex\Desktop>set GOPATH=c:\users\alex\dev

C:\Users\Alex\Desktop>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
Microsoft Windows [Version 10.0.17134.407]
(c) 2018 Microsoft Corporation. All rights reserved.

c:\Users\Alex\dev\go\src>make
Building Go cmd/dist using c:\users\alex\dev\go1.4.3
go tool dist: cannot invoke C compiler "cl": exit status 2

Go needs a system C compiler for use with cgo.
To set a C compiler, set CC=the-compiler.
To disable cgo, set CGO_ENABLED=0.

Command output:

Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25507.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '--help'
cl : Command line error D8003 : missing source filename

The system cannot find the batch label specified - fail

c:\Users\Alex\dev\go\src>

Was fehlt mir hier?

Dankeschön.

Alex

@alexbrainman

Was fehlt mir hier?

Sie müssen wahrscheinlich mindestens CC_FOR_CGO=gcc setzen. Ich habe persönlich auch noch nie probiert das selber bauen mit MSVC geht. Ich bin mir nicht sicher, ob das funktionieren würde/sollte unterstützt werden.

-C

Sie müssen wahrscheinlich mindestens CC_FOR_CGO=gcc setzen.

Ihr https://go-review.googlesource.com/c/go/+/133940 enthält einige Tests. Wie kann ich überprüfen, ob die Tests bestanden wurden? Was sind genaue Schritte?

Außerdem führen die Go-Builder https://build.golang.org %GOROOT%\src\all.bat aus, um alle Tests zu überprüfen (einschließlich der unter https://go-review.googlesource.com/c/go/+/ 133940) bestanden. Wie schlagen Sie vor, dass wir den Go-Code ändern, damit %GOROOT%\src\all.bat Ihre angepassten Tests von https://go-review.googlesource.com/c/go/+/133940 ausführt

Ich habe persönlich auch noch nie probiert das selber bauen mit MSVC geht. Ich bin mir nicht sicher, ob das funktionieren würde/sollte unterstützt werden.

Sie können all.bat erfolgreich ausführen, ohne dass gcc installiert ist. Die aktuelle Version von Go benötigt zum Erstellen nur eine andere Version von Go (mindestens go1.4). Nur Cgo benötigt den C-Compiler. Ich hatte den Eindruck, dass Ihre Änderungen die von MSVC erstellte Cgo-Version implementieren. Aber vielleicht irre ich mich. Bitte korrigiert mich, wenn ich falsch liege.

Dankeschön.

Alex

@alexbrainman

Ihr https://go-review.googlesource.com/c/go/+/133940 enthält einige Tests. Wie kann ich überprüfen, ob die Tests bestanden wurden? Was sind genaue Schritte?

Vielleicht kann all.bat sowohl die gcc- als auch die msvc-Version der Tests testen. Vielleicht können wir eine Umgebungsvariable verwenden, die all.bat mitteilt, welche Testversion ausgeführt werden soll - und dann könnten wir zwei verschiedene Builder verschiedene Versionen der Tests ausführen lassen. Hast du an das alles gedacht?

Ja, genau dieser Mechanismus wird in https://go-review.googlesource.com/c/go/+/133946/ verwendet. Da alle Aufrufe von run.bat unter Windows durchgeführt wurden, wurde der Mechanismus zum Aufrufen von cgo-Tests dort platziert. Sie oder der Builder würden also mit einem normalen Setup CC=gcc beginnen. Dann würden Sie GOTESTMSVC=1 und GOVSVARSPATH=einen vsvars.bat-Pfad setzen. Danach sollte das Erstellen mit all.bat sowohl gcc- als auch msvc-cgo-Tests durchlaufen.

Sie können all.bat erfolgreich ausführen, ohne dass gcc installiert ist. Die aktuelle Version von Go benötigt zum Erstellen nur eine andere Version von Go (mindestens go1.4). Nur Cgo benötigt den C-Compiler. Ich hatte den Eindruck, dass Ihre Änderungen die von MSVC erstellte Cgo-Version implementieren. Aber vielleicht irre ich mich. Bitte korrigiert mich, wenn ich falsch liege.

Du hast Recht. Go selbst sollte gut bauen. Beim Testen kann es zu Problemen kommen, da run.bat geändert wurde, um einige Umgebungsvariablen zu setzen, wenn GOTESTMSVC=1 ist. Wir könnten wahrscheinlich versuchen, festzustellen, ob go gerade mit msvc erstellt wird, und dann die entsprechenden dist-Umgebungsvariablen setzen, damit die Tests nicht fehlschlagen.

Dann würden Sie GOTESTMSVC=1 und GOVSVARSPATH=einen vsvars.bat-Pfad setzen. Danach sollte das Erstellen mit all.bat sowohl gcc- als auch msvc-cgo-Tests durchlaufen.

Das habe ich versucht.

ich benutzte

commit e56d52f66b95b87001867a2487a11bd961f40d4d (HEAD)
Author: Caleb Champlin <[email protected]>
Date:   Sat Sep 8 00:26:32 2018 -0600

    cmd/compile: add support for MSVC toolchain to go build

    Allows building with MSVC as an external compiler/linker.

    Setting CC=cl.exe inside an MSVC environment will automatically
    build cgo executables using MSVC as the external compiler and
    linker.

    For the builders setting the environment variable GOVSVARSPATH
    to the location of a msvsvars.bat file and setting the
    environment variable GOTESTMSVC=1 will automatically cause
    all.bat to run tests and compiler with both gcc and MSVC.

    Updates #20982

    Change-Id: I44be1f43aa0d53a688c595bc8336e0364b809ced

Ich führe zuerst diese Batchdatei aus:

set TERM=msys
set MYHOME=c:\users\alex\dev
set GOROOT=%MYHOME%\go
set GOROOT_BOOTSTRAP=%MYHOME%\go1.4.3
set GOPATH=%MYHOME%
set MINGW=%MYHOME%\mingw64_4.9.1

set GOTESTMSVC=1
set GOVSVARSPATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"

set PATH=%PATH%;%MINGW%\bin;%MYHOME%\my\bin\;%GOROOT%\bin
cd %GOROOT%\src
CMD

und dann all.bat ausführen. all.bat schlägt fehl mit

--- FAIL: TestDocsUpToDate (0.00s)
    help_test.go:26: alldocs.go is not up to date; run mkalldocs.sh to regenerate it
go test proxy starting
go test proxy running at GOPROXY=http://127.0.0.1:52023/mod
go proxy: no archive w.1 v1.2.0
go proxy: no archive x.1 v1.0.0
go proxy: no archive z.1 v1.2.0
go proxy: no archive rsc.io v1.5.0
go proxy: no archive example.com/unused v0.0.0
go proxy: no archive example.com/unused v0.0.0
go proxy: no archive sub.1 v1.0.0
go proxy: no archive badsub.1 v1.0.0
go proxy: no archive versioned.1 v1.0.0
go proxy: no archive versioned.1 v1.1.0
go proxy: no archive golang.org/x/text/language 14c0d48
go proxy: no archive golang.org/x/text/language 14c0d48
go proxy: no archive golang.org/x/text/language 14c0d48
go proxy: no archive golang.org/x/text/foo 14c0d48
go proxy: no archive golang.org/x 14c0d48
go proxy: no archive golang.org 14c0d48
go proxy: no archive example.com/split/subpkg v1.0.0
FAIL
FAIL    cmd/go  147.247s
ok      cmd/go/internal/cache   13.115s
ok      cmd/go/internal/dirhash 0.518s
ok      cmd/go/internal/generate        0.180s
ok      cmd/go/internal/get     0.761s
ok      cmd/go/internal/imports 0.212s
ok      cmd/go/internal/load    1.050s
ok      cmd/go/internal/modconv 1.596s
ok      cmd/go/internal/modfetch        0.881s
ok      cmd/go/internal/modfetch/codehost       0.179s
ok      cmd/go/internal/modfile 0.193s
ok      cmd/go/internal/modload 2.820s
ok      cmd/go/internal/module  0.860s
ok      cmd/go/internal/mvs     0.255s
ok      cmd/go/internal/par     0.107s
ok      cmd/go/internal/search  0.087s
ok      cmd/go/internal/semver  0.140s
ok      cmd/go/internal/txtar   0.249s
ok      cmd/go/internal/web2    0.136s
ok      cmd/go/internal/work    0.200s
ok      cmd/gofmt       0.216s
ok      cmd/internal/buildid    0.522s
ok      cmd/internal/dwarf      0.077s
ok      cmd/internal/edit       0.160s
ok      cmd/internal/goobj      2.430s
ok      cmd/internal/obj        0.103s
ok      cmd/internal/obj/arm64  0.190s
ok      cmd/internal/obj/x86    0.845s
ok      cmd/internal/objabi     0.063s
ok      cmd/internal/src        0.093s
ok      cmd/internal/test2json  0.253s
ok      cmd/link        6.285s
ok      cmd/link/internal/ld    24.147s
ok      cmd/link/internal/sym   0.887s
ok      cmd/nm  7.678s
ok      cmd/objdump     2.772s
ok      cmd/pack        3.256s
ok      cmd/trace       0.449s
ok      cmd/vendor/github.com/google/pprof/internal/binutils    0.479s
ok      cmd/vendor/github.com/google/pprof/internal/driver      6.103s
ok      cmd/vendor/github.com/google/pprof/internal/elfexec     0.079s
ok      cmd/vendor/github.com/google/pprof/internal/graph       0.455s
ok      cmd/vendor/github.com/google/pprof/internal/measurement 0.066s
ok      cmd/vendor/github.com/google/pprof/internal/report      0.154s
ok      cmd/vendor/github.com/google/pprof/internal/symbolizer  0.096s
ok      cmd/vendor/github.com/google/pprof/internal/symbolz     0.078s
ok      cmd/vendor/github.com/google/pprof/profile      0.527s
ok      cmd/vendor/github.com/ianlancetaylor/demangle   0.109s
ok      cmd/vendor/golang.org/x/arch/arm/armasm 0.424s
ok      cmd/vendor/golang.org/x/arch/arm64/arm64asm     0.537s
ok      cmd/vendor/golang.org/x/arch/ppc64/ppc64asm     0.155s
ok      cmd/vendor/golang.org/x/arch/x86/x86asm 0.239s
ok      cmd/vendor/golang.org/x/crypto/ssh/terminal     0.174s
ok      cmd/vendor/golang.org/x/sys/windows     0.334s
ok      cmd/vendor/golang.org/x/sys/windows/registry    0.199s
ok      cmd/vendor/golang.org/x/sys/windows/svc 0.316s
ok      cmd/vendor/golang.org/x/sys/windows/svc/eventlog        0.089s
ok      cmd/vendor/golang.org/x/sys/windows/svc/mgr     0.432s
ok      cmd/vet 6.392s
ok      cmd/vet/internal/cfg    0.102s
2018/12/16 15:55:18 Failed: exit status 1

Auch das Setzen von GOTESTMSVC und GOVSVARSPATH könnte für Leute funktionieren, die all.bat ausführen. Aber was werden andere Benutzer Ihrer Änderung tun, wenn sie MSVC für Cgo verwenden müssen? Was ist Ihr Plan dafür?

Alex

@alexbrainman
Ich bin mir nicht sicher, was los ist. Dieser Test schlägt für mich auf Master fehl

> git status
On branch master
Your branch is up to date with 'origin/master'

> cd src\cmd\go
> go test .\help_test.go
--- FAIL: TestDocsUpToDate (0.00s)
    help_test.go:26: alldocs.go is not up to date; run mkalldocs.sh to regenerate it

In help.go https://github.com/golang/go/blob/c040786f37246f40ae29402fbdb6e97031a21713/src/cmd/go/internal/help/help.go#L37
es iteriert durch base.Go.Commands. Welches wird in main.go initialisiert https://github.com/golang/go/blob/c040786f37246f40ae29402fbdb6e97031a21713/src/cmd/go/main.go#L43
aber ich bin mir nicht sicher, wie diese init-Funktion jemals in einer ausführbaren Testdatei aufgerufen werden würde, daher habe ich keine Ahnung, wie Master derzeit Tests besteht, da ich denke, dass dies auf der ganzen Linie fehlschlagen sollte.


Auch das Setzen von GOTESTMSVC und GOVSVARSPATH könnte für Leute funktionieren, die all.bat ausführen. Aber was werden andere Benutzer Ihrer Änderung tun, wenn sie MSVC für Cgo verwenden müssen? Was ist Ihr Plan dafür?

Also in einer Situation, in der Sie nur Cgo-Code mit MSVC erstellen möchten

call vsvars64.bat
set CC_FOR_CGO=gcc
set CC=cl.exe
go build

sollte alles sein was du brauchst denke ich

Ich bin mir nicht sicher, wie diese init-Funktion jemals in einer ausführbaren Testdatei aufgerufen werden würde, daher habe ich keine Ahnung, wie Master derzeit Tests besteht, da ich denke, dass dies auf der ganzen Linie fehlschlagen sollte.

Wenn go test mit einer Datei in cmd/go verwendet wird, erstellt das go-Tool das cmd/go-Paket und erstellt dann die Tests, generiert den Testtreiber, erstellt diesen und verknüpft alles zu einem neuen Hauptpaket. Dies geschieht, obwohl cmd/go selbst ein Hauptpaket ist. Das heißt, das Hauptpaket in cmd/go/*.go wird zu Testzwecken als Nicht-Hauptpaket behandelt. Dadurch können Tests gegebenenfalls im Hauptpaket definierte Funktionen aufrufen.

Entschuldigung, ich antworte langsam. Aber ich hatte keine Zeit, mir das noch einmal anzusehen.

Ich bin mir nicht sicher, was los ist. Dieser Test schlägt für mich auf Master fehl

Master habe ich nicht verwendet. Ich habe Ihr e56d52f66b95b87001867a2487a11bd961f40d4d-Commit verwendet. Haben Sie all.bat nicht für diesen Commit ausgeführt, bevor Sie ihn zur Überprüfung gesendet haben? War all.bat erfolgreich? Können Sie versuchen, all.bat auf diesem Commit erneut auszuführen, um zu sehen, ob es etwas mit meiner Systemkonfiguration zu tun hat. Dankeschön.

Also in einer Situation, in der Sie nur Cgo-Code mit MSVC erstellen möchten

call vsvars64.bat
set CC_FOR_CGO=gcc
set CC=cl.exe
go build

sollte alles sein was du brauchst denke ich

2 Umgebungsvariablen ist für den durchschnittlichen Benutzer wahrscheinlich zu kompliziert. Und CC_FOR_CGO=gcc sieht für mich seltsam aus - warum verwenden wir gcc, um Code mit MSVC zu erstellen?

Alex

@alexbrainman

Master habe ich nicht verwendet. Ich habe Ihr e56d52f66b95b87001867a2487a11bd961f40d4d-Commit verwendet. Haben Sie all.bat nicht für diesen Commit ausgeführt, bevor Sie ihn zur Überprüfung gesendet haben? War all.bat erfolgreich? Können Sie versuchen, all.bat auf diesem Commit erneut auszuführen, um zu sehen, ob es etwas mit meiner Systemkonfiguration zu tun hat. Dankeschön.

Ich denke, es lag an meiner Systemkonfiguration, die mir beim Ausführen der Tests seltsame Ergebnisse lieferte. Ich glaube, ich habe das Problem behoben und einige Updates für das Änderungsset verschoben.

2 Umgebungsvariablen ist für den durchschnittlichen Benutzer wahrscheinlich zu kompliziert. Und CC_FOR_CGO=gcc sieht für mich seltsam aus - warum verwenden wir gcc, um Code mit MSVC zu erstellen?

Es sollte eigentlich wahrscheinlich CC_FOR_CGO=gcc.exe sein, mein Fehler. Aber um Ihre Frage zu beantworten; von gerit:

PS1, Zeile 1324:
cgo benötigt weiterhin gcc für die Typanalyse. Wenn CC auf einen MSVC-Compiler gesetzt ist, benötigt cgo ein Mittel zum Aufrufen von GCC, das von CC_FOR_CGO bereitgestellt wird. Leider hat die MSVC-Toolchain keinen Mechanismus, um die gleichen Typinformationen bereitzustellen, die von gcc gesammelt werden. Theoretisch könnte ein go-spezifisches Tool erstellt werden, um die Typinformationen zu sammeln, die von cgo verwendet werden, aber das könnte den Rahmen sprengen und möglicherweise erheblichen Aufwand sein (ich habe persönlich noch nie etwas geschrieben, um eine statische Typanalyse von C/C++-Code durchzuführen).

Ich scheine auch etwas mit dem Cache zwischen den Läufen für GCC vs MSVC kaputt gemacht zu haben. Ich bin mir nicht sicher, warum einige Tests immer noch so wirken, als ob sie zwischengespeichert wären.

Ich glaube, ich habe das Problem behoben und einige Updates für das Änderungsset verschoben.

Dieses Setup https://github.com/golang/go/issues/20982#issuecomment -447618566 on

commit 5479fc9fe61fb998082fea5cb423314cc1afa649 (HEAD)
Author: Caleb Champlin <[email protected]>
Date:   Sat Sep 8 00:26:32 2018 -0600

    cmd/compile: add support for MSVC toolchain to go build

    Allows building with MSVC as an external compiler/linker.

    Setting CC=cl.exe inside an MSVC environment will automatically
    build cgo executables using MSVC as the external compiler and
    linker.

    For the builders setting the environment variable GOVSVARSPATH
    to the location of a msvsvars.bat file and setting the
    environment variable GOTESTMSVC=1 will automatically cause
    all.bat to run tests and compiler with both gcc and MSVC.

    Updates #20982

    Change-Id: I44be1f43aa0d53a688c595bc8336e0364b809ced

bringt mich weiter, scheitert aber immer noch mit

##### API check
+pkg go/build, type Context struct, CompilerType string
+pkg go/build, type Package struct, CgoMSCFLAGS []string
+pkg go/build, type Package struct, CgoMSCPPFLAGS []string
+pkg go/build, type Package struct, CgoMSCXXFLAGS []string
+pkg go/build, type Package struct, CgoMSLDFLAGS []string
+pkg os, method (*File) SyscallConn() (syscall.RawConn, error)

ALL TESTS PASSED

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

# runtime/cgo
msvc_libinit_windows.c
msvc_libinit_windows.c(133): error C2220: warning treated as error - no 'object' file generated
msvc_libinit_windows.c(133): warning C4710: 'int fprintf(FILE *const ,const char *const ,...)': function not inlined
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\ucrt\stdio.h(826): note: see declaration of 'fprintf'
go tool dist: FAILED: go install -gcflags=all= -ldflags=all= std cmd: exit status 2

c:\Users\Alex\dev\go\src>

Es sollte eigentlich wahrscheinlich CC_FOR_CGO=gcc.exe sein, mein Fehler.

Ich mache mir keine Sorgen um .exe in gcc.exe. Meine Probleme sind

  • Sie benötigen sowohl gcc- als auch MSVC-Tools, um MSVC zu verwenden (es wäre unseren Benutzern schwer zu erklären), aber ich verstehe, dass nichts dagegen unternommen werden kann;

  • Ich brauchte beide Umgebungsvariablen CC_FOR_CGO=gcc und CC=cl.exe gesetzt - vielleicht können wir einfach davon ausgehen, dass CC_FOR_CGO immer auf gcc gesetzt ist?

Aber um Ihre Frage zu beantworten; von gerit:

Danke für die Erklärung.

Alex

@alexbrainman

# runtime/cgo
msvc_libinit_windows.c
msvc_libinit_windows.c(133): error C2220: warning treated as error - no 'object' file generated
msvc_libinit_windows.c(133): warning C4710: 'int fprintf(FILE *const ,const char *const ,...)': function not inlined
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\ucrt\stdio.h(826): note: see declaration of 'fprintf'
go tool dist: FAILED: go install -gcflags=all= -ldflags=all= std cmd: exit status 2

Ich bin mir nicht sicher, wie diese Warnung auftreten würde, es sei denn, Sie haben irgendwie eine andere / alte Kopie von msvc_libinit_windows.c. Können Sie bestätigen, dass es diese Zeile enthält:

// src/runtime/cgo/msvc_libinit_windows.c
#pragma warning(disable:4668 4255 4710)

C4710 sollte für das stdio-Include unterdrückt werden. Ich sehe, dass Ihre Version von MSVC etwas anders ist als meine, was auch ein Schuldiger sein könnte. Ich bin mir jedoch nicht sicher, warum sie diese Unterdrückung in einer anderen Version aktiv ignorieren würden.

Sie können auch versuchen, eine Änderung vorzunehmen, um die Unterdrückung global einzubeziehen, egal was passiert

// src/cmd/go/internal/work/exec.go
// Line 2719
cgoMSCPPFLAGS = append(cgoMSCFLAGS, "/wd4668") // this should be cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4668") I'll fix the change set to correct
+cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4710") 

Ich brauchte beide Umgebungsvariablen CC_FOR_CGO=gcc und CC=cl.exe gesetzt - vielleicht können wir einfach davon ausgehen, dass CC_FOR_CGO immer auf gcc gesetzt ist?

Ich denke, dass gco prüft, ob gcc existiert, wenn CC_FOR_CGO nicht gesetzt ist, wäre in Ordnung. CC_FOR_CGO ist eher für Leute wie mich, die kein gcc im Weg haben. Mein CC_FOR_CGO sieht so aus CC_FOR_CGO=I:\Development\tmd-gcc\bingcc.exe. Wenn wir den Anwendungsfall nicht unterstützen möchten, dass GCC nicht auf dem Weg für MSVC-Builds ist, lassen Sie es mich wissen und ich kann die Umgebungsvariable alle loswerden.

Ich habe diese Version noch einmal probiert

commit 6741b7009d1894b5bf535d82ad46f4a379651670 (HEAD)
Author: Caleb Champlin <[email protected]>
Date:   Sat Sep 8 00:26:32 2018 -0600

    cmd/compile: add support for MSVC toolchain to go build

    Allows building with MSVC as an external compiler/linker.

    Setting CC=cl.exe inside an MSVC environment will automatically
    build cgo executables using MSVC as the external compiler and
    linker.

    For the builders setting the environment variable GOVSVARSPATH
    to the location of a msvsvars.bat file and setting the
    environment variable GOTESTMSVC=1 will automatically cause
    all.bat to run tests and compiler with both gcc and MSVC.

    Updates #20982

    Change-Id: I44be1f43aa0d53a688c595bc8336e0364b809ced

und ich bekomme den gleichen fehler

##### API check
+pkg go/build, type Context struct, CompilerType string
+pkg go/build, type Package struct, CgoMSCFLAGS []string
+pkg go/build, type Package struct, CgoMSCPPFLAGS []string
+pkg go/build, type Package struct, CgoMSCXXFLAGS []string
+pkg go/build, type Package struct, CgoMSLDFLAGS []string
+pkg os, method (*File) SyscallConn() (syscall.RawConn, error)

ALL TESTS PASSED

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

# runtime/cgo
msvc_libinit_windows.c
msvc_libinit_windows.c(133): error C2220: warning treated as error - no 'object' file generated
msvc_libinit_windows.c(133): warning C4710: 'int fprintf(FILE *const ,const char *const ,...)': function not inlined
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\ucrt\stdio.h(826): note: see declaration of 'fprintf'
go tool dist: FAILED: go install -gcflags=all= -ldflags=all= std cmd: exit status 2

c:\Users\Alex\dev\go\src>

Können Sie bestätigen, dass es diese Zeile enthält:

// src/runtime/cgo/msvc_libinit_windows.c
#pragma warning(disable:4668 4255 4710)

Dies ist der Anfang meiner Datei src/runtime/cgo/msvc_libinit_windows.c

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build cgo

#define WIN64_LEAN_AND_MEAN
// Suppress MSVC specific warnings.
// C4668: symbol' is not defined as a preprocessor macro, 
// replacing with '0' for 'directives'.
// C4255: function' : no function prototype given: converting '()' 
// to '(void)'.
// C4710: function' : function not inlined
#pragma warning(disable:4668 4255 4710)
#include <windows.h>
#include <process.h>
...

Sie können auch versuchen, eine Änderung vorzunehmen, um die Unterdrückung global einzubeziehen, egal was passiert

// src/cmd/go/internal/work/exec.go
// Line 2719
cgoMSCPPFLAGS = append(cgoMSCFLAGS, "/wd4668") // this should be cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4668") I'll fix the change set to correct
+cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4710") 

Ich habe diese Änderung vorgenommen:

c:\Users\Alex\dev\go\src>git diff
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 49d1d849f5..9fb442ab95 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -2717,6 +2717,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcMSCFLAGS, pc
        cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
        if cfg.BuildContext.CompilerType == "msvc" {
                cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4668")
+               cgoMSCFLAGS = append(cgoMSCFLAGS, "/wd4710")

                cgoMSCPPFLAGS = append(cgoMSCPPFLAGS, pcMSCFLAGS...)
                cgoMSCPPFLAGS = append(cgoMSCPPFLAGS, "/c")

c:\Users\Alex\dev\go\src>

aber ich sehe den gleichen fehler

##### API check
+pkg go/build, type Context struct, CompilerType string
+pkg go/build, type Package struct, CgoMSCFLAGS []string
+pkg go/build, type Package struct, CgoMSCPPFLAGS []string
+pkg go/build, type Package struct, CgoMSCXXFLAGS []string
+pkg go/build, type Package struct, CgoMSLDFLAGS []string
+pkg os, method (*File) SyscallConn() (syscall.RawConn, error)

ALL TESTS PASSED

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

# runtime/cgo
msvc_libinit_windows.c
msvc_libinit_windows.c(133): error C2220: warning treated as error - no 'object' file generated
msvc_libinit_windows.c(133): warning C4710: 'int fprintf(FILE *const ,const char *const ,...)': function not inlined
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\ucrt\stdio.h(826): note: see declaration of 'fprintf'
go tool dist: FAILED: go install -gcflags=all= -ldflags=all= std cmd: exit status 2

c:\Users\Alex\dev\go\src>

Alex

Ich habe gestern Abend versucht, dies zu reproduzieren, und es gelang mir nicht. Ich frage mich, ob Sie dies erleben: https://developercommunity.visualstudio.com/content/problem/35734/c-cannot-disable-specific-warnings-with-pragmas-wh.html

Ist es möglich, auf das neueste SDK und die Build-Tools zu aktualisieren? Ich verwende SDK 10.0.17763.0. und Version 15.9.28307.222 der Build-Tools/devenv

Ich versuche, eine Windows-DLL mit MSVC zu erstellen, aber es sieht so aus, als ob Go versucht, eine Warnung mit einer Nummer über 65535 (oder keiner Nummer) zu deaktivieren, wodurch MSVC beendet wird.

image

Nein. Werror ist eine GCC-Option, um jede Warnung als Fehler zu behandeln.

Für MSVC sollten Sie WX .

@pravic guter Punkt, wie würde ich das machen? Ich stelle es nicht ein, alles was ich tue ist:

set CC=cl.exe
go build -o next.dll .\main.go

@galich Leider kann ich nicht helfen, da ich die MSVC-Integration nicht verfolge.

Wo sind beispielsweise die Patches zu diesem Thread? Im Master oder woanders?

@pravic die Änderungen findet ihr hier: https://go-review.googlesource.com/c/go/+/133946/5

@mxplusb danke für den Link, mein spezielles Problem mit /Werror scheint dort gelöst zu sein.
Weißt du, wann dies zur Beta/Nightly/Stable kommt?

Ist es möglich, auf das neueste SDK und die Build-Tools zu aktualisieren? Ich verwende SDK 10.0.17763.0. und Version 15.9.28307.222 der Build-Tools/devenv

@cchamplin endlich habe ich es geschafft, meine MSVC zu aktualisieren. Ich habe jetzt

c:\Users\Alex\dev\go\src>%GOVSVARSPATH%
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

c:\Users\Alex\dev\go\src>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27030.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

c:\Users\Alex\dev\go\src>

Ich habe diese Version noch einmal probiert

commit 6741b7009d1894b5bf535d82ad46f4a379651670 (HEAD)
Author: Caleb Champlin <[email protected]>
Date:   Sat Sep 8 00:26:32 2018 -0600

    cmd/compile: add support for MSVC toolchain to go build

    Allows building with MSVC as an external compiler/linker.

    Setting CC=cl.exe inside an MSVC environment will automatically
    build cgo executables using MSVC as the external compiler and
    linker.

    For the builders setting the environment variable GOVSVARSPATH
    to the location of a msvsvars.bat file and setting the
    environment variable GOTESTMSVC=1 will automatically cause
    all.bat to run tests and compiler with both gcc and MSVC.

    Updates #20982

    Change-Id: I44be1f43aa0d53a688c595bc8336e0364b809ced

und all.bat wird erfolgreich abgeschlossen. Aber ich bekomme diese Warnungen.

##### ../misc/cgo/stdio

##### ../misc/cgo/life

##### ../misc/cgo/test
# _/c_/Users/Alex/dev/go/misc/cgo/test
issue28896.cgo2.c
.\issue28896.go(30): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'g1'
.\issue28896.go(36): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'f2'
# _/c_/Users/Alex/dev/go/misc/cgo/test
cthread_windows.c
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(37) : note: index 'i' range checked by comparison on this line
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : note: feeds call on this line
PASS
scatter = 00007FF670706000
hello from C
sqrt is: 0
ok      _/c_/Users/Alex/dev/go/misc/cgo/test    3.534s
# _/c_/Users/Alex/dev/go/misc/cgo/test
issue28896.cgo2.c
.\issue28896.go(30): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'g1'
.\issue28896.go(36): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'f2'
# _/c_/Users/Alex/dev/go/misc/cgo/test
cthread_windows.c
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(37) : note: index 'i' range checked by comparison on this line
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : note: feeds call on this line
PASS
scatter = 00007FF7DD026000
hello from C
sqrt is: 0
ok      _/c_/Users/Alex/dev/go/misc/cgo/test    3.229s
# _/c_/Users/Alex/dev/go/misc/cgo/test
issue28896.cgo2.c
.\issue28896.go(30): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'g1'
.\issue28896.go(36): warning C4820: '<anonymous-tag>': '4' bytes padding added after data member 'f2'
# _/c_/Users/Alex/dev/go/misc/cgo/test
cthread_windows.c
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(37) : note: index 'i' range checked by comparison on this line
c:\users\alex\dev\go\misc\cgo\test\cthread_windows.c(39) : note: feeds call on this line
PASS
scatter = 00007FF655CF6000
hello from C
sqrt is: 0
ok      _/c_/Users/Alex/dev/go/misc/cgo/test    3.172s

##### ../test/bench/go1
testing: warning: no tests to run
PASS
ok      _/c_/Users/Alex/dev/go/test/bench/go1   3.178s

##### ../test

##### API check
+pkg go/build, type Context struct, CompilerType string
+pkg go/build, type Package struct, CgoMSCFLAGS []string
+pkg go/build, type Package struct, CgoMSCPPFLAGS []string
+pkg go/build, type Package struct, CgoMSCXXFLAGS []string
+pkg go/build, type Package struct, CgoMSLDFLAGS []string
+pkg os, method (*File) SyscallConn() (syscall.RawConn, error)

ALL TESTS PASSED

---
Installed Go for windows/amd64 in c:\Users\Alex\dev\go
Installed commands in c:\Users\Alex\dev\go\bin
*** You need to add c:\Users\Alex\dev\go\bin to your PATH.

c:\Users\Alex\dev\go\src>

Außerdem ist mir aufgefallen, dass Sie alle Tests zweimal ausführen.

...
##### API check
+pkg go/build, type Context struct, CompilerType string
+pkg go/build, type Package struct, CgoMSCFLAGS []string
+pkg go/build, type Package struct, CgoMSCPPFLAGS []string
+pkg go/build, type Package struct, CgoMSCXXFLAGS []string
+pkg go/build, type Package struct, CgoMSLDFLAGS []string
+pkg os, method (*File) SyscallConn() (syscall.RawConn, error)

ALL TESTS PASSED

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'


##### Testing packages.
ok      archive/tar     0.256s
ok      archive/zip     2.070s
ok      bufio   (cached)
ok      bytes   1.624s
ok      compress/bzip2  (cached)
ok      compress/flate  1.067s
...

Wieso den?

Alex

@alexbrainman Die Warnungen können für diese Tests wahrscheinlich unterdrückt werden, insbesondere in diesem Fall die Gespensterwarnungen.

Für die Tests, die zweimal ausgeführt werden, wurde dies meiner Meinung nach für den Builder so gemacht, führen Sie die Tests einmal mit der gcc-Kompilierung durch und führen Sie sie dann erneut mit MSVC (sofern aktiviert) durch, um sicherzustellen, dass die Kompilierung mit beiden Toolchains funktioniert. Ich bin mir nicht sicher, was hier gewünscht wird, also kann ich es so ändern, dass wir die Tests nur mit MSVC ausführen, wenn all.bat mit aktiviertem MSVC aufgerufen wird. In diesem Fall gehe ich davon aus, dass zusätzliche Builder nur für MSVC hinzugefügt werden müssen, im Gegensatz zu einigen Buildern, die auch mit MSVC bauen?

Einverstanden, dass unter Windows ein Builder mit der MinGW-W64-Toolchain und ein anderer mit der MSVC-Toolchain ausgeführt werden muss, um beide Szenarien zu testen.

Ich glaube, es wurde für den Builder so gemacht, führen Sie die Tests einmal mit der gcc-Kompilierung durch und führen Sie sie dann erneut mit MSVC (wenn aktiviert) durch, um sicherzustellen, dass die Kompilierung mit beiden Toolchains funktioniert.

Ich stimme zu, dass dies das bevorzugte Verhalten sein sollte, sodass eine Garantie besteht, dass vorhandene Workloads nicht unterbrochen werden, wenn beide Toolchains vorhanden sind.

Die Warnungen können für diese Tests wahrscheinlich unterdrückt werden, insbesondere in diesem Fall die Gespensterwarnungen.

Der Befehl Go zeigt keine Warnungen an, daher sollten keine Warnungen angezeigt werden.

Außerdem ist mir aufgefallen, dass der Befehl go env keine CC_FOR_CGO-Variable anzeigt. Wenn CC_FOR_CGO die Funktionsweise von go build beeinflusst, sollte CC_FOR_CGO zusammen mit anderen angezeigt werden. Brauchen wir wirklich die Variable CC_FOR_CGO? Was sonst, aber CC_FOR_CGO=gcc kann es sein?

Für die Tests, die zweimal ausgeführt werden, wurde dies meiner Meinung nach für den Builder so gemacht, führen Sie die Tests einmal mit der gcc-Kompilierung durch und führen Sie sie dann erneut mit MSVC (sofern aktiviert) durch, um sicherzustellen, dass die Kompilierung mit beiden Toolchains funktioniert.

Viele Tests verwenden kein gcc. Es ist eine Zeitverschwendung von Menschen / Computern, wenn Pakettests ohne Grund zweimal ausgeführt werden. Wie Sie aus https://github.com/golang/go/issues/20982#issuecomment -480569880 archive/zip können, wurden Pakettests zweimal ausgeführt - ich sehe keine Notwendigkeit für einen zweiten Lauf.

Ich bin mir nicht sicher, wie ich das arrangieren soll, aber vielleicht sollten Sie Ihren Aufruf von go tool dist test in run.bat ersetzen, um nur eine Auswahl von Tests durchzuführen, die zum Testen von MSVC-Build erforderlich sind. Sehen Sie sich beispielsweise go tool dist test -h an, um zu erfahren, wie Sie nur bestimmte Tests auswählen können. @bradfitz vielleicht könnten wir ein Flag oder eine Umgebungsvariable erstellen, die den Befehl dist anweist, MSVC-spezifische Tests auszuführen.

Aber im Allgemeinen erstellt Ihr https://go-review.googlesource.com/c/go/+/133946/5 eine ausführbare Datei für mich. Zum Beispiel kann ich mit gcc ausführbare Dateien erstellen:

c:\Users\Alex\dev\src\issue\go\20982\hello>type *

hello.c


#include <stdio.h>

extern void hello()
{
    printf("Hello World from C");
}

hello.go


package main

/*
        extern void hello();
*/
import "C"
import "fmt"

func main() {
    fmt.Println("Hello from Go!")
        C.hello()
}

c:\Users\Alex\dev\src\issue\go\20982\hello>go build

c:\Users\Alex\dev\src\issue\go\20982\hello>hello
Hello from Go!
Hello World from C
c:\Users\Alex\dev\src\issue\go\20982\hello>

und dann kann ich eine ausführbare Datei mit MSVC erstellen

c:\Users\Alex\dev\src\issue\go\20982\hello>%GOVSVARSPATH%
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

c:\Users\Alex\dev\src\issue\go\20982\hello>set CC=cl

c:\Users\Alex\dev\src\issue\go\20982\hello>go build
# issue/go/20982/hello
hello.c
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\stdio.h(948): warning C4710: 'int printf(const char *const ,...)': function not inlined
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\stdio.h(948): note: see declaration of 'printf'

c:\Users\Alex\dev\src\issue\go\20982\hello>hello
Hello from Go!
Hello World from C
c:\Users\Alex\dev\src\issue\go\20982\hello>

Das Erstellen mit MSVC erfordert also, dass Benutzer eine MS-Batch-Datei ausführen, um alle Umgebungsvariablen festzulegen (siehe GOVSVARSPATH in meiner Ausgabe) - und das, nehme ich an, Standard und hat nichts mit Go zu tun. Und set CC=cl . Einfach genug.

Das einzige Problem, das ich bei diesem Ansatz sehe, ist, dass MSVC-Benutzer immer noch gcc installiert haben müssen. gcc wird von cmd/cgo verwendet, um alle C-Schnittstellen zu erkennen - dieser Teil wird nicht mit MSVC implementiert. Klingt ungewöhnlich für Leute, die nicht wissen, wie cmd/cgo funktioniert, ist aber so.

@ianlancetaylor und @bradfitz klingt das alles vernünftig, um dies voranzutreiben? Sollten wir versuchen, dies in go1.13 zur Verfügung zu stellen?

Builder, auf denen MSVC bereits installiert ist, können den gesamten neuen Code testen. Andere Builder überspringen die Tests einfach.

Alex

gcc wird von cmd/cgo verwendet, um alle C-Schnittstellen zu erkennen - dieser Teil wird nicht mit MSVC implementiert.

Wie kann das überwunden werden? Im Idealfall wäre es großartig, wenn keine Anforderung für gcc besteht, sondern nur MSVC.

Wie kann das überwunden werden?

Teile von cmd/cgo, die gcc verwenden, müssen umgeschrieben werden, um MSVC zu verwenden. Wenn es möglich ist.

Alex

Ich habe mich gefragt, ob diese Funktion näher an der Serienreife ist? Ich sehe, dass es für 1.13 markiert war und das gerade herauskam. Ich versuche, Python-Erweiterungen mit einem Go c-Archive-Build zu erstellen, der mit dem Erweiterungscode verknüpft ist, aber Python erfordert MSVC.

Ich weiß nicht, wie der Status dieses Problems ist. Es wurde von Release zu Release nach vorne getreten, also werde ich es auf ungeplant verschieben. Wenn es in 1.14 kommt, großartig.

Trotz der Doppel-Compiler-Anforderung würde ich mich freuen, wenn die aktuelle Implementierung es in die nächste Version schafft. Es macht es zumindest möglich, ausführbare Dateien/Bibliotheken mit MSVC zu kompilieren, was besser ist als nichts.

Trotz der Doppel-Compiler-Anforderung würde ich mich freuen, wenn die aktuelle Implementierung es in die nächste Version schafft.

Ich denke, das wäre eine gute "Beta"-Implementierung. Es würde es ermöglichen, Fehler auszuspülen und die Implementierung zu reifen. Was bleibt noch zu tun, bevor es einer ernsthaften Überprüfung unterzogen werden kann?

Aus meiner Sicht und woran ich mich erinnern kann, als ich mir das das letzte Mal angesehen habe (vor etwa 6 Monaten) gab es ungefähr ein Dutzend Bereinigungselemente, die für den Code-Review-Prozess abgeschlossen werden mussten. Zusätzliche Arbeit kann auch erforderlich sein, um einige Tests zu deduplizieren, die im Grunde mit sehr geringfügigen Änderungen kopiert wurden, um mit einer anderen Toolchain zu arbeiten. Außerdem müssen bestimmte msvc-Warnungen überprüft und deaktiviert werden.

Zu den wichtigsten noch offenen Fragen gehören:

Ohne gcc können wir keine Typanalyse durchführen, dafür gibt es keine einfache oder unmittelbare Lösung.

Finalisieren des Setups und wie alles für die Builder funktionieren wird.

Ich glaube, dass es in den letzten 6 Monaten einige ziemlich bedeutende Änderungen am Compiler und Linker gegeben hat, die die aktuelle Arbeit dafür stark beeinträchtigen können, aber ich konnte das nicht bestätigen. Aufgrund der Komplexität und der hohen Lernkurve beim Navigieren in Gos Compiler/Linker/Toolchain kann es einige Zeit dauern, bis ich mich ausreichend auf den neuesten Stand gebracht habe, um die Auswirkungen der Änderungen auf diese Arbeit abzuschätzen.

Es gibt keine Unterstützung für die komplexen numerischen Typen. MSCVs C lib ist einfach inkompatibel. Ich glaube, es gibt wahrscheinlich eine Möglichkeit, dies mit C++ zu simulieren, aber ich bin mir unsicher, vielleicht kann sich jemand von MS, der mit den MSVC-Toolketten vertraut ist, einschalten.

Leider haben mich das Leben und andere Projekte ziemlich stark daran gehindert, mehr Zeit dafür zu investieren, aber ich werde versuchen, in den kommenden Wochen etwas Zeit damit zu verbringen.

@manbearian Bei diesem Problem geht es darum, Golang MSVC-Unterstützung hinzuzufügen. An wen im MSVC-Team könnte man sich bei MSVC-Fragen wenden?

@kesmit13 und @mxplusb

Dies

https://go-review.googlesource.com/c/go/+/133946/5

ist @cchamplin der neueste Code, der funktioniert.

Meine aktuelle Sorge mit dem Code, dass es unklar ist, wie man ihn verwendet. Welchen Befehl führen Sie aus? Wie muss meine Umgebung eingerichtet werden?

Ich denke, der nächste Schritt besteht darin, dass jemand versucht, diesen Code zu verwenden und zu sehen, ob er ihn tatsächlich verwenden kann. Wenn es funktioniert, müssen die Schritte dokumentiert werden, damit auch andere den Code verwenden können. Vielleicht ist es zu kompliziert oder funktioniert nicht. Dann müssen wir den Code entsprechend anpassen.

Sobald wir mit dem aktuellen Status des Codes zufrieden sind, sollten wir ihn auf den Master umbasieren. Es wurden zu viele verschiedene Dateien geändert, sodass es nicht einfach sein wird, ein Rebase zu erstellen. Vielleicht könnten wir die Änderung anpassen, um weniger Änderungen vorzunehmen, damit es einfacher ist, ein Rebase zu machen.

Alex

@mxplusb @kesmit13 Die aktuelle Implementierung wurde gegen den Master umbasiert und ist hier zu finden: https://go-review.googlesource.com/c/go/+/133946/6

@alexbrainman

Meine aktuelle Sorge mit dem Code, dass es unklar ist, wie man ihn verwendet. Welchen Befehl führen Sie aus? Wie muss meine Umgebung eingerichtet werden?

Ich bin damit einverstanden, dass eine Dokumentation zur Verwendung hinzugefügt werden muss. Ich bin mir jedoch nicht ganz sicher, wo ich es hinstellen soll, lass es mich wissen, wenn du eine Idee hast. Idk, ob es unter die cmd/go-Dokumentation zum Erstellen/Ausführen über MSVC gehen sollte oder ob es unter der CGO-Dokumentation oder vielleicht ganz woanders leben sollte?

Viele Tests verwenden kein gcc. Es ist eine Zeitverschwendung von Menschen / Computern, wenn Pakettests ohne Grund zweimal ausgeführt werden. Wie Sie aus # 20982 (Kommentar) sehen können, wurden Archiv-/Zip-Pakettests zweimal ausgeführt - ich sehe keine Notwendigkeit für einen zweiten Lauf.

Ich bin mir nicht sicher, wie ich das arrangieren soll, aber vielleicht sollten Sie Ihren Call-of-Go-Tool-Dist-Test in run.bat ersetzen, um nur eine Auswahl von Tests durchzuführen, die zum Testen von MSVC-Build erforderlich sind. Sehen Sie sich zum Beispiel go tool dist test -h an, um zu erfahren, wie Sie nur bestimmte Tests auswählen können. @bradfitz vielleicht könnten wir ein Flag oder eine Umgebungsvariable erstellen, die den Befehl dist anweist, MSVC-spezifische Tests auszuführen.

Die Änderung enthält bereits eine Umgebungsvariable, die dist hinzugefügt wurde, um es wissen zu lassen, dass wir MSVC-Dinge "GO_TEST_TESTINGMSVC" machen, glaube ich. Ich bin mir nicht sicher, wie wir die durchzuführenden Tests auf Dinge filtern, die nur MSVC beeinflussen könnten, wenn wir nicht alle Tests zweimal ausführen. Möglicherweise nur auf CGO-bezogene Tests beschränkt, aber ich glaube, es gibt überall CGO-Tests und ich weiß nicht, ob dist einen Mechanismus hat, um diese herauszufiltern?

Ich bin mir jedoch nicht ganz sicher, wo ich es hinstellen soll, lass es mich wissen, wenn du eine Idee hast.

Ich denke, bevor Sie eine Dokumentation aktualisieren, sollten Sie hier nur beschreiben, wie Sie Cgo-Code mit MSVC erstellen. Für @mxplusb und @kesmit13, damit sie Ihre Änderungen ausprobieren können.

Um beispielsweise gcc zum Erstellen von Cgo-Code zu verwenden,

  1. passe meinen %PATH% an, um gcc.exe einzuschließen
  2. build Gehen Sie zuerst, indem Sie make.bat aus dem Verzeichnis %GOROOT%\src ausführen
  3. Verwenden Sie die Standardbefehle go build und go install

Wie mache ich dasselbe mit MSVC?

Ich bin mir nicht sicher, wie wir die durchzuführenden Tests auf Dinge filtern, die nur MSVC beeinflussen könnten, wenn wir nicht alle Tests zweimal ausführen. Möglicherweise nur auf CGO-bezogene Tests beschränkt, aber ich glaube, es gibt überall CGO-Tests und ich weiß nicht, ob dist einen Mechanismus hat, um diese herauszufiltern?

Ich würde mit %GOROOT%\misc\cgo anfangen. Jede Quelle, die Sie dort bauen können, sollten Sie bauen. Alles darüber liegt bei Ihnen.

Alex

@cchamplin Entschuldigung für die Verzögerungen, ich werde mein Bestes tun, um es diese Woche zu testen und Sie wissen zu lassen, wie es läuft.

Hallo, Leute, es tut mir leid, dass ich zu spät zur Party komme... Ich kann versuchen, Fragen zur MSVC-Funktionalität zu beantworten oder Sie an Leute weiterleiten, die dies können. Ich habe mir das Gespräch durchgelesen, aber leider bin ich mit go nicht vertraut genug, um die erforderliche GCC-Funktionalität zu verstehen, die in MSVC möglicherweise fehlt oder nicht.

Hallo Leute,
Wird diese Funktion in Go 1.14 veröffentlicht?
Falls freigegeben, teilen Sie bitte alle verfügbaren Dokumente mit, um sie zu verwenden.
Wenn noch nicht veröffentlicht, gibt es eine Idee, wann es veröffentlicht wird?
Warte sehnsüchtig auf die MSVC-Unterstützung.
Danke im Voraus :)

Hallo, niemand hat jemals auf meine Anfrage nach weiteren Informationen geantwortet, daher bin ich mir nicht sicher, was benötigt wird. Kann mich bitte jemand ausfüllen?

Leider weiß ich nicht, ob jemand aktiv an diesem Thema arbeitet.

Hallo, auf meine Anfrage nach weiteren Informationen hat noch nie jemand geantwortet, ...

Hallo @manbearian

Welche Anfrage ist das? Welche Information brauchst du?

Alex

Ich wurde früher in diesem Thread zur Information markiert, aber ich weiß nicht, wonach die Leute suchen und konnte nicht helfen. Wenn keine Hilfe benötigt wird, ist das großartig. Lass es mich einfach wissen.

Lass es mich einfach wissen.

@manbearian

Danke für dein Angebot. Ich weiß nicht, wer dich markiert hat. Wenn sie noch Hilfe brauchen, werden sie dich erneut markieren.

Alex

Wenn noch nicht veröffentlicht, gibt es eine Idee, wann es veröffentlicht wird?
Warte sehnsüchtig auf die MSVC-Unterstützung.

@dhinesherode91

Der Code ist da und vollständig; Ich glaube, das einzige, was dies wirklich zurückhält, sind die Leute, die die Änderungen testen und Feedback geben, damit sie dann ordnungsgemäß überprüft und genehmigt werden können. Ich zögere jedoch, die Änderungen auf den aktuellen Master zu übertragen. Ich habe es 5-6 Mal gemacht und es ist extrem zeitaufwendig, und dann bekomme ich keine Tests/Feedback. Wenn keine weiteren Parteien bereit sind, an diesem Test teilzunehmen, könnte das Problem tot sein.

Wenn keine weiteren Parteien bereit sind, an diesem Test teilzunehmen, könnte das Problem tot sein.

@cchamplin zählen Sie auf mich,

@cchamplin Schön zu hören, dass der Implementierungsteil abgeschlossen ist.
Ich bin daran interessiert, am Testteil teilzunehmen, aber ich bin ein Anfänger in GoLang und auch ein guter Anfänger in Windows-APIs (begann vor einigen Wochen). Ich hatte vor, mit der Windows-API in MS C++ zu arbeiten, da es anscheinend viele offizielle Ressourcen dafür gibt. Aber dann fing ich an, nach einer Sprache (für meine Systemprogrammierung) zu suchen, in der ich sie für meine Multiplattform-Systemprogrammierung verwenden konnte und bin von GoLang beeindruckt. Immer bereit für den Beitrag von meiner Seite und braucht dringend Anleitung.

@cchamplin, wenn Sie ein Rebase machen, werde ich versuchen, darauf aufzubauen. Ich würde gerne die mingw64-Anforderung aus einigen meiner Projekte bei der Arbeit fallen lassen. Meine Build-Tools sind alle für MSVC eingerichtet, sodass ich nichts anderes tun müsste, als Ihren Patch zu verwenden.

@cchamplin auch, ich habe deine CLs durchgesehen und keine für das cgo-Tool gefunden, also habe ich mit meinem eigenen Patch begonnen. Gibt es Vorarbeiten?

@ericlagergren

@cchamplin auch, ich habe deine CLs durchgesehen und keine für das cgo-Tool gefunden, also habe ich mit meinem eigenen Patch begonnen. Gibt es Vorarbeiten?

Ich bin mir nicht sicher, ob ich das verstehe. Unter https://go-review.googlesource.com/c/go/+/133946/6 berühren viele der zugehörigen Commits in gewisser Weise direkt den cgo-Teil von Go.

@ccahoon okay, ich muss sie verpasst haben. Wenn das cgo-Tool nicht aktualisiert worden wäre, würde ich das anbieten.

@ericlagergren

Ich würde gerne die mingw64-Anforderung aus einigen meiner Projekte bei der Arbeit fallen lassen

Nur zu deiner Information. Die

https://go-review.googlesource.com/c/go/+/133946/6

Veränderung braucht immer noch Mingw, um zu funktionieren. Sie müssen sowohl Mingw- als auch MSVC-Tools installiert haben, um die @cchamplin- Änderung zu verwenden.

Alex

@cchamplin , warum wird Mingw noch benötigt? Was wäre erforderlich, um diese Abhängigkeit zu beseitigen?

@alexbrainman Ich habe mich falsch ausgedrückt. Im Moment müssen wir MSYS2 (einschließlich mingw64) verwenden, da der Nicht-MSVC-Buildprozess Autotools erfordert. Dass Dropping wäre fantastisch. Aber auch, wie @cglong sagte, bin ich mir nicht sicher, warum dies auch mingw64 erfordern würde.

@ericlagergren @cglong CGO muss

@cchamplin gotcha, das habe ich mir gedacht. Ich kenne Bibliotheken von Drittanbietern wie libclang und cznic/cc. Aber leider ist libclang gigantisch und cznic/cc wurde nicht auf Windows oder macOS getestet. Bietet PDB nicht genügend Informationen?

CGO muss Typinformationen über den C-Code, mit dem es kompiliert wird, sammeln und verfügbar haben. GCC hat ein Flag, das Typdaten in einem bequem zu analysierenden Format ausgibt. MSVC verfügt meines Wissens nicht über die Funktionalität, die gleichen Informationen bereitzustellen.

Vielleicht kann @manbearian hier einige

Ich würde nicht sagen, dass GCC Ausgabetypdaten in einem speziellen Format ausgibt. Es gibt DWARF-Debugging-Daten aus, die für Debugger gedacht sind, und cgo liest diese Daten mit dem debug/dwarf-Paket. MSVC hat vermutlich auch ein Debug-Format. Wenn dieses Format irgendwo dokumentiert ist, könnten wir es mit cgo genauso lesen wie die DWARF-Daten.

@ianlancetaylor MSVC kann PDB-Dateien ausgeben. Siehe https://github.com/Microsoft/microsoft-pdb

FWIW, das Lesen der Debug-Ausgabe von MSVC ist das, worüber ich gesprochen habe, als ich das cgo-Tool in https://github.com/golang/go/issues/20982#issuecomment -648462003 erwähnt habe

Ich würde nicht sagen, dass GCC Ausgabetypdaten in einem speziellen Format ausgibt. Es gibt DWARF-Debugging-Daten aus, die für Debugger gedacht sind, und cgo liest diese Daten mit dem debug/dwarf-Paket. MSVC hat vermutlich auch ein Debug-Format. Wenn dieses Format irgendwo dokumentiert ist, könnten wir es mit cgo genauso lesen wie die DWARF-Daten.

@ericlagergren @ianlancetaylor
Wir brauchen also die DWARF-Daten, die einen großen Teil davon ausmachen. Theoretisch könnten wir jedoch die gleichen Informationen aus PDB-Daten gewinnen.

Worauf ich mich jedoch speziell bezog, waren nicht nur die DWARF-Daten, die GCC erzeugt, sondern die Ausgabe von gcc -E -dM, die alle #defines ausgibt, nachdem die Vorverarbeitung stattgefunden hat. Es ist möglich, dass PDB allein die gleichen Informationen liefern könnte ... was ich skeptisch bin, ist, ob wir MSVC dazu zwingen könnten, Debug-Informationen/Typ-Informationen in irgendeiner Form zu löschen, ohne dass es tatsächlich kompiliert werden muss der Code. Im Moment macht CGO genau das mit GCC.

Aus dem Speicher sollte /EP /d1PP etwas ähnliches wie -E -dM ausgeben.

Aus dem Speicher sollte /EP /d1PP etwas ähnliches wie -E -dM ausgeben.

Wenn ja, wäre das ausgezeichnet, ich gehe davon aus, dass /d1PP ein undokumentiertes Flag ist? Ich habe es noch nie gesehen. Das würde nur das Abrufen von äquivalenten Typinformationen im Voraus überlassen.

@cchamplin ja, es ist undokumentiert. Viele der /dXXX-Flags sind anscheinend. Die Verwendung undokumentierter Flags ist bedauerlich, aber (IMO) scheint es zumindest unter Windows keine so schlimme Sünde zu sein. Ich habe gesehen, wie MSVC STL-Entwickler in einem Reddit-Thread darüber gesprochen haben, aber es ist auch überall im Internet zu finden.

Kann mir jemand eine kurze Zusammenfassung zum aktuellen Stand des MSVC-Supports geben? Ich verstehe nicht viel von all diesem Low-Level-Compiler-Zeug. Es ist nur so, dass ich eine go-Bibliothek habe, die ich aus C#/UWP verwenden möchte - und die funktioniert bereits mit go build und dem buildmode c-shared. ABER: Diese App wird nie vom Windows Store akzeptiert, da die generierte DLL von go einige Compiler/Linker-Flags vermisst, die (ich nehme an) nur von der MSVC-Toolchain gesetzt werden können.

Also: wie könnte ich das hier testen? Jeder Rat wird geschätzt! Dankeschön!

diese App wird nie vom Windows Store akzeptiert, da die generierte DLL von go einige Compiler/Linker-Flags vermisst, die (ich nehme an) nur von der MSVC-Toolchain gesetzt werden können.

@TopperDEL sagt Ihnen der Windows Store, welche Compiler-Flags fehlen? Wenn mingw-64 sie unterstützt, können Sie beim Erstellen der DLL immer -extldflags mit den richtigen Flags verwenden.

@qmuntal Ja, das tun sie:
"Wenden Sie die erforderlichen Linker-Optionen an – SAFESEH, DYNAMICBASE, NXCOMPAT und APPCONTAINER – wenn Sie die App verknüpfen."

Ich habe es schon versucht
go build -ldflags="-s -w '-extldflags=-Wl,--dynamicbase,--high-entropy-va'" -o storj_uplink.dll -buildmode c-shared

An der Store-Einreichung änderte das aber nichts. Und nach meinem Verständnis ist SAFESEH zumindest eine MSVC-spezifische Sache, oder?

"Wenden Sie die erforderlichen Linker-Optionen an – SAFESEH, DYNAMICBASE, NXCOMPAT und APPCONTAINER – wenn Sie die App verknüpfen."

Ich kenne keine einfache Möglichkeit, SAFESEH- oder APPCONTAINER-Flags in Mingw-w64 zu aktivieren, vielleicht kann Ihnen dieses Projekt https://github.com/status-im/mingw-windows10-uwp eine Anleitung geben.

Auf der anderen Seite sind DYNAMICBASE und NXCOMPAT standardmäßig in go 1.16 aktiviert (siehe #41421), können aber wie erwähnt bereits mit -extldflags werden, tatsächlich mache ich dies für einige Projekte.

@qmuntal Danke! Also sollten zumindest meine obigen extldflags richtig sein?
Ich werde mir das mingw für Windows 10-uwp ansehen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen