go-astilectron-bundler
go-astilectron-bundler copied to clipboard
Using xgo for cross compiling
This PR for https://github.com/asticode/go-astilectron-bundler/issues/17
To build your app using xgo you should add
"xgo": { "enabled": true, "deps": ["https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2"] }
into your bundler.json
To install and/or update xgo, simply type:
go get -u github.com/karalabe/xgo
You can test whether xgo is functioning correctly by requesting it to cross compile itself and verifying that all cross compilations succeeded or not.
$ xgo github.com/karalabe/xgo
...
$ ls -al
-rwxr-xr-x 1 root root 2792436 Sep 14 16:45 xgo-android-21-arm
-rwxr-xr-x 1 root root 2353212 Sep 14 16:45 xgo-darwin-386
-rwxr-xr-x 1 root root 2906128 Sep 14 16:45 xgo-darwin-amd64
-rwxr-xr-x 1 root root 2388288 Sep 14 16:45 xgo-linux-386
-rwxr-xr-x 1 root root 2960560 Sep 14 16:45 xgo-linux-amd64
-rwxr-xr-x 1 root root 2437864 Sep 14 16:45 xgo-linux-arm
-rwxr-xr-x 1 root root 2551808 Sep 14 16:45 xgo-windows-386.exe
-rwxr-xr-x 1 root root 3130368 Sep 14 16:45 xgo-windows-amd64.exe
@vidmed I don't feel the way it's done right now would allow adding more build tools in the future. Here's what I have in mind:
- in the
Configuration
, add aBuilder
attribute which would be of typeConfigurationBuilder
- add a
ConfigurationBuilder
type like this:
type ConfigurationBuilder struct {
Name string `json:"name"`
XGO ConfigurationXGO `json:"xgo"`
}
- add a ConfigurationXGO type like this:
type ConfigurationXGO struct {
Deps []string `json:"deps"`
}
- create a
builder
interface (unexported for now) like this (I've added the first arguments that came to mind but of course you will have to add more arguments for bothCmd
andFinish
):
type builder interface {
Cmd(os, arch string, l ldflags) *exec.Cmd
Finish() error
}
Basically, in the case of xgo
, the Cmd
method would do:
return exec.Command("xgo", "--deps", strings.Join(b.xgo.Deps, " "), "--targets", e.OS+"/"+e.Arch, "--dest", environmentPath, "--out", binaryName, "-ldflags", l.string(), b.pathInput)
And the Finish
method would do:
astilog.Debug("Searching for binary produced by xgo")
// Search for file binary
// xgo names output files by himself. The only option we can set is prefix. So we must find file with such prefix
var files []os.FileInfo
files, err = ioutil.ReadDir(environmentPath)
if err != nil {
err = errors.Wrapf(err, "unable to find binary: %s", binaryName)
return
}
for _, f := range files {
if strings.HasPrefix(f.Name(), binaryName) {
binaryPath = filepath.Join(environmentPath, f.Name())
astilog.Debugf("Found binary produced by xgo - %s", binaryPath)
break
}
}
- add a
builderDefault
and abuilderXGO
that would implement thebuilder
interface - add a
builder
attribute to theBundler
- depending on the
Name
attribute of theConfigurationBuilder
, in theNew
method you would instantiate the correct builder (ifName
is empty, instantiatebuilderDefault
by default) in thebuilder
attribute - in the
bundle
method, simply use theCmd
andFinish
methods of thebuilder
interface.
That way, we'll be able to add more builder in the future.
And if someone wants to use xgo
, he/she can use the following configuration:
{
"builder": {
"name": "xgo",
"xgo": {
"deps": ["https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2"]
}
}
}
What do you think?
Actually, I haven't even thought about extending builders. Your idea is quite reasonable. But! Your approach won't allow developers to extend builders via registering their own ones. So I'd like to have an opportunity to register builders using something like
func RegisterBuilder(name sting, b Builder){ KnownBuilders[name] }
But there is a problem. For custom builders there might be some custom configuration. For example as for xgo deps. And that is a bad idea to store xgo configuration in ConfigurationBuilder
. We have to come up with storing custom config for builder in some way. Do you have any ideas? I hope I explained my thoughts clearly.
We could store builder config like
type ConfigurationBuilder struct {
Name string `json:"name"`
Config map[string]interface{} `json:"config"`
}
And then in Cmd
method parse config. Also this method have to return error if parsing or something else went wrong. What do you think?
Adding a RegisterBuilder
method sounds like a good idea to me. Please store the builders in an unexported map protected by a mutex.
However, regarding the configuration, I would create the ConfigurationBuilder
type like this:
type ConfigurationBuilder struct {
Custom json.RawMessage `json:"custom"`
Name string `json:"name"`
}
Then I would add a method ParseConfig(b json.RawMessage) error
to the Builder
interface. That way, one could implement such a method like this:
func ParseConfig(b json.RawMessage) error {
var v myAwewomeStruct
json.Unmarshal(b, &v)
}
What do you think?
@vidmed did you have time to work on this PR?
Has there been any progress toward support for xgo other than this abandoned pull request? I've come upon a build issue that might be solved by a change to using xgo. I am trying to determine my options...
Thanks!
@chinenual there has been no progress toward supporting xgo apart from that PR.
I'd be happy to review it if you decide to pick it up.
@asticode OK. I'm currently exploring a different fix (which avoids need for native code/xgo). But I may return to this and work on a PR.