Можно определить путь во время компиляции и использовать в коде go [duplicate]

__foo__: это просто соглашение, способ использования системы Python для имен, которые не будут конфликтовать с именами пользователей.

_foo: это просто соглашение, способ для программиста указать, что переменная является частной (что бы это ни значило в Python).

__foo: это имеет реальное значение: интерпретатор заменяет это имя на _classname__foo, чтобы гарантировать, что имя не будет перекрываться с похожим именем в другом классе.

В мире Python нет другой формы подчеркивания.

Нет никакой разницы между классом, переменной, глобальным и т. д. эти соглашения.

129
задан Sebastián Grignoli 6 July 2012 в 01:52
поделиться

5 ответов

Коммандер Go ( go tool link ) имеет возможность установить значение неинициализированной строковой переменной:

-X importpath.name=value
    Set the value of the string variable in importpath named name to value.
    Note that before Go 1.5 this option took two separate arguments.
    Now it takes one argument split on the first = sign.

Как часть процесса сборки, вы можете с помощью этого используйте переменную строки версии. Вы можете передать это через инструмент go, используя -ldflags. Например, с учетом следующего исходного файла:

package main

import "fmt"

var xyz string

func main() {
    fmt.Println(xyz)
}

Затем:

$ go run -ldflags "-X main.xyz=abc" main.go
abc

Чтобы установить main.minversion на дату и время сборки при создании:

go build -ldflags "-X main.minversion=`date -u +.%Y%m%d.%H%M%S`" service.go

Если вы скомпилируете без инициализации main.minversion таким образом, он будет содержать пустую строку.

252
ответ дан Matt 20 August 2018 в 22:04
поделиться
  • 1
    Будет ли это значение сохранено в двоичном формате, если я использую go bouild вместо go run? – Sebastián Grignoli 6 July 2012 в 05:17
  • 2
    go build -ldflags "-X main.minversion `date -u +.%Y%m%d%.H%M%S`" service.go – Sebastián Grignoli 6 July 2012 в 05:49
  • 3
    goxc делает это для вас :) по умолчанию он компилируется с -ldflags & quot; -Xmain.VERSION x.x.x -Xmain.BUILD_DATE CurrentDateInISO8601 & quot ;, но вы можете настроить эти имена переменных, если хотите. См. github.com/laher/goxc ... (отказ от ответственности: я написал goxc) – laher 14 November 2013 в 22:51
  • 4
    рабочий пример с новым синтаксисом 1.5 для добавления переменной времени сборки go build -ldflags "-X 'main.buildtime=$(date -u '+%Y-%m-%d %H:%M:%S')'" – xorpaul 26 October 2015 в 17:17
  • 5
    обратите внимание, что требуется полное имя пакета. go build -ldflags "-X pkg.version=123" не будет работать, пока go build -ldflags "-X path/to/pkg.version=123" работает должным образом. Надеюсь, поможет. – csyangchen 25 November 2015 в 10:04

использовать multi -ldflags:

$ go build -ldflags "-X name1=value1 -X name2=value2" -o path/to/output
6
ответ дан Kimia Zhu 20 August 2018 в 22:04
поделиться

Кроме того, я хотел бы разместить небольшой пример того, как использовать git и makefile:

--- Makefile ----

# This how we want to name the binary output
BINARY=gomake

# These are the values we want to pass for VERSION and BUILD
# git tag 1.0.1
# git commit -am "One more change after the tags"
VERSION=`git describe --tags`
BUILD=`date +%FT%T%z`

# Setup the -ldflags option for go build here, interpolate the variable values
LDFLAGS_f1=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f1"
LDFLAGS_f2=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f2"

# Builds the project
build:
    go build ${LDFLAGS_f1} -o ${BINARY}_f1
    go build ${LDFLAGS_f2} -o ${BINARY}_f2

# Installs our project: copies binaries
install:
    go install ${LDFLAGS_f1}

# Cleans our project: deletes binaries
clean:
    if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi

.PHONY: clean install

Файл make создаст два исполняемых файла. Один из них выполняет функцию один, другой будет выполнять функцию 2 в качестве основной записи:

package main

import (
        "fmt"
)

var (

        Version string
        Build   string
        Entry   string

        funcs = map[string]func() {
                "f1":functionOne,"f2":functionTwo,
        }

)

func functionOne() {
    fmt.Println("This is function one")
}

func functionTwo() {
    fmt.Println("This is function two")
}

func main() {

        fmt.Println("Version: ", Version)
        fmt.Println("Build Time: ", Build)

    funcs[Entry]()

}

Затем просто запустите:

make

Вы получите:

mab@h2470988:~/projects/go/gomake/3/gomake$ ls -al
total 2020
drwxrwxr-x 3 mab mab    4096 Sep  7 22:41 .
drwxrwxr-x 3 mab mab    4096 Aug 16 10:00 ..
drwxrwxr-x 8 mab mab    4096 Aug 17 16:40 .git
-rwxrwxr-x 1 mab mab 1023488 Sep  7 22:41 gomake_f1
-rwxrwxr-x 1 mab mab 1023488 Sep  7 22:41 gomake_f2
-rw-rw-r-- 1 mab mab     399 Aug 16 10:21 main.go
-rw-rw-r-- 1 mab mab     810 Sep  7 22:41 Makefile
mab@h2470988:~/projects/go/gomake/3/gomake$ ./gomake_f1
Version:  1.0.1-1-gfb51187
Build Time:  2016-09-07T22:41:38+0200
This is function one
mab@h2470988:~/projects/go/gomake/3/gomake$ ./gomake_f2
Version:  1.0.1-1-gfb51187
Build Time:  2016-09-07T22:41:39+0200
This is function two
13
ответ дан Maciej A. Bednarz 20 August 2018 в 22:04
поделиться
  • 1
    Или проще: просто сделайте два основных в двух разных каталогах. Это решение, похоже, серьезно переработано. – dolmen 27 October 2017 в 16:09

В ОС Windows с учетом программы ниже

package main

import "fmt"

var (
    version string
    date    string
)

func main() {
    fmt.Printf("version=%s, date=%s", version, date)
}

Вы можете создавать с использованием

go build -ldflags "-X main.version=0.0.1 -X main.date=%date:~10,4%-%date:~4,2%-%date:~7,2%T%time:~0,2%:%time:~3,2%:%time:~6,2%"

Формат даты предполагает, что ваша среда echo %date% - Fri 07/22/2016 и echo %time% 16:21:52.88

Тогда выход будет: version=0.0.1, date=2016-07-22T16:21:52

5
ответ дан ostati 20 August 2018 в 22:04
поделиться

У меня возникли проблемы с использованием параметра -ldflags при создании моего смешанного проекта приложения и библиотеки в командной строке, поэтому я решил использовать целевой файл Makefile для создания исходного файла Go, содержащего версию моего приложения и дату сборки:

BUILD_DATE := `date +%Y-%m-%d\ %H:%M`
VERSIONFILE := cmd/myapp/version.go

gensrc:
    rm -f $(VERSIONFILE)
    @echo "package main" > $(VERSIONFILE)
    @echo "const (" >> $(VERSIONFILE)
    @echo "  VERSION = \"1.0\"" >> $(VERSIONFILE)
    @echo "  BUILD_DATE = \"$(BUILD_DATE)\"" >> $(VERSIONFILE)
    @echo ")" >> $(VERSIONFILE)

В моем методе init() я делаю это:

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "%s version %s\n", os.Args[0], VERSION)
    fmt.Fprintf(os.Stderr, "built %s\n", BUILD_DATE)
    fmt.Fprintln(os.Stderr, "usage:")
    flag.PrintDefaults()
}

Однако, если вы хотите увеличить число номеров сборки, а не дату сборки, вам, вероятно, потребуется создайте локальный файл, содержащий последний номер сборки. Ваш Makefile будет читать содержимое файла в переменной, увеличивать его, вставлять в файл version.go вместо даты и записывать новый номер сборки обратно в файл.

20
ответ дан pegli 20 August 2018 в 22:04
поделиться
  • 1
    Хорошее решение. Тем не менее, я думаю, что я нашел причину проблем -ldflags. Если файл, содержащий переменную, обновляемую с помощью -X, не затрагивается, компиляция не запускается, и у вас есть старая версия в двоичном формате. Моим решением было прикоснуться к маленькому файлу, содержащему только переменную, сбрасываемую с помощью -ldflags & quot; -X ... & quot; – Wojciech Kaczmarek 21 June 2017 в 23:23
Другие вопросы по тегам:

Похожие вопросы: