Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross compile instructions need to be updated #432

Open
Jacalz opened this issue Sep 22, 2019 · 18 comments
Open

Cross compile instructions need to be updated #432

Jacalz opened this issue Sep 22, 2019 · 18 comments

Comments

@Jacalz
Copy link

@Jacalz Jacalz commented Sep 22, 2019

The instructions on compiling for Windows during cross compilation seems to be outdated. For example the yaourt program is dead and not used anymore so it makes it more difficult to get everything built correctly. It would be great if the cross compilation instructions could be updated with better instructions and being more up to date.

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Sep 26, 2019

I'm looking into compiling from another OS, like Debian (which I think has the needed libraries). If we can get it working, it should be fairly easy to make an "out of the box" compiling environment using Docker or something

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Sep 27, 2019

Ok, I successfully cross-compiled for windows from a Fedora Docker image. I've never used Fedora or Docker before, so this needs some improvements before we can add it to the wiki.

  • install docker and start the system service from your Linux computer
  • $ docker run -it fedora /bin/bash
  • once in the shell, run yum install mingw64-gtk3 go glib2-devel
  • go get your program
  • $ PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go install -v github.com/gotk3/gotk3/gtk -- this takes around 8 minutes
  • cd to your project directory in the go source tree and run CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -ldflags -H=windowsgui
  • yes | cp -r /usr/x86_64-w64-mingw32/sys-root/mingw/* .
  • from another shell (in your main Linux environment), you can pull the built program from the Fedora image like this: docker cp <image-id>:/root/go/src/github.com/yourname/yourproject newdir (use docker ps -alq to get the image ID)

TODOS:

  • figure out which libraries actually need to be copied from the /usr/x86_64-w64-mingw32/sys-root/mingw/ directory so we don't have to distribute a ~200MB folder
  • if someone knows anything about Docker, we could probably make this non-interactive and much faster.
@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Sep 27, 2019

Oops, I forgot one other thing to run from Fedora:
bash -c "sed -i -e 's/-Wl,-luuid/-luuid/g' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/gdk-3.0.pc" to fix the broken file found in #296

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 9, 2019

Here's a better setup, using Buildah instead of Docker. Drop these scripts in your package directory and run winbuild.sh. It works as an unprivileged user (and no daemon required). The first run takes a long time but after that it saves a copy of the container so subsequent builds (in any of your gotk3 projects) only take a few seconds.
winbuild.sh:

#!/bin/bash
setup () {
    # Create a fedora container
    container=$(buildah from fedora)

    # Install dependencies 
    buildah run $container dnf -y install mingw64-gtk3 go # glib2-devel gtk3-devel

    # Fix typo in mingw library
    buildah run $container bash -c "sed -i -e 's/-Wl,-luuid/-luuid/g' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/gdk-3.0.pc"

    # Download gotk3
    buildah run $container go get -u github.com/gotk3/gotk3/gtk

    # Temporarily fix https://github.com/gotk3/gotk3/issues/444
    buildah run $container sed -i '7i\ // #include <stdlib.h>' /root/go/src/github.com/gotk3/gotk3/gtk/gtk_since_3_16.go

    # Compile gotk3
    buildah run $container bash -c "PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go install -v github.com/gotk3/gotk3/gtk"

    # Cache image to avoid re-downloading dependencies every time
    buildah commit $container my-gotk3-app

    # Clean up
    buildah rm $container
}

# This just checks whether the container already exists on your drive
buildah inspect localhost/my-gotk3-app &>/dev/null
return_value=$?

if [ $return_value -eq 1 ]
then
    echo "Initial container setup"
    setup
fi

# In order to run some of these commands as an unprivileged user, they
# need to be wrapped in "buildah unshare". The easiest way for me to
# do that was by simply calling a separate bash script, but there's
# probably a workaround to get everything in this one file

buildah unshare ./build.sh

build.sh:

#!/bin/bash

# Where windows executable and libraries will be saved
output_folder=./windows

# Create a new container from the base one we created
container=$(buildah from localhost/my-gotk3-app)

# Directory of your package in the container
folder=$(go list) 
folder=/root/go/src/$folder 

# Clear previous build
yes | rm -r $output_folder

# Copy program into container
buildah copy $container . $folder

# Pull dependencies for your program. There are a bunch of irrelevant
# pkg-config errors, but they don't matter because we'll be compiling
# with the MinGW pkg-config, not the local Linux one. If you want to
# resolve the errors, uncomment the extra dependencies in winbuild.sh
# but I don't recommend it because this command will take way longer
buildah run $container bash -c "cd $folder && go get ./... &>/dev/null"&>/dev/null

# Compile your program
buildah run $container bash -c "cd $folder && CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -ldflags -H=windowsgui"

# Copy mingw dlls into project folder:

# This is the main line that you might need to personalize. For
# instance, I was getting "No GSettings schemas are installed on the
# system" errors that I think were related to my FileChooserDialog, so
# I included that folder and added os.Setenv("GSETTINGS_SCHEMA_DIR",
# ".\\schemas") to my main.go
buildah run $container bash -c "yes | cp -r /usr/x86_64-w64-mingw32/sys-root/mingw/{bin/*.dll,share/glib-2.0/schemas} $folder"

# Copy the results of compilation from container
mountpoint=$(buildah mount $container)
cp -ru $mountpoint$folder/ $output_folder

# Clean up
buildah rm $container

I tested it on my own program and a couple of the gtk-examples from an Arch Linux host. It would be great if someone could test it from another Linux distribution, maybe @rasteric?

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 14, 2019

I figured out how to do it from one script - I also added a line to generate a basic Windows installer. The file size for the installer is much more manageable at 47M.
https://gist.github.com/wrycode/581989a06cd9f96c1f65cd31947c809c

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 14, 2019

That’s great! Will it work on more distros than fedora?
It looks to have some fedora references...

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 15, 2019

The only dependency for the script is buildah, so it should work on any Linux distro. I would like someone else to confirm this. All of the Fedora-specific commands (like dnf install ...) are run from inside a Fedora container, so your local system isn't modified.

The only places this script modifies on your system are $output_folder and the container storage area (something like ~/.local/share/containers/storage/vfs/dir/).

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 15, 2019

But you still need those commands in the first place? I’m unsure, but I did test this yesterday evening on Solus and ran in to a bunch of issues. I don’t know if I did anything wrong or if I had buildah set up wrong. Will try again today if I get the time for it.

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 15, 2019

But you still need those commands in the first place?

No, you don't. That's the real reason I'm doing it this way. Getting the MinGW libraries is a nightmare on Arch, but Fedora already has packages for them.

Thanks for looking into it! What issues did you run into?

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 18, 2019

I think I am getting it to work now. Must have been doing something wrong the last time I tried it. Might also be worth noting that it needs to be run with sudo privileges, otherwise it will fail hard.

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 18, 2019

Got this error at the end it seems:

Output: "installer.exe"
Install: 3 pages (192 bytes), 4 sections (1 required) (131168 bytes), 7169 instructions (200732 bytes), 3093 strings (84959 bytes), 1 language table (250 bytes).
Uninstall: 1 page (128 bytes), 1 section (32792 bytes), 69 instructions (1932 bytes), 109 strings (2220 bytes), 1 language table (194 bytes).
Datablock optimizer saved 8869 KiB (~15.7%).

Using zlib compression.

EXE header size:               76800 / 76288 bytes
Install code:                  52118 / 319389 bytes
Install data:               48355450 / 172162655 bytes
Uninstall code+data:            1622 / 2118 bytes
CRC (0x12817848):                  4 / 4 bytes

Total size:                 48485994 / 172560454 bytes (28.0%)
ERRO error unmounting /var/lib/containers/storage/overlay/9dab112c6df8b0f442eb554b3a605a507ea79eb50fb2eb4727c0506f5e913bfd/merged: invalid argument 
error mounting "my-gotk3-app-working-container" container "my-gotk3-app-working-container": error mounting build container "b3edb80e7bf384e52e922886b152d8b738dd7867de82843cb6d327f8774eae71": error creating overlay mount to /var/lib/containers/storage/overlay/9dab112c6df8b0f442eb554b3a605a507ea79eb50fb2eb4727c0506f5e913bfd/merged: operation not permitted
ERRO exit status 1                                
ERRO exit status 1                                
cp: cannot stat '/root/go/src/_/home/jacob/Documents/cmpp-winbuild/windows': No such file or directory
b3edb80e7bf384e52e922886b152d8b738dd7867de82843cb6d327f8774eae71

These are the files and where they are placed:
image

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 20, 2019

Might also be worth noting that it needs to be run with sudo privileges, otherwise it will fail hard.

Could you paste the errors you get if you run it without root privileges? One benefit of Buildah (vs. Docker) is that unprivileged users should be able to use it, so I want to get this working without sudo.

Your error message indicates that the build succeeded and the installer was successfully created, but the script failed to pull the file from the container. The relevant part is

ERRO error unmounting /var/lib/containers/storage/overlay/9dab112c6df8b0f442eb554b3a605a507ea79eb50fb2eb4727c0506f5e913bfd/merged: invalid argument 
error mounting "my-gotk3-app-working-container" container "my-gotk3-app-working-container": error mounting build container "b3edb80e7bf384e52e922886b152d8b738dd7867de82843cb6d327f8774eae71": error creating overlay mount to /var/lib/containers/storage/overlay/9dab112c6df8b0f442eb554b3a605a507ea79eb50fb2eb4727c0506f5e913bfd/merged: operation not permitted
ERRO exit status 1                                
ERRO exit status 1                                
cp: cannot stat '/root/go/src/_/home/jacob/Documents/cmpp-winbuild/windows': No such file or directory
b3edb80e7bf384e52e922886b152d8b738dd7867de82843cb6d327f8774eae71

I tried running the script as root out of curiosity (it works as a normal user for me) and I got the exact same error:

ERRO error unmounting /var/lib/containers/storage/overlay/249bdb00434e843eaa49d760978ca425fb315f2635a079e451e98d3c1b1cb2b8/merged: invalid argument 
error mounting "my-gotk3-app-working-container" container "my-gotk3-app-working-container": error mounting build container "c08d3dc130fe9f25de612d0a511a706f6feed62f4ad34a2b7b5acd393acdff23": error creating overlay mount to /var/lib/containers/storage/overlay/249bdb00434e843eaa49d760978ca425fb315f2635a079e451e98d3c1b1cb2b8/merged: operation not permitted
ERRO exit status 1                                
ERRO exit status 1                                
cp: cannot stat '/root/go/src/_/home/wrycode/.go/src/github.com/wrycode/olduvai/windows': No such file or directory
c08d3dc130fe9f25de612d0a511a706f6feed62f4ad34a2b7b5acd393acdff23

So the problem is related to this line in build ():

cp -ru $(buildah unshare buildah mount $container)$folder/$output_folder .

The folder=$(go list) line also needs to be changed, because root has a different GOPATH than the normal user.

I'd prefer to get this working without sudo, but if that's not an option for you, I suspect the workaround would be remove just the words buildah unshare from that line (buildah unshare isn't designed to be run as root). And possibly hardcode the folder variable.

Note that if you do switch to running it as a normal user, the script will probably do the lengthy initial setup again because root has a different container store than your user.

To debug, you can comment out the final line of build ()

 #buildah rm $container

and run the script, then the container will still be available so you can keep trying variations of the cp -ru command until you find out what works.

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 21, 2019

Here are the issues when running without sudo:

jacob@pacman ~/Documents/cmpp-winbuild $ ./winbuild.sh
Initial container setup
Getting image source signatures
Copying blob 9908e4690737 done
Copying config 9eff96f4c8 done
Writing manifest to image destination
Storing signatures
ERRO Error while applying layer: ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 192:192 for /run/systemd/netif): lchown /run/systemd/netif: invalid argument 
Getting image source signatures
Copying blob e979bb52402a done
Copying config 071ac0765f done
Writing manifest to image destination
Storing signatures
ERRO Error while applying layer: ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 0:12 for /var/spool/mail): lchown /var/spool/mail: invalid argument 
The following failures happened while trying to pull image specified by "fedora" based on search registries in /etc/containers/registries.conf:
* "localhost/fedora": Error initializing source docker://localhost/fedora:latest: pinging docker registry returned: Get https://localhost/v2/: dial tcp 127.0.0.1:443: connect: connection refused
* "docker.io/library/fedora": Error committing the finished image: error adding layer with blob "sha256:9908e46907377e84bd6646bdb18abebeb4163b85135739e1cd60aae154d4557c": ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 192:192 for /run/systemd/netif): lchown /run/systemd/netif: invalid argument
* "gcr.io/fedora": Error initializing source docker://gcr.io/fedora:latest: unexpected http code: 400 (Bad Request), URL: https://gcr.io/v2/token?scope=repository%3Afedora%3Apull&service=gcr.io
* "quay.io/fedora": Error initializing source docker://quay.io/fedora:latest: Error reading manifest latest in quay.io/fedora: error parsing HTTP 404 response body: invalid character '<' looking for beginning of value: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>\n"
* "registry.fedoraproject.org/fedora": Error committing the finished image: error adding layer with blob "sha256:e979bb52402afe9decc81f0787920da1db85c99b89851990bfc7cbd66411224e": ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 0:12 for /var/spool/mail): lchown /var/spool/mail: invalid argument
* "registry.access.redhat.com/fedora": Error initializing source docker://registry.access.redhat.com/fedora:latest: Error reading manifest latest in registry.access.redhat.com/fedora: name unknown: Repo not found
* "registry.centos.org/fedora": Error initializing source docker://registry.centos.org/fedora:latest: Error reading manifest latest in registry.centos.org/fedora: manifest unknown: manifest unknown
ERRO exit status 1                                
error reading build container "dnf": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
error reading build container "go": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
error reading build container "my-gotk3-app": error reading build container: container not known
ERRO exit status 1                                
container ID must be specified
ERRO exit status 1                                
Error initializing source docker://localhost/my-gotk3-app:latest: pinging docker registry returned: Get https://localhost/v2/: dial tcp 127.0.0.1:443: connect: connection refused
ERRO exit status 1                                
error reading build container ".": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
error reading build container "bash": error reading build container: container not known
ERRO exit status 1                                
cp: cannot stat '/root/go/src/_/home/jacob/Documents/cmpp-winbuild/windows': No such file or directory
container ID must be specified
ERRO exit status 1

I am currently fiddling around with your suggestions for getting it working as root.

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 21, 2019

Looks like the very first line is the problem, so maybe (hopefully?) it's an upstream bug. You could check by just running it from your shell:

$ container=$(buildah from fedora)

If I'm right, the Solus Package is a few minor versions behind the current release so getting a newer copy might resolve the issue.

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 21, 2019

I see, will see about getting that updated. I am a packager for Solus myself.

I used your suggestions and managed to get a working installer (running under root) that I fired up on my windows laptop and installed it just like expected. Everything works the only issue is that the name is a bit strange, would be great to be able to set that before building. Anyhow, thanks for helping me get it working. I needed it working for tomorrow for a school project so this was done with perfect timing :)

I wrote a ui using fyne just in case I wouldn't get this to work, but now that it does, I have two user interfaces to be graded on in the course :) Have you thought about making a specified program to help compile gotk3 for multiple architectures and operating systems? This tool for fyne called fyne-cross is just amazing for cross compiling software. I think it would be really cool to have a dedicated program for helping out with this and I think you could draw some inspiration from fyne-cross if you'd like.

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 21, 2019

I just updated and built buildah myself to get it updated to the latest version. Seems like the issue isn't resolved by updating to 1.11.3 :(

@wrycode

This comment has been minimized.

Copy link
Contributor

@wrycode wrycode commented Oct 21, 2019

Everything works the only issue is that the name is a bit strange, would be great to be able to set that before building.

Was it "TOPP-Faunal-Data-Tool"? There's a variable you can change in the script, executable_name, I just left it set to the name of my current project and buried it in the middle of the script (oops).

The installer setup is a pretty simple command using a wrapper for makensis, if you need more control you can run it once without the --run flag, save the resulting installer.nsi file, and edit it to your liking (you can customize things like the program name in Windows, storage location, icon, etc.). Then instead of the nsiswrapper command in the script you'd run makensis installer.nsi. I'll put this in the wiki.

Glad I helped you beat a deadline :)

Hmmm, thanks for the pointer to fyne-cross. It looks like it is a comparable setup, except with Docker (and they provide a prebuilt container to download).

@Jacalz

This comment has been minimized.

Copy link
Author

@Jacalz Jacalz commented Oct 22, 2019

Yes it was and I managed to build it using a new name that I changed in the script. Thanks for all the help :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.