What's go's convention for specifying the equivolent of configure --prefix?

118 views
Skip to first unread message

hey...@gmail.com

unread,
Dec 1, 2022, 4:39:38 AM12/1/22
to golang-nuts
I'm writing a command line program in go, and it needs to access some predefined external files like /usr/lib/name/file. What would be a good way to allow specify the constant path in compile time?

I see two options:

1. go generate
2. -ldflags="-X 'main.Path=..."

Both seem to be flawed. For #1, the blog clearly stated that it's designed for package author, and not for clients (and go generate doesn't support passing arguments to //go:generate anyways). For #2, the path can't be a constant.

Is there a convention on how this problem should be solved or external paths should always be passed in as arguments in go?

Shulhan

unread,
Dec 1, 2022, 5:15:11 AM12/1/22
to hey...@gmail.com, golang-nuts
On Thu, 1 Dec 2022 01:39:38 -0800 (PST)
"hey...@gmail.com" <hey...@gmail.com> wrote:

> I'm writing a command line program in go, and it needs to access some
> predefined external files like /usr/lib/name/file. What would be a
> good way to allow specify the constant path in compile time?
>
> I see two options:
>
> 1. go generate
> 2. -ldflags="-X 'main.Path=..."
>
> Both seem to be flawed. For #1, the blog clearly stated that it's
> designed for package author, and not for clients (and go generate
> doesn't support passing arguments to //go:generate anyways). For #2,
> the path can't be a constant.
>

Whats wrong with const? And could not be global var then?

Glen Huang

unread,
Dec 1, 2022, 5:21:59 AM12/1/22
to Shulhan, golang-nuts

Whats wrong with const? 

Const is the ideal choice, but how do users of my program specify the path when they compile it?

And could not be global var then?

Using var loses the guarantee that the path won’t be changed, and the go compiler can no longer optimize as much I presume?

Nick

unread,
Dec 1, 2022, 5:32:58 AM12/1/22
to golan...@googlegroups.com
On Thu, Dec 01, 2022 at 06:21:37PM +0800, Glen Huang wrote:
> Const is the ideal choice, but how do users of my program specify the path when
> they compile it?

I don't think this is something for which there is a "canonical Go
way", so I'd say something like a tiny makefile that sets the path
with the PREFIX environment variable, passing that to -ldflags as
you suggested.

> Using var loses the guarantee that the path won’t be changed, and the go
> compiler can no longer optimize as much I presume?

I don't think it being var rather than const is going to be an
optimization bottleneck. But if it really was important, then you
could use a makefile to insert / overwrite a line with sed or
similar, keeping some sensible default working for users who
eschewed the makefile and just used 'go install' or whatever.

Shulhan

unread,
Dec 1, 2022, 6:48:01 AM12/1/22
to Glen Huang, golang-nuts
On Thu, 1 Dec 2022 18:21:37 +0800
Glen Huang <hey...@gmail.com> wrote:

> > Whats wrong with const?
>
> Const is the ideal choice, but how do users of my program specify the
> path when they compile it?
>

They can't, but in Go, I am leaning to prefer where user can set the
"prefix" when running the program rather than statically set when
compile time.
The const become default, when the prefix is not set from CLI or any
input.

Hervé "Kyle" MUTOMBO

unread,
Dec 1, 2022, 12:12:19 PM12/1/22
to hey...@gmail.com, golang-nuts
I'd use godotenv in this case. True, it will require a .env file with a path variable in it and true it won't be as having consts but it will do the job.

import (
    "os"
"github.com/joho/godotenv"
)
func init() {
    if os.Getenv("MODE") != "PROD" {
        godotenv.Load()
    }
}

// ...
// Then later
path := os.Getenv("MY_PATH")



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/e5029b93-a3d9-4256-ab1c-a83d3b35c579n%40googlegroups.com.

Brian Candler

unread,
Dec 1, 2022, 12:29:07 PM12/1/22
to golang-nuts
If you are happy for the compile-time data to be in a file, rather than supplied as flags to the build command, then
//go:embed
should do the trick.

Glen Huang

unread,
Dec 1, 2022, 11:35:50 PM12/1/22
to golang-nuts
@m.shulhan @hervinhioslash

Thanks for the suggestion. I agree that using a runtime mechanism like env vars or command line flag can solve this problem. But the path value is for internal use, it should be customized only by the system administrators or package managers who determine where to install things, but not by the users of the package. If the referenced file lives at /usr/lib/name/file, it makes no sense to ask users to point to another location.

So am I correct to assume that there currently exists no convention to specify a const path like this? Maybe I should just write a configure script that generate a go file containing the const paths? Is providing a configure script in a go project something frowned upon?

hey...@gmail.com

unread,
Dec 1, 2022, 11:42:46 PM12/1/22
to golang-nuts
@Nick @Brian

Somehow I missed your replies.

Using a Makefile makes sense.

And thanks for bringing embed to my attention. I never knew it exists. Sounds like it can solve my problem.

Thanks a lot.

Nick White

unread,
Dec 3, 2022, 6:50:00 AM12/3/22
to golan...@googlegroups.com
On Thu, Dec 01, 2022 at 08:42:46PM -0800, hey...@gmail.com wrote:
> Using a Makefile makes sense.
>
> And thanks for bringing embed to my attention. I never knew it exists. Sounds
> like it can solve my problem.

Yeah, embed is brilliant, I'm glad it can help you.

One thing I forgot to mention is build tags. If you only have a few
options of different things to embed / change, they're a great way
to specify them. Just have a few small different files containing a
line like '//go:build mytag', defining things as you need them, and
set the tags appropriately when you build / install with '-tags
mytag'. It's easier and nicer than replacing things with a makefile.
Reply all
Reply to author
Forward
0 new messages