Question regarding a very tricky build set up

100 views
Skip to first unread message

kevma...@gmail.com

unread,
Dec 21, 2019, 11:12:21 AM12/21/19
to golang-nuts
Let me explain my situation.

I'm making a website and uses some very advanced functionality. It includes a front-end wasm module, a daemon (written in GoLang), nginx configuration, some PHP, and some haml, and sass. I have written a makefile to build everything into 1) ELF binary (the daemon), 2) a wasm binary, 3) an 'ext' directory (which holds images and other large static files for the website) and 4) and PHAR archive (which holds all html and PHP). Needless to say, the makefile is very useful. The repository holding all of this looks like this:

daemon/
build
/
doc
/
etc
/
scripts
/
test
s/
wasm
/
website
/
makefile


As you can tell, all major component has its own directory and is neatly laid out.


This layout traditionally worked for other projects that utilized other languages such as C, C++, Javascript, and Python. However, with GoLang, its aggressive use of GOPATH causes an architectural problem I'm running into regarding the daemon and wasm. You see, both the daemon and wasm module are built using packages that are exclusive to their respective binaries. For instance, 

files in ~/projects/project1/

daemon
/
 
- main.go
 
- package1/
 
- package2/
wasm
/
 
- main.go
 
- package3/
 
- package4/

This would not be a problem, as the make file can appened GOPATH to include the packages in the respective components. Unfortunately, GOPATH requires a directory exactly named "src" to be present... thus makes the building impossible by traditional means. Thus I see only a few exact workarounds...

A) Renaming my "~/projects" folder to "~/src" making this possible:

import "project1/daemon/package1"

B) Adding "src" to each component:

daemon/
 
- src/
   
- package1/
   
- package2/

daemon
/src/main.go:
import "package1"


C) Using symlinks 

daemon/
 
- main.go
 
- package1/
 
- package2/
 
- src -> ./


D) Throwing all golang components into a src dir at the project root dir

src/
 
- daemon/
 
- wasm/
build
/
doc
/
etc
/
scripts
/
test
s/
website
/
makefile


E) Relative package include

import "./package1"



Reasons why I hate all of these solutions:

A - Renaming my projects directory to simply "src" makes the directory makes it misleading. I have many other things besides just source code in that directory. I'm very organized as you can tell.

B - Its just another sub directory I have to enter in order to get to the code I need to edit. Every time I'm navigating through the project it's going to force me to use an extra "../" or an extra "src/". The flatter the file system, the easier it is to navigate (in this case).

C - This works for the most part. But this monstrosity of a work-arounds usually makes my IDEs sh*t the bed when trying to index code.

D - Having a "src" directory listed in the project's root directory would be misleading. As there's source code in website/, scripts/, and maybe etc/ and tests/, thus all would technically need to be in that "src" directory... complicating the file structure and adding unnecessary depth. I would be more attuned to this if I could use a "go-src" directory. But I can't.

E - This one is definitely the go-to. Unfortunately, I'm using TinyGo to compile the WASM module, and it does not support relative imports. I contact the team why, and they said the support is on the backlog but also that relative imports were not "best practice". So I'll agree with that until I'm told otherwise. 

My gripe:

I get that Go's design is deliberately simple. And forcing things like syntax and naming standards in the actual code makes it more readable and simple for all... which is Go's best quality. However, when attempting to have the same mindset with the file structure does the exact opposite. GOPATH and GOROOT are always the hardest concepts to understand for new learners, and I've been using go for a good year and I still don't completely understand the purpose of go modules (I know it was an effort to ease the GOPATH requirements for new learners).
It's almost like in order to use Go you'd have to reconfigure your operating system's normal file structure. It is such a pain and goes against the fundamental simplicity of go. It's even more strange that Go builds into native binary when the source files are in the most non-native locations, ie everything in "/usr/local/go/src/" should be in "/usr/local/include/go/". Go seems to be trying to install its philosophy on my whole computer and I don't like it. 

Anyways:

Does anyone have any thoughts as to what I should do? Or is this project structure just invalid? Also, project  goals are as follows:
  1. Must work with `make build`, `make test`, and `make install`
  2. Must be able to be put into a `deb` package
  3. Must be optimal inside a git repository (ie, do not track binaries)
  4. As few directories as possible (Occam's file system)

Thanks Guys and Gals.

christoph...@gmail.com

unread,
Dec 22, 2019, 3:08:56 AM12/22/19
to golang-nuts
Oh my gosh. You could have saved all the time for writing that long long question if someone had told you before that GOPATH is a thing of the past.

Go has a new package dependency management system called Go Modules, and this removes the need for a central source code workspace.

See https://github.com/golang/go/wiki/Modules to get started, search https://blog.golang.org for its Go Module posts, or search the Web for "Go Modules".

Amnon Baron Cohen

unread,
Dec 26, 2019, 8:14:55 AM12/26/19
to golang-nuts

The problem is that the documentation on golang.org is still littered with instructions about the GOPATH way of doing things.
Happily there is a review in flight to fix this https://go-review.googlesource.com/c/website/+/199417
which hopefully will land soon. 
Reply all
Reply to author
Forward
0 new messages