[archived] Building Syncthing

Possibly godep has become more strict in a later update. The build.go script currently tries to do some magic so things will work even if GOPATH is not set, but that won’t help godep and does nothing if GOPATH is set but not set correctly.

It’s a bit of a love-it-or-hate-it situation, I’m personally not that impressed by the whole GOPATH thing, although when set up exactly as the tools expect it it works very well.

I created a Dockerfile and script that will automatically build the syncthing binary for you from source. . Just run ./build.sh and the binary will be created in that directory. The only prerequisite is a working Docker environment. Wasn’t sure if there was someplace else in the docs to put this :smile:

Scott

Edit: advantage for this – you don’t need a Go environment installed on your machine. It’s all containerized.

1 Like

What’s the reason why you have to set the directories in such a way to build? It’s the first program that I see that needs to be in a particular directory to be build…

Because Go.

I’m trying to update the FreeBSD port and make it work with build.go I’m trying to avoid using git because I want to just get the tar.gz of the source for checksum verification.

my issue is ‘git describe’ is failing because it isn’t a got repo, just the untared source code.

is there a way for my to specify the version being compiled by a flag? or any other way? my other solution is to patch the build script to hardset the version number, but this isn’t as maintainable.

thanks

This link might be useful for anyone trying to make a fork

1 Like

Is it right that there is no way to build it without mercurial, since go get need mercurial?

No, you don’t, actually. As long as you use Godep and the bundled dependencies. (I just uninstalled hg from the build server, and it builds just fine.)

I began having problems building this evening after taking an update. I did a clean, no luck. Removed all source and refetched, no luck. Any thoughts?

GOPATH=/mnt/home/bboerner/play/go/src/github.com/syncthing/syncthing/Godeps/_workspace:/home/bboerner/play/go
go install -v -ldflags -w -X main.Version v0.10.1+1-gfc6b2d9 -X main.BuildStamp 1413118476 -X main.BuildUser bboerner -X main.BuildHost care -X main.BuildEnv default ./cmd/...
github.com/syncthing/syncthing/cmd/stindex
github.com/syncthing/syncthing/internal/model
# github.com/syncthing/syncthing/cmd/stindex
/home/bboerner/play/go/src/github.com/syncthing/syncthing/cmd/stindex/main.go:26: inconsistent definition for type leveldb.snapshotElement during import
	struct { seq uint64; ref int; next *leveldb.snapshotElement; prev *leveldb.snapshotElement } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; ref int; e *list.Element } (in "github.com/syndtr/goleveldb/leveldb")
/home/bboerner/play/go/src/github.com/syncthing/syncthing/cmd/stindex/main.go:26: inconsistent definition for type leveldb.DB during import
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsRoot leveldb.snapshotElement; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsList *list.List; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syndtr/goleveldb/leveldb")
# github.com/syncthing/syncthing/internal/model
/home/bboerner/play/go/src/github.com/syncthing/syncthing/internal/model/model.go:41: inconsistent definition for type leveldb.snapshotElement during import
	struct { seq uint64; ref int; next *leveldb.snapshotElement; prev *leveldb.snapshotElement } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; ref int; e *list.Element } (in "github.com/syncthing/syncthing/internal/stats")
/home/bboerner/play/go/src/github.com/syncthing/syncthing/internal/model/model.go:41: inconsistent definition for type leveldb.DB during import
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsRoot leveldb.snapshotElement; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsList *list.List; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syncthing/syncthing/internal/stats")
/home/bboerner/play/go/src/github.com/syncthing/syncthing/internal/model/model.go:43: inconsistent definition for type leveldb.snapshotElement during import
	struct { seq uint64; ref int; next *leveldb.snapshotElement; prev *leveldb.snapshotElement } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; ref int; e *list.Element } (in "github.com/syndtr/goleveldb/leveldb")
/home/bboerner/play/go/src/github.com/syncthing/syncthing/internal/model/model.go:43: inconsistent definition for type leveldb.DB during import
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsRoot leveldb.snapshotElement; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syncthing/syncthing/internal/files")
	struct { seq uint64; s *leveldb.session; memMu sync.RWMutex; memPool chan *memdb.DB; mem *leveldb.memDB; frozenMem *leveldb.memDB; journal *journal.Writer; journalWriter storage.Writer; journalFile storage.File; frozenJournalFile storage.File; frozenSeq uint64; snapsMu sync.Mutex; snapsList *list.List; aliveSnaps int32; aliveIters int32; writeC chan *leveldb.Batch; writeMergedC chan bool; writeLockC chan struct {}; writeAckC chan error; journalC chan *leveldb.Batch; journalAckC chan error; tcompCmdC chan leveldb.cCmd; tcompPauseC chan chan<- struct {}; tcompTriggerC chan struct {}; mcompCmdC chan leveldb.cCmd; mcompTriggerC chan struct {}; compErrC chan error; compErrSetC chan error; compStats [7]leveldb.cStats; closeW sync.WaitGroup; closeC chan struct {}; closed uint32; closer io.Closer } (in "github.com/syndtr/goleveldb/leveldb")
exit status 2
exit status 1

rm -rf $GOPATH/pkg

I am so upset that this happens, and that godeps doesn’t take care of this.

My gocode sometimes rebuilds packages, and if I got the latest checked out on $GOPATH, I get screwed over by pkg not having the right version.

This is an annoyance in the compiler, or rather the go tool that wraps the compiler. We build with a split $GOPATH; the dependencies under Godeps/_workspace are first in the path, and the “regular” path follows, something like

GOPATH=/Users/jb/src/github.com/syncthing/syncthing/Godeps/_workspace:/Users/jb

Thing is though, if you run (for example) go get github.com/syndtr/goleveldb from a terminal with just the regular GOPATH, it’ll build that package and stash it in (on my setup) /Users/jb/pkg. When you next clean and build syncthing, it’ll check for an existing compiled package of leveldb first in .../Godeps/_workspace/pkg (which won’t exist), then in /Users/jb/pkg (which does exist), and use the latter if those files are not older than the source files in the syncthing repo. Hence, possible mismatch.

On the other hand, this is just a sign of other breakage that would have happened had we not been using godeps; because then it would have compiled and built against the wrong version of goleveldb (or another dependency).

Running godep restore should check out the “syncthing versions” of all dependencies in your regular GOPATH, preventing this from happening. If you want that, and don’t have other things that depend on specific versions of them, etc etc.

This has mostly come up with goleveldb because that API has changed a bit lately… If the external API doesn’t change, this isn’t an issue.

@calmh, thanks for the fix and description of why it happens.

Regards.

If you want to rebuild just the Web UI and test it in Pulse, run:

go run build.go assets
go run build.go

If you want to quickly iterate without rebuilding, just run a quick web server in gui/ — e.g.,

python -m SimpleHTTPServer 8000

Or just STGUIASSETS=path/to/gui syncthing. :wink:

Last time I’ve checked, that didn’t work for all the files.

It should? File a bug! :grinning:

One a day, keeps the milestone achievement away.

1 Like

Sorry if this is a newbie question: how do I rebuild all the binaries we have available for download? (I’m successfully building single binaries using the instructions here but would like to build, for example, a Linux binary also from my Mac.) Is there a build task I’m overlooking or a different process for that? Please feel free to point me at something I can read on the subject; tried searching but came up empty. Thanks!