Heim  >  Artikel  >  Backend-Entwicklung  >  go build funktioniert nicht, wenn es mit Workspace verwendet wird

go build funktioniert nicht, wenn es mit Workspace verwendet wird

王林
王林nach vorne
2024-02-08 21:06:181208Durchsuche

与工作区一起使用时 go build 不起作用

php-Editor Banana möchte Ihnen ein häufiges Problem vorstellen, nämlich dass der Befehl „go build“ bei Verwendung des Arbeitsbereichs nicht ordnungsgemäß funktioniert. Dieses Problem kann Entwickler verwirren, da der Arbeitsbereich ein sehr wichtiges Konzept in der Go-Sprache ist und die Unfähigkeit, den Go-Build-Befehl ordnungsgemäß zu verwenden, den Entwicklungsprozess ernsthaft beeinträchtigen wird. Im folgenden Artikel werden wir die Ursache dieses Problems eingehend analysieren und Lösungen bereitstellen, die Entwicklern helfen, dieses Problem erfolgreich zu lösen.

Frageninhalt

Das Folgende ist die Struktur meines Golang-Codes,

├── go.work
├── moda
│   ├── go.mod
│   └── main.go
├── go.mod
└── modb
    └── main.go

Das Problem ist, dass ich nur Binärdateien für ein einzelnes Modul erstellen kann. Beim Erstellen anderer Module funktioniert es nur, wenn ich die anderen Module in go.work auskommentiere

Mein go.work ist wie folgt,

go 1.19
use (
    ./moda
    .
)

Wenn ich also go.work oben verwende, um wie folgt zu erstellen, funktioniert es einwandfrei,

go build -o test-binary -modfile ./moda/go.mod ./moda

Aber wenn ich versuche, für mein anderes Modul (d. h. modb/) zu bauen, wie unten gezeigt,

go build -o test-binary1 -modfile ./go.mod ./modb

Ich habe den folgenden Fehler festgestellt:

directory modb is contained in a module that is not one of the workspace modules listed in go.work. you can add the module to the workspace using go work use .

Ich habe es mit go 工作 use versucht, aber ich stehe immer noch vor dem gleichen Problem. Kann mir jemand helfen, dieses Problem zu lösen?

Edit 1:

Ich hatte ein Projekt, das mehrere go.mod-Dateien erforderte, um die Abhängigkeiten von Haupt- und Untermodulen zu trennen, und da begann ich, etwas über Go-Arbeitsbereiche zu lernen, die sehr gut zu meinem Anwendungsfall passten.

Meine Projektstruktur ist die gleiche wie oben erwähnt,

├── go.work
├── submodule
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── mainmodule
    └── main.go
├── go.mod
├── go.sum

Wenn Sie nun die ausführbare Datei für ein Submodul erstellen, funktioniert go build einwandfrei, aber wenn Sie die ausführbare Datei für das Hauptmodul erstellen, werden die in submodule/go.mod vorhandenen Importe auch zur ausführbaren Datei des Hauptmoduls hinzugefügt. Ich habe das auch mit go build -n verifiziert.

Um das Hinzufügen von Submodulimporten zur ausführbaren Datei des Hauptmoduls zu vermeiden, habe ich -modfile verwendet, aber damit kann ich nur die ausführbare Datei für das Submodul und nicht für das Hauptmodul erstellen.

Github-Quellcode

ps: Obwohl ich Beispielcode in Github hinzugefügt habe, kann ich das gleiche Problem nicht reproduzieren (Untermodulimporte werden zum Hauptmodul hinzugefügt). Ich bin mir nicht sicher, ob es an den von mir verwendeten Importen liegt


Richtige Antwort


Nachher Bei der Diskussion mit @arigatomanga haben wir herausgefunden, dass die Verwirrung durch die Minimum Version Selection (mvs) im Arbeitsbereich verursacht wird. Ein Arbeitsbereich ist eine Sammlung von Modulen auf der Festplatte, die als Hauptmodul verwendet wird, wenn Minimum Version Selection (mvs) (Reference) ausgeführt wird. Dank mvs können Module, die mit aktiviertem Arbeitsbereichsmodus erstellt wurden, andere abhängige Module verwenden als Module, die mit deaktiviertem Arbeitsbereichsmodus erstellt wurden.

Dies ist das dokumentierte Verhalten des Arbeitsbereichs und es gibt derzeit kein Problem.

Update: Nachfolgend finden Sie die ursprüngliche Antwort, wobei der Schwerpunkt auf der -modfile-Flagge liegt. Im Arbeitsbereichsmodus in go1.21 wird dieses Flag abgelehnt.

Im Go-Tool ist ein Fehler aufgetreten. Ich habe dieses Problem gerade hier gemeldet.

Die Fehlermeldung in go1.20 ist anders und immer noch irreführend:

go: module example.com/m1 appears multiple times in workspace

Der Unterschied wurde durch Commit eingeführt cmd/go/internal/modload: Beim Duplizieren von Modulpfaden zwischen Modulen in go.work wurde ein Fehler zurückgegeben, aber die Grundursache ist dieselbe: Im Arbeitsbereichsmodus wurde das -modfile-Flag nicht behoben .

Update: Der folgende Abschnitt ist derzeit nicht relevant. Bevor wir verstehen, was MVC ist, ist der Versuch, MVS mit der Flagge -modfile zu unterdrücken, ein gescheiterter Versuch.

Im Problembericht habe ich vorgeschlagen, die -modfile-Flagge im Arbeitsbereichsmodus zu blockieren. Aber Sie haben in den Kommentaren gesagt, dass Sie diese Flagge brauchen.

Der Grund für die Verwendung von -modfile 的原因是如果我为 ./src 构建二进制文件,即使在 ./moda 中存在的模块也会作为 ./src ist, dass, wenn ich eine Binärdatei für ./src erstelle, sogar die in ./moda vorhandenen Module als ./src code> wird als Teil der Binärdatei heruntergeladen und geladen, obwohl sie nicht enthalten sein sollten

Aber laut der cmd/go-Dokumentation :

-modfile-Datei

Lesen (und möglicherweise schreiben) Sie im modulbewussten Modus alternative go.mod Datei anstelle einer Datei im Modulstammverzeichnis. Eine Person mit Namen „go.mod“ muss noch vorhanden sein, um das Modul-Root zu ermitteln Verzeichnis, aber auf das Verzeichnis wurde nicht zugegriffen. Wenn -modfile angegeben ist, Verwendet auch eine alternative go.sum-Datei: Ihr Pfad wird von abgeleitet -modfile-Flag, indem die Erweiterung „.mod“ gekürzt und „.sum“ angehängt wird.

Das Flag

-modfile 标志用于替换模块根目录中的 go.mod wird verwendet, um die Datei go.mod im Modulstammverzeichnis zu ersetzen. Aber in Ihrem Beispiel haben Sie dieselbe Datei angegeben wie im Modulstammverzeichnis. Also ich verstehe es nicht ganz. Können Sie Ihre Frage aktualisieren, um diesen Teil näher zu erläutern? Demo ist besetzt!

Das obige ist der detaillierte Inhalt vongo build funktioniert nicht, wenn es mit Workspace verwendet wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen