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

Updates readme with examples for godot 3 and 4 #9

Open
wants to merge 8 commits into
base: 2023.08.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Dockerfile.linux-builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM almalinux:8

RUN yum -y update && \
yum -y install make ncurses-devel which unzip perl cpio rsync fileutils bc bzip2 gzip sed git python3 file patch wget perl-Thread-Queue perl-Data-Dumper perl-ExtUtils-MakeMaker perl-IPC-Cmd gcc gcc-c++ && \
yum clean all

105 changes: 105 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Godot buildroot

This repository contains the Godot buildroot to generate toolchains for building the Godot engine in a portable way for Linux. Using these toolchains is the best way to distribute Linux builds of your custom-compiled Godot game.

*You will only need this if you built the engine manually. If you use official templates you will not need this*

The toolchain current contains the following:
* gcc-13.2.0
* glibc-2.28
* pulseaudio
* alsa
* X client libraries
* udev
* libGL
* fontconfig
* speechd

# Using the SDKs

This section is first because there's a lot of stuff below and this is likely what you came here for. Don't forget to check out the `Obtaining an SDK` section below!

The first part of an SDK filename referes to the architecture that this SDK will generate binaries *for*. If you want to ship your game to both 32bit and 64bit Intel/AMD users you will need both `x86_64-godot-linux-gnu_sdk-buildroot.tar.gz` and `i686-godot-linux-gnu_sdk-buildroot.tar.gz`.

Unpack the toolchain anywhere you like and run the `relocate-sdk.sh` script within. This needs to happen every time you move the toolchain to a different directory, but only needs to happen once after installation.

After this you can build the engine more-or-less like normal.

## Examples:

### Godot 4:

#### x86_64:

`PATH=/home/hp/tmp/x86_64-godot-linux-gnu_sdk-buildroot/bin:$PATH scons p=linuxbsd target=release_debug CXX=/home/hp/tmp/x86_64-godot-linux-gnu_sdk-buildroot/bin/x86_64-godot-linux-gnu-g++ use_static_cpp=yes`

#### x86:

`PATH=/home/hp/tmp/arm-godot-linux-gnueabihf_sdk-buildroot/bin/:$PATH scons p=linuxbsd target=release_debug use_static_cpp=yes bits=32`

*Note the `bits=32` at the end!*

### Godot 3:

#### x86_64:

`PATH=/home/hp/tmp/x86_64-godot-linux-gnu_sdk-buildroot/bin:$PATH scons platform=x11 tools=no target=release_debug use_static_cpp=yes -j$(nproc)`

#### x86:

`PATH=/home/hp/tmp/arm-godot-linux-gnueabihf_sdk-buildroot/bin/:$PATH scons platform=x11 tools=no target=release_debug use_static_cpp=yes -j$(nproc) bits=32`

*Note the `bits=32` at the end!*


For other build-time options please see https://docs.godotengine.org/en/stable/development/compiling/compiling_for_x11.html


# Obtaining an SDK

## Downloading a pre-built SDK

Pre-built toolchains are available on https://download.tuxfamily.org/godotengine/toolchains/linux.

## Using buildroot to generate SDKs

### Building a toolchain for local use

*Using this method will create a toolchain you yourself can use to create Godot releases that will work on any Linux system currently in use. However the toolchain you generate will not be portable to older Linuxes. If you plan to distribute the toolchain itself use the podman method below*

The basic steps for building a toolchain are:

* copy `config-godot-<arch>` to `.config`
* run `make olddefconfig`
* run `make clean sdk`

Afterwards the SDK will be in `output/images/<arch>-godot-linux-gnu_sdk-buildroot.tar.gz`.

**NOTE: that `make clean sdk` will delete old builds. Move them out of the way first!**

### Building a toolchain for distribution

This method uses a Alma Linux 8 container to make the buildroot *itself* portable so it can be distributed to other users. This is also the way the downloads above are generated.

* run `./build-sdk.sh <arch>` for instance `x86_64`

The toolchain will appear in the `godot-toolchains` directory

## Modifying the toolchain

For detailed information please see https://buildroot.org however a short version is here:

**NOTE: re-running the build-sdk.sh script will overwrite your changes by default. Take care**

* Copy the architecture you would like to change to `.config` for instance `cp config-godot-x86_64 .config`
* Run `make menuconfig`
* Make your changes

At this point your changes exist in .config. **Make a backup**. If you're building for local use just run `make clean sdk`, if you're using the container approach copy your `.config` file to the arch config like `config-godot-x64_64`


## Making Pull Requests for this repository

First of all: Thanks for wanting to help! Second of all: Since we support multiple architectures make sure that you make *the same* changes to all architectures and PR them together. If you *specifically* want to make a change to one architecture please note that clearly in the PR message.

Thanks!
File renamed without changes.
83 changes: 83 additions & 0 deletions build-sdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash
set -e

function usage() {
echo "usage: $0 host target"
echo " where host is one of linux-x86_64"
echo " where target is one of i686, x86_64, armv7"
exit 1
}

if [ -z $1 ] || [ -z $1 ]; then
usage
fi

case $1 in
linux-x86_64)
host=$1
;;
*)
echo "unknown SDK host \"$1\""
usage
esac

case $2 in
i686)
cp config-godot-i686 .config
toolchain_prefix=i686-godot-linux-gnu
bits=32
;;
x86_64)
cp config-godot-x86_64 .config
toolchain_prefix=x86_64-godot-linux-gnu
bits=64
;;
armv7)
cp config-godot-armv7 .config
toolchain_prefix=arm-godot-linux-gnueabihf
bits=32
;;
aarch64)
cp config-godot-aarch64 .config
toolchain_prefix=aarch64-godot-linux-gnu
bits=64
;;
*)
echo "unknown SDK target \"$2\""
usage
;;
esac

if which podman &> /dev/null; then
container=podman
elif which docker &> /dev/null; then
container=docker
else
echo "Podman or docker have to be in \$PATH"
exit 1
fi

function build_linux_sdk() {
${container} build -f Dockerfile.linux-builder -t godot-buildroot-builder-linux
${container} run -it --rm -v $(pwd):/tmp/buildroot:z -w /tmp/buildroot -e FORCE_UNSAFE_CONFIGURE=1 --userns=keep-id godot-buildroot-builder-linux bash -c "make syncconfig; make clean sdk"

mkdir -p godot-toolchains

rm -fr godot-toolchains/${toolchain_prefix}_sdk-buildroot
tar xf output/images/${toolchain_prefix}_sdk-buildroot.tar.gz -C godot-toolchains

pushd godot-toolchains/${toolchain_prefix}_sdk-buildroot
../../clean-linux-toolchain.sh ${toolchain_prefix} ${bits}
popd

pushd godot-toolchains
tar -cjf ${toolchain_prefix}_sdk-buildroot.tar.bz2 ${toolchain_prefix}_sdk-buildroot
rm -rf ${toolchain_prefix}_sdk-buildroot
popd
}

build_linux_sdk

echo
echo "***************************************"
echo "Build succesful your toolchain is in the godot-toolchains directory"
108 changes: 108 additions & 0 deletions clean-linux-toolchain.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/bin/bash

set -e

if [ -z $1 ] || [ -z $2 ]; then
echo "usage: $0 arch bits"
exit 1
fi

arch=$1
bits=$2

bin_to_keep="aclocal autoconf autoheader automake autoreconf cmake gawk libtool m4 meson ninja pkgconf pkg-config python python3.11 scons tar toolchain-wrapper"
lib_to_keep="cmake gcc libpkgconf libpython3.11 libz libisl libmpc libmpfr libgmp libffi python3.11 pkgconfig libm libmvec"
share_to_keep="aclocal autoconf buildroot cmake gcc libtool pkgconfig"
sysroot_share_to_keep="aclocal pkgconfig"

function clean_directory() {
pushd $1
files_to_keep="${@:2}"

for file in $(ls -1); do
keep_file=0

if echo ${file} | grep -qe "^${arch}"; then
keep_file=1
fi

for keep in ${files_to_keep}; do
if echo ${file} | grep -qe "^${keep}"; then
keep_file=1
break
fi
done

if [ ${keep_file} -eq 0 ]; then
rm -rf ${file}
fi
done

popd
}

rm -f $(find -name *.a | grep -vE '(nonshared|gcc|libstdc++)')
find -regex '.*\.so\(\..*\)?' -exec bin/${arch}-strip {} \; 2> /dev/null
find bin -exec bin/${arch}-strip {} \; 2> /dev/null
find ${arch}/bin -exec bin/${arch}-strip {} \; 2> /dev/null
find libexec/gcc -type f -exec bin/${arch}-strip {} \; 2> /dev/null

clean_directory bin ${bin_to_keep}
clean_directory lib ${lib_to_keep}
clean_directory share ${share_to_keep}
clean_directory ${arch}/sysroot/usr/share ${sysroot_share_to_keep}

find -name *.pyc -delete

rm -f usr lib64
rm -rf sbin var

for s in bin lib lib64 sbin; do
if [ -L ${arch}/sysroot/${s} ]; then
rm -f ${arch}/sysroot/${s}
fi
done

if [ ${bits} == 64 ]; then
libdir_to_remove=lib
libdir_to_keep=lib64
else
libdir_to_remove=lib64
libdir_to_keep=lib
fi

rm -rf ${arch}/sysroot/usr/{bin,sbin}

mkdir -p ${arch}/sysroot/${libdir_to_keep}
cp ${arch}/sysroot/usr/${libdir_to_keep}/libpthread*so* ${arch}/sysroot/${libdir_to_keep}
cp ${arch}/sysroot/usr/${libdir_to_keep}/ld-linux*so* ${arch}/sysroot/${libdir_to_keep}
cp ${arch}/sysroot/usr/${libdir_to_keep}/libc*so* ${arch}/sysroot/${libdir_to_keep}
cp ${arch}/sysroot/usr/${libdir_to_keep}/libm.so* ${arch}/sysroot/${libdir_to_keep}
cp ${arch}/sysroot/usr/${libdir_to_keep}/libmvec.so* ${arch}/sysroot/${libdir_to_keep} || /bin/true # Does not exist on arm

if [ -L ${arch}/sysroot/usr/${libdir_to_keep} ]; then
rm ${arch}/sysroot/usr/${libdir_to_keep}
mv ${arch}/sysroot/usr/${libdir_to_remove} ${arch}/sysroot/usr/${libdir_to_keep}
mkdir ${arch}/sysroot/usr/${libdir_to_remove}
mv ${arch}/sysroot/usr/${libdir_to_keep}/crt*.o ${arch}/sysroot/usr/${libdir_to_remove}
mv ${arch}/sysroot/usr/${libdir_to_keep}/pkgconfig ${arch}/sysroot/usr/${libdir_to_remove}
# But why tho
mv ${arch}/sysroot/usr/${libdir_to_keep}/pulseaudio ${arch}/sysroot/usr/${libdir_to_remove}
fi

mkdir -p ${arch}/sysroot/${libdir_to_remove}
cp ${arch}/sysroot/usr/${libdir_to_keep}/ld-linux*so* ${arch}/sysroot/${libdir_to_remove} # aarch64 apparently wants ld-linux.so in /lib not /lib64?

ln -s ${arch}-gcc bin/gcc
ln -s ${arch}-gcc.br_real bin/gcc.br_real
ln -s ${arch}-g++ bin/g++
ln -s ${arch}-g++.br_real bin/g++.br_real
ln -s ${arch}-cpp bin/cpp
ln -s ${arch}-cpp.br_real bin/cpp.br_real
ln -s ${arch}-ar bin/ar
ln -s ${arch}-ranlib bin/ranlib
ln -s ${arch}-gcc-ar bin/gcc-ar
ln -s ${arch}-gcc-ranlib bin/gcc-ranlib

find -name *python2* -exec rm -rf {} \; || true

Loading