-1

I have a golang code on Linux VM which I am remotely debugging using VS Code. Below is my folder structure

MainFolder  
|__Config  
|__Other folders 
Other Files

When I run the code using VS debugger, it runs properly and my code is able to find the path to files. But when I use the terminal to the code (I have workspace configured and need other project to run, and one project to debug) using go run ./folder, it gives some path like /tmp/go-build2342342342/b001/ when absolute path is populated. Any idea why it works this way and how to make the behavior consistent for properly getting the path?

Below is the code converting relative path to absolute

dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
    log.Fatal(err)
}
var path = filepath.Join(dir, relPath)
absPath, err := filepath.Abs(path)
Chaitanya Gadkari
  • 2,669
  • 4
  • 30
  • 54
  • 1
    Provide the folder as an explicite argument to your executable and do not use go run. – Volker Mar 17 '20 at 17:08
  • @Volker I am sorry but I am not exactly getting what you are trying to say. I can not start debug on another project when one is running, how should I run the other one simultaneously? You mean build and then execute using the compiled one? Yeah maybe that makes more sense – Chaitanya Gadkari Mar 17 '20 at 17:50
  • Amd I still would like to understand how that run path is set..... Is go run not recommneded at any point? – Chaitanya Gadkari Mar 17 '20 at 17:56
  • `go run` is **not** the way to build and execute a binary written in Go! The correct way is `go build` and executing the generated binary. (`go run` is used to run single-file simple helper scripts, it is **unsuitable** for any project consisting of more than one file!) – Volker Mar 17 '20 at 20:13
  • Go programs cannot reliably access their source code folder structure, really, you cannot, there are no tricks that work and your os.Args[0]-stuff doesn't work either. You **must** add a flag and use that as the path. There are several similiar questions on SO discussing this. – Volker Mar 17 '20 at 20:15
  • @Volker, `go run` is fine for binaries that span multiple files (and even multiple modules or packages). – bcmills Mar 19 '20 at 02:09
  • @bcmills It works, but it it unsuitable: It is halfway safe to use if you specify a package to run, but `go run`'s ability to be invoked with a list of _files_ is a loaded footgun: You have to supply the arguments in their proper _order_ (and offloading that to the shell with simple *.go doesn't work if *_test.go files are present), you have to select the files to run manually, e.g. the *_darwin.go files on OSX so `go run` is not a portable command. Empirical fact: `go run` with file arguments leads to problems much more often than go build. – Volker Mar 19 '20 at 07:42
  • @bcmills You are right that this is not per se a problem of `go run`. It is `go run`'s list-of-files-as-argument mode that leads to problems. To me it seems as if a lot of novices find `go run main.go` convenient, a lot of tutorials recommend this and once your project has three source code files and one test it gets hairy and error prone: `go run *.go` complains about *_test.go files, the original `go run main.go` which was so convenient complains about undefined stuff and `go run main.go init.go global.go` executes init functions in different order. SO is full of that sort of problem. – Volker Mar 19 '20 at 07:50
  • Let me reword my warning: Use `go run` with packages only (import path or file system path). Do not use `go run` with several source code files as arguments. – Volker Mar 19 '20 at 07:53
  • @Volker package as in module we build? or one we use from the https://golang.org/pkg – Chaitanya Gadkari Mar 19 '20 at 09:59
  • I do not understand your question. Packages are a fundamental concept in go and they can be bundled in modules and the stdlib packages are documented on golang.org/pkg. There is no "or" here. – Volker Mar 19 '20 at 10:21
  • @Volker, the subtlety of `go run` with a list of file arguments is more-or-less irrelevant to this question. The OP was describing `go run` with a relative package path, not a list of source files. – bcmills Mar 19 '20 at 14:47

1 Answers1

0

Go binaries are compiled, even when run via go run. When you go run a package, os.Args[0] is set to the path of the compiled binary within the build cache, not the directory containing the source code for that binary.

To determine the path to source files, you must either pass the source location explicitly (as a flag or explicit argument), or invoke go run in a well-known directory and use os.Getwd to located it.

However, for run-time debugging information specifically, see the runtime and runtime/debug packages.

bcmills
  • 4,391
  • 24
  • 34