x/mobile: Feature, add "-target=io/arm,ios/386" and "-nobitcode" to bind command

606 views
Skip to first unread message

Tristian Azuara

unread,
Apr 1, 2019, 12:32:35 AM4/1/19
to golang-nuts
Hi!

First, gomobile has been a real life saver thank you to all of those who have contributed.

The current commit at master (167ebed0ec6dd457a6b24a4f61db913f0af11f70) automatically adds the "-fembed-bitcode" flag to the cflags and 
it also automatically builds for all of iOS architectures.

We currently use `gomobile` to produce a framework for iOS and macOS applications. We also include applications for macOS that do not include 
support for instruction sets such as `386` but iOS does, some of those libraries we have no control over and some are our own.

Our current workaround is for us to manually patch `gomobile`'s source, like follows:

 λ ~/go/src/golang.org/x/mobile (master): git diff -p
diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go
index dbf9c8c..8f21b10 100644
--- a/cmd/gomobile/env.go
+++ b/cmd/gomobile/env.go
@@ -23,7 +23,8 @@ var (
        androidArmNM string
        darwinArmNM  string
 
-       allArchs = []string{"arm", "arm64", "386", "amd64"}
+       // allArchs = []string{"arm", "arm64", "386", "amd64"}
+       allArchs = []string{"arm", "arm64", "amd64"}
 )
 
 func buildEnvInit() (cleanup func(), err error) {
@@ -137,7 +138,7 @@ func envInit() (err error) {
                default:
                        panic(fmt.Errorf("unknown GOARCH: %q", arch))
                }
-               cflags += " -fembed-bitcode"
+               // cflags += " -fembed-bitcode"
                if err != nil {
                        return err
                }

I think that the addition of the following options would greatly simplify our CI/CD process, the goal would be to be able to use the command as follows:

$ gomobile bind -target=ios/arm,ios/arm64,ios/amd64 -nobitcode example.com/libs/mobile

By running it that way basically one would be able to exclude iOS simulator arch and the bitcode situation. I understand that probably it may not be something common, but being able to adjust the build process would be a great boon.

Does anyone else find that this would be something useful?, I'd be happy to contribute to this.

Cheers, Tristian.

ma...@eliasnaur.com

unread,
Apr 1, 2019, 3:09:35 AM4/1/19
to golang-nuts
Hi,

The -target flag does support architectures. Have you tried -target ios/amd64,ios/arm64,ios/arm from your example?

I'm not sure I understand the problem with bitcode and macOS; what is the error you get from  -fembed-bitcode?

  - elias

Tristian Azuara

unread,
Apr 1, 2019, 12:30:23 PM4/1/19
to golang-nuts
Hi Elias, thank you for the quick reply, I see, you're correct it does support the archs for ios, I had not tried it for ios, because the documentation just mentions that you can specify specific instruction sets when binding for android:

$ gomobile bind --help


By default, -target=android builds shared libraries for all supported
instruction sets (arm, arm64, 386, amd64). A subset of instruction sets
can be selected by specifying target type with the architecture name. E.g.,
-target=android/arm,android/386.

For -target ios, gomobile must be run on an OS X machine with Xcode
installed. The generated Objective-C types can be prefixed with the -prefix
flag.

There's no mention that you can filter out instruction sets for iOS but I just tested using it and it works!, thank you for pointing that out.

Now, regarding the bitcode part basically, because it's added automatically; any libraries that don't have BITCODE enabled don't link properly, here's some sample output:

GO111MODULE=off gomobile bind -v -target=ios/arm,ios/arm64,ios/amd64 -tags=ios example.com/mobile
runtime/cgo
os/user
net
ld: warning: ignoring file pycore/libpython-scriptengine.a, file was built for archive which is not the architecture being linked (armv7): pycore/libpython-scriptengine.a
ld: warning: object file (/Users/tristian/go/src/example.com/pycore/libpython-scriptengine-ios.a(python-scriptengine-ios.o)) was built for newer iOS version (9.3) than being linked (7.0)
ld: '/Users/tristian/go/src/example.com/pycore/libpython-scriptengine-ios.a(python-scriptengine-ios.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: ignoring file jscore/libscriptengine-ios-x86_64.a, file was built for archive which is not the architecture being linked (armv7): jscore/libscriptengine-ios-x86_64.a
ld: warning: object file (/Users/tristian/go/src/example.com/jscore/libscriptengine-ios-arm.a(test_lib_for_ios.o)) was built for newer iOS version (10.2) than being linked (7.0)
ld: '/Users/tristian/go/src/example.com/jscore/libscriptengine-ios-arm.a(test_lib_for_ios.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gomobile: darwin-arm: go build -tags ios ios -v -buildmode=c-archive -o /var/folders/g1/v3hz1sm92nv7wbzpg3dx_h_h0000gp/T/gomobile-work-974051835/mobile-arm.a gobind failed: exit status 2

make: *** [Mobile.framework] Error 1

This would force us to recompile libpython-scriptengine-ios.a or any other libraries that don't have bitcode support

When I comment out -fembed-bitcode I no longer see that error.

Best, Tristian

ma...@eliasnaur.com

unread,
Apr 1, 2019, 12:53:55 PM4/1/19
to golang-nuts
One thing you should be able to do is disable bitcode in the Xcode project settings (suggested as "disable bitcode for this target"). If that doesn't work, please file an issue.

 - elias

const...@topinvestor.app

unread,
May 15, 2019, 12:00:32 AM5/15/19
to golang-nuts
When I compile with:
gomobile bind -target=ios -tags="ios" -v mygomobileios


and importing the generated Mygomobileios.framework

I get an error:

ld: '/mygo/src/mygomobileios/gomobileios_test/Mygomobileios.framework/Mygomobileios(go.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64

clang: error: linker command failed with exit code 1 (use -v to see invocation)


Which indicates the generated framework does not contain bitcode.

Ho to get the bitcode generated?

Tristian Azuara

unread,
May 15, 2019, 12:18:12 AM5/15/19
to golang-nuts
Hi!,

gomobile does not produce BITCODE enabled frameworks,  (AFAIK) you have to set the XCode `ENABLE_BITCODE` build setting to `NO`, `gomobile` (the latest version) automatically adds the `-fembed-bitcode` as C flag, here you can find a better explanation of it:

 * https://stackoverflow.com/a/34965178

const...@topinvestor.app

unread,
May 15, 2019, 3:36:29 AM5/15/19
to golang-nuts
I ran this command:

brew install go --HEAD


Now Xcode compiles without an error and ENABLE_BITCODE=YES
Reply all
Reply to author
Forward
0 new messages