go-astilectron-bundler icon indicating copy to clipboard operation
go-astilectron-bundler copied to clipboard

Using xgo for cross compiling

Open vidmed opened this issue 6 years ago • 8 comments

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 avatar Mar 29 '18 17:03 vidmed

@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 a Builder attribute which would be of type ConfigurationBuilder
  • 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 both Cmd and Finish):
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 a builderXGO that would implement the builder interface
  • add a builder attribute to the Bundler
  • depending on the Name attribute of the ConfigurationBuilder, in the New method you would instantiate the correct builder (if Name is empty, instantiate builderDefault by default) in the builder attribute
  • in the bundle method, simply use the Cmd and Finish methods of the builder 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?

asticode avatar Mar 29 '18 19:03 asticode

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.

vidmed avatar Mar 29 '18 20:03 vidmed

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?

vidmed avatar Mar 29 '18 21:03 vidmed

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?

asticode avatar Mar 30 '18 09:03 asticode

@vidmed did you have time to work on this PR?

asticode avatar Apr 18 '18 07:04 asticode

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 avatar Aug 17 '20 20:08 chinenual

@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 avatar Aug 19 '20 08:08 asticode

@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.

chinenual avatar Aug 19 '20 13:08 chinenual