Skip to content

Instantly share code, notes, and snippets.

@ArseniyShestakov
Last active November 23, 2016 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArseniyShestakov/39261e5d268cd7c021b0 to your computer and use it in GitHub Desktop.
Save ArseniyShestakov/39261e5d268cd7c021b0 to your computer and use it in GitHub Desktop.
VCMI cross compilation from Linux to Windows using MXE
## Building VCMI for Windows from Linux.
#
# Building of Qt5 make process a lot longer.
# Likely you only need game client so build without launcher.
#
# More comments available in forum topic:
# http://forum.vcmi.eu/viewtopic.php?p=14756#14756
# This one is now documented on Wiki:
# http://wiki.vcmi.eu/index.php?title=How_to_build_VCMI_(Linux/Cmake/MXE)
# Dependencies from MXE website:
apt-get install autoconf automake autopoint bash bison bzip2 cmake flex gettext git g++ gperf intltool libffi-dev libgdk-pixbuf2.0-dev libtool libltdl-dev libssl-dev libxml-parser-perl make openssl p7zip-full patch perl pkg-config python ruby scons sed unzip wget xz-utils
apt-get install g++-multilib libc6-dev-i386
mkdir /home/test
cd /home/test
git clone https://github.com/mxe/mxe.git
cd mxe
# edit "settings.mk"
nano settings.mk
# Uncomment "MXE_TARGETS" and make it look like that:
MXE_TARGETS := i686-w64-mingw32.shared
# To build without launcher:
make -j 9 gcc boost zlib sdl2 sdl2_gfx sdl2_image sdl2_mixer sdl2_ttf ffmpeg
# To build with launcher:
make -j 9 gcc boost zlib sdl2 sdl2_gfx sdl2_image sdl2_mixer sdl2_ttf ffmpeg qt5
cd ..
git clone https://github.com/vcmi/vcmi.git
mkdir vcmi-build
mkdir vcmi-shared
cd vcmi-shared
# To build without launcher:
cmake ../vcmi -DCMAKE_TOOLCHAIN_FILE=/home/test/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake -DCMAKE_INSTALL_PREFIX=/home/test/vcmi-build -DENABLE_LAUNCHER=0
# With launcher:
cmake ../vcmi -DCMAKE_TOOLCHAIN_FILE=/home/test/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake -DCMAKE_INSTALL_PREFIX=/home/test/vcmi-build
make -j 9
# Once compilation finished you may get all DLLs in single directory this way:
make install
# Remove useless parts:
rm -rf /home/test/vcmi-build/home
rm -rf /home/test/vcmi-build/include
rm -rf /home/test/vcmi-build/lib
rm /home/test/vcmi-build/vcmibuilder
#!/usr/bin/php
<?php
$opts = [
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: PHP'
]
]
];
$context = stream_context_create($opts);
$contents = file_get_contents('https://api.github.com/repos/vcmi/vcmi/pulls?state=open', false, $context);
if(strlen($contents))
{
$json = json_decode($contents, true);
foreach($json as $pr)
{
system('/home/mxe/builduploader-pr.sh ' . $pr['number']);
}
}
#!/bin/bash
if [ -z "$1" ]
then
echo "PR number \$1 is empty."
exit 0
else
prid="$1"
fi
# TODO: Fix issues with deps checker case sensetivity
files=( VCMI_client.exe VCMI_server.exe VCMI_launcher.exe AI/BattleAI.dll AI/EmptyAI.dll AI/StupidAI.dll AI/VCAI.dll smpeg2.dll ssleay32.dll libeay32.dll )
useless_files=( include lib home vcmibuilder )
files_checked=()
local_directory="/home/mxe"
remote_directory="/home/vcmibuilds/web/windows/PR/$prid/"
file_mxe_cmake="$local_directory/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake"
file_latest="$local_directory/latest-pr-$prid.txt"
file_ongoing="$local_directory/BUILD_LOCK_PR"
dir_src="$local_directory/vcmi-pr/"
dir_cmake="$local_directory/vcmi-pr-cmake/"
dir_build="$local_directory/vcmi-pr-build/"
if [ -f $file_ongoing ]; then
echo "Other build is going, stopping!"
exit 0
else
echo "ONGOING" > $file_ongoing
fi
cd $local_directory
#################### Initialize build environment
#################### Update repository
cd $dir_src
git checkout develop
git pull
git branch -D "pr$prid"
git fetch upstream "pull/$prid/head:pr$prid"
git checkout "pr$prid"
previous_hash=`cat $file_latest`
current_hash=`git log --format="%H" -n 1`
if [ "$previous_hash" == "$current_hash" ] ; then
echo "Repository didn't change, stopping!"
rm $file_ongoing
exit 0
fi
#################### Removing previous build
rm -rf $dir_cmake
rm -rf $dir_build
mkdir $dir_cmake
mkdir $dir_build
#################### Making a build
cd $dir_cmake
cmake $dir_src -DCMAKE_TOOLCHAIN_FILE=$file_mxe_cmake -DCMAKE_INSTALL_PREFIX=$dir_build -DENABLE_TEST=0
# Disturb me less if more than one VM is running
qemu_count=`pgrep -c qemu-system-x86`
if [ "$qemu_count" -ge "2" ]
then
echo "Found more than two QEMUs. Using slow build..."
make -j 2
else
make -j 9
fi
make install
#################### Cleaning everything
cd $local_directory
is_checked(){
for checked_file in "${files_checked[@]}"
do
if [ "$checked_file" == "$1" ] ; then
return 0
fi
done
return 1
}
check_deps(){
echo "Checking deps of: $1"
check_fullpath="$dir_build/$1"
files_checked+=( $1 )
deps=($(objdump -p $check_fullpath | grep 'DLL Name:' | awk '{print $3}' | sed 's/:.*//'))
for dep in "${deps[@]}"
do
if is_checked $dep ; then
echo "Dep: $dep - checked already"
else
echo "Dep: $dep - not yet checked"
check_deps $dep
fi
done
}
# Remove symlinks
find $dir_build -type l -exec rm -f {} \;
# Remove useless directories and files
for useless_file in "${useless_files[@]}"
do
removepath="$dir_build/$useless_file"
echo "Remove useless directory / file $removepath"
rm -rf $removepath
done
# Check dependencies of each file
for checkfile in "${files[@]}"
do
check_deps $checkfile
done
# Remove useless files
arr=($dir_build/*.dll)
for somefile in "${arr[@]}"
do
somefile=${somefile##*/}
if is_checked $somefile ; then
echo "Keep useful file $somefile"
else
echo "Remove useless file $somefile"
rm "$dir_build/$somefile"
fi
done
#################### Create archive
archive_filename="vcmi-build-pr$prid-$current_hash.7z"
7z a -t7z $archive_filename -m0=lzma2 -mx=9 -aoa $dir_build
#################### Upload on server
rsync -axSRzvI $archive_filename vcmi:$remote_directory
#################### Cleanup
echo "$current_hash" > $file_latest
rm $file_ongoing
rm $archive_filename
#!/bin/bash
# 0 6,17 * * * /home/mxe/builduploader.sh
# TODO: Fix issues with deps checker case sensetivity
files=( VCMI_client.exe VCMI_server.exe VCMI_launcher.exe AI/BattleAI.dll AI/EmptyAI.dll AI/StupidAI.dll AI/VCAI.dll smpeg2.dll ssleay32.dll libeay32.dll )
useless_files=( include lib home vcmibuilder )
files_checked=()
local_directory="/home/mxe"
remote_directory="/home/vcmibuilds/web/windows/"
file_mxe_cmake="$local_directory/mxe/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake"
file_latest="$local_directory/latest.txt"
file_ongoing="$local_directory/BUILD_LOCK"
dir_src="$local_directory/vcmi/"
dir_cmake="$local_directory/vcmi/vcmi-shared/"
dir_build="$local_directory/vcmi-build/"
if [ -f $file_ongoing ];
then
echo "Other build is going, stopping!"
exit 0
else
echo "ONGOING" > $file_ongoing
fi
cd $local_directory
#################### Initialize build environment
#################### Update repository
cd $dir_src
git pull
previous_hash=`cat $file_latest`
current_hash=`git log --format="%H" -n 1`
if [ "$previous_hash" == "$current_hash" ] ; then
echo "Repository didn't change, stopping!"
exit 0
fi
#################### Removing previous build
rm -rf $dir_cmake
rm -rf $dir_build
mkdir $dir_cmake
mkdir $dir_build
#################### Making a build
cd $dir_cmake
cmake $dir_src -DCMAKE_TOOLCHAIN_FILE=$file_mxe_cmake -DCMAKE_INSTALL_PREFIX=$dir_build -DENABLE_TEST=0
# Disturb me less if more than one VM is running
qemu_count=`pgrep -c qemu-system-x86`
if [ "$qemu_count" -ge "2" ]
then
echo "Found more than two QEMUs. Using slow build..."
make -j 2
else
make -j 9
fi
make install
#################### Cleaning everything
cd $local_directory
is_checked(){
for checked_file in "${files_checked[@]}"
do
if [ "$checked_file" == "$1" ] ; then
return 0
fi
done
return 1
}
check_deps(){
echo "Checking deps of: $1"
check_fullpath="$dir_build/$1"
files_checked+=( $1 )
deps=($(objdump -p $check_fullpath | grep 'DLL Name:' | awk '{print $3}' | sed 's/:.*//'))
for dep in "${deps[@]}"
do
if is_checked $dep ; then
echo "Dep: $dep - checked already"
else
echo "Dep: $dep - not yet checked"
check_deps $dep
fi
done
}
# Remove symlinks
find $dir_build -type l -exec rm -f {} \;
# Remove useless directories and files
for useless_file in "${useless_files[@]}"
do
removepath="$dir_build/$useless_file"
echo "Remove useless directory / file $removepath"
rm -rf $removepath
done
# Check dependencies of each file
for checkfile in "${files[@]}"
do
check_deps $checkfile
done
# Remove useless files
arr=($dir_build/*.dll)
for somefile in "${arr[@]}"
do
somefile=${somefile##*/}
if is_checked $somefile ; then
echo "Keep useful file $somefile"
else
echo "Remove useless file $somefile"
rm "$dir_build/$somefile"
fi
done
#################### Create archive
archive_filename="vcmi-build-$current_hash.7z"
7z a -t7z $archive_filename -m0=lzma2 -mx=9 -aoa $dir_build
#################### Upload on server
rsync -axSRzvI $archive_filename vcmi:$remote_directory
#################### Cleanup
echo "$current_hash" > $file_latest
rm $file_ongoing
rm $archive_filename
#!/bin/bash
# Cron entry on storage server:
# 30 23 * * * /home/vcmibuilds/cronremover.sh
num=`find /home/vcmibuilds/web/windows/*.7z -type f | wc -l`
if (( num > 15 )); then
find /home/vcmibuilds/web/windows/*.7z -type f -mtime +7 -exec rm {} \;
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment