Skip to content

Commit

Permalink
scripts to build toolchain added
Browse files Browse the repository at this point in the history
  • Loading branch information
dkimitsa committed Dec 13, 2017
1 parent 4a2bdb6 commit bd46edb
Show file tree
Hide file tree
Showing 31 changed files with 1,837 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RoboVM ToolChain

This repo contains builds scripts used to compile/crosscompile toolchain utilities used to enable RoboVM compilation on Windows/Linux
RoboVM branch for Windows/Linux is [here](https://github.com/dkimitsa/robovm/tree/linuxwindows)

## Build
To build there is build.sh script that will build all tools for all platrforms available.
See options (run ./build --helps) to limit/customize build
After binaries are built they can be packed into archives with ./seal.sh

## Host system
Toolchain was successfuly compiled in ArchLinux 2017.11.01
Tools were used: GCC 7.2.0, mingw 7.2.0

## License
Scripts itself are GPL2 but binaries that are produced are covered by corresponding Project's license
121 changes: 121 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/bin/bash
set -e

SELF=$(basename $0)
BASE=$(cd $(dirname $0); pwd -P)
SUPORTED_TARGETS=("macosx-x86_64" "linux-x86_64" "linux-x86" "windows-x86_64" "windows-x86")
DEFAULT_TARGETS=("linux-x86_64" "linux-x86" "windows-x86_64" "windows-x86")
SUPORTED_TOOLS=("llvm" "libmd" "ld64" "llvm-dsym" "xcbuild" "file" "xib2nib" "deps")


function usage {
cat <<EOF
Usage: $SELF [options] [target1] [target2] ...
Supported targets: "${SUPORTED_TARGETS[*]}"
Supported tools: "${SUPORTED_TOOLS[*]}"
Options:
--help Displays this information and exits.
[target] target to build
[tool] tool to build
EOF
exit $1
}

function arrayContainsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}

TARGETS=()
TOOLS=()

for arg in "$@"
do
case $arg in
'--help')
usage 0
;;
*)
if arrayContainsElement "$arg" "${SUPORTED_TARGETS[@]}"; then
TARGETS+=("$arg")
elif arrayContainsElement "$arg" "${SUPORTED_TOOLS[@]}"; then
TOOLS+=("$arg")
else
echo "Unrecognized option or syntax error in option '$arg'"
usage 1
fi
;;
esac
done

if [ ${#TARGETS[@]} -eq 0 ]; then
TARGETS=(${DEFAULT_TARGETS[*]})
fi
if [ ${#TOOLS[@]} -eq 0 ]; then
TOOLS=(${SUPORTED_TOOLS[*]})
fi

# the template for subscripts to properly make destination install directory
# as defined in SUPORTED_TARGETS
INSTALL_DIR="${BASE}/bin/_OS_-_ARCH_/"
# pre-create bin directories
for T in ${TARGETS[@]}; do
mkdir -p "${BASE}/bin/${T}"
done

echo "--------------"
echo "Building tools ${TOOLS[*]} for ${TARGETS[*]}"
echo "--------------"

# building tools one by one
if arrayContainsElement "llvm" "${TOOLS[@]}"; then
echo "Building LLVM for ${TARGETS[*]}"
llvm/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "libmd" "${TOOLS[@]}"; then
echo "Building libmobiledev for ${TARGETS[*]}"
libmd/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "ld64" "${TOOLS[@]}"; then
echo "Building cctools/ld64 for ${TARGETS[*]}"
ld64/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "llvm-dsym" "${TOOLS[@]}"; then
echo "Building llvm-dsym for ${TARGETS[*]}"
llvm-dsym/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "xcbuild" "${TOOLS[@]}"; then
echo "Building xcbuild for ${TARGETS[*]}"
xcbuild/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "file" "${TOOLS[@]}"; then
echo "Building unix file for ${TARGETS[*]}"
file/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "xib2nib" "${TOOLS[@]}"; then
echo "Building xib2nib file for ${TARGETS[*]}"
xib2nib/build.sh --clean --postclean "--install=${INSTALL_DIR}" ${TARGETS[*]}
fi

if arrayContainsElement "deps" "${TOOLS[@]}"; then
if arrayContainsElement "windows-x86_64" "${TARGETS[@]}"; then
echo "Copy dependencies windows-x86_64..."
cp -f /usr/x86_64-w64-mingw32/bin/libwinpthread-1.dll "${BASE}/bin/windows-x86_64/"
cp -f /usr/x86_64-w64-mingw32/bin/libgcc_s_seh-1.dll "${BASE}/bin/windows-x86_64/"
cp -f /usr/x86_64-w64-mingw32/bin/libstdc++-6.dll "${BASE}/bin/windows-x86_64/"
fi
if arrayContainsElement "windows-x86" "${TARGETS[@]}"; then
echo "Copy dependencies windows-x86..."
cp -f /usr/i686-w64-mingw32/bin/libwinpthread-1.dll "${BASE}/bin/windows-x86/"
cp -f /usr/i686-w64-mingw32/bin/libgcc_s_sjlj-1.dll "${BASE}/bin/windows-x86/"
cp -f /usr/i686-w64-mingw32/bin/libstdc++-6.dll "${BASE}/bin/windows-x86/"
fi
fi
73 changes: 73 additions & 0 deletions file/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
cmake_minimum_required(VERSION 2.8)
include(ExternalProject)

# Parameters to be specified from command line
# OS name
# INSTALL_DIR if required to override

if(NOT DEFINED OS)
message(FATAL_ERROR "Please specify an os (macosx, linux, windows), e.g. -DOS=linux")
elseif(OS STREQUAL "windows")
set(WINDOWS YES)
set(DLIB_SUFFIX ".dll")
set(EXE_SUFFIX ".exe")
else()
message(FATAL_ERROR "Not supported OS ${OS}" )
endif()

if(NOT DEFINED ARCH)
set(ARCH "x86_64")
set(X86_64 YES)
elseif (ARCH STREQUAL "x86")
set(X86 YES)
elseif (ARCH STREQUAL "x86_64")
set(X86_64 YES)
else()
message(FATAL_ERROR "Not supported ARCH ${ARCH}")
endif()

if(WINDOWS)
if(NOT DEFINED MINGW_VARIANT)
message(FATAL_ERROR "Please setup MINGW_VARIANT, e.g. -DMINGW_VARIANT=x86_64-w64-mingw32 variable")
endif()
set(TENTATIVE_CROSS_COMPILE_HOST "--host=${MINGW_VARIANT}")
endif()

project(robovm-unix-file)

message (STATUS "OS=${OS}")
message (STATUS "ARCH=${ARCH}")

set(EXTPREFIX "${CMAKE_BINARY_DIR}/ext")

ExternalProject_Add(pcre2ext
URL https://ftp.pcre.org/pub/pcre/pcre2-10.30.zip
CONFIGURE_COMMAND bash -c "./configure ${TENTATIVE_CROSS_COMPILE_HOST} --prefix=${EXTPREFIX} --enable-shared=no"
BUILD_IN_SOURCE 1
)

ExternalProject_Add(extfile
URL https://github.com/file/file/archive/FILE5_32.tar.gz
PATCH_COMMAND bash -c "${CMAKE_SOURCE_DIR}/patches/apply-patches"
CONFIGURE_COMMAND bash -c "autoreconf --install && ./configure LDFLAGS=\"-static -L${EXTPREFIX}/lib\" CFLAGS=\"-DPCRE2_STATIC -I${EXTPREFIX}/include\" --host=${MINGW_VARIANT} --prefix=${EXTPREFIX}"
BUILD_IN_SOURCE 1
DEPENDS pcre2ext
)

add_custom_target(robovm-unix-file)
add_dependencies(robovm-unix-file extfile)

if (DEFINED INSTALL_DIR)
# replace template with values
string(REPLACE "_OS_" "${OS}" INSTALL_DIR ${INSTALL_DIR})
string(REPLACE "_ARCH_" "${ARCH}" INSTALL_DIR ${INSTALL_DIR})
message (STATUS "Custom install dir=${INSTALL_DIR}")

add_custom_command(TARGET robovm-unix-file POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
${EXTPREFIX}/bin/file${EXE_SUFFIX}
${INSTALL_DIR})
add_custom_command(TARGET robovm-unix-file POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
${EXTPREFIX}/share/misc/magic.mgc
${INSTALL_DIR})
endif(DEFINED INSTALL_DIR)

110 changes: 110 additions & 0 deletions file/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash

SELF=$(basename $0)
BASE=$(cd $(dirname $0); pwd -P)
SUPORTED_TARGETS=("macosx-x86_64" "linux-x86_64" "linux-x86" "windows-x86_64" "windows-x86")
# targets that already has file implementation
OMIT_TARGETS=("macosx-x86_64" "linux-x86_64" "linux-x86")
CLEAN=0
POSTCLEAN=0
WORKERS=1
SUFFIX=unix-file
CMAKE_INSTALL_DIR=

function usage {
cat <<EOF
Usage: $SELF [options] [target1] [target2] ...
Supported targets: "${SUPORTED_TARGETS[*]}"
Options:
--clean Cleans the build dir before starting the build.
--help Displays this information and exits.
--postclean Cleans the build dir after performing the build
--install=/<OS>/<ARCH> Sets custom intstall path, <OS> and <ARCH> will be replaced with proper values
[target] target to build
EOF
exit $1
}

function arrayContainsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}

TARGETS=()
SKIPPED_TARGETS=()

for arg in "$@"
do
case $arg in
'--clean') CLEAN=1 ;;
'--postclean') POSTCLEAN=1 ;;
'--install='* )
CMAKE_INSTALL_DIR="-DINSTALL_DIR=${arg#*=}"
;;
'--help')
usage 0
;;
*)
if arrayContainsElement "$arg" "${SUPORTED_TARGETS[@]}"; then
if arrayContainsElement "$arg" "${OMIT_TARGETS[@]}"; then
echo "Skipping $arg"
SKIPPED_TARGETS+=("$arg")
else
TARGETS+=("$arg")
fi
else
echo "Unrecognized option or syntax error in option '$arg'"
usage 1
fi
;;
esac
done

if [ ${#TARGETS[@]} -eq 0 ]; then
if [ ${#SKIPPED_TARGETS[@]} -ne 0 ]; then
exit 0
fi
echo "No target specified !"
usage 1
fi

mkdir -p "$BASE/target.${SUFFIX}/build"

for T in ${TARGETS[@]}; do
OS=${T%%-*}
ARCH=${T#*-}
BUILD_TYPE=Release
MAKE=make
case "$T" in
"windows-x86_64")
CMAKE_PARAMS="-DMINGW_VARIANT=x86_64-w64-mingw32"
;;
"windows-x86")
CMAKE_PARAMS="-DMINGW_VARIANT=i686-w64-mingw32"
;;
esac

echo "Building target $T with params: $CMAKE_PARAMS $CMAKE_INSTALL_DIR"
# clean before build
if [ "$CLEAN" = '1' ]; then
rm -rf "$BASE/target.${SUFFIX}/build/$T"
fi
mkdir -p "$BASE/target.${SUFFIX}/build/$T"
if [ -z "$CMAKE_INSTALL_DIR" ]; then
# there is no override in install location, so just
rm -rf "$BASE/binaries/$OS/$ARCH"
fi
bash -c "cd '$BASE/target.${SUFFIX}/build/$T'; cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DOS=$OS -DARCH=$ARCH $CMAKE_PARAMS $CMAKE_INSTALL_DIR '$BASE'; $MAKE robovm-unix-file"
R=$?
if [[ $R != 0 ]]; then
echo "$T build failed"
exit $R
fi
# clean after build
if [ "$POSTCLEAN" = '1' ]; then
rm -rf "$BASE/target.${SUFFIX}/build/$T"
fi
done

48 changes: 48 additions & 0 deletions file/patches/01-gnurx-to-pcre2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
diff -ur a/configure.ac b/configure.ac
--- a/configure.ac 2017-09-02 11:54:09.000000000 +0300
+++ b/configure.ac 2017-11-21 14:21:29.760641012 +0200
@@ -159,7 +159,7 @@
AC_CHECK_LIB(z, gzopen)
fi
if test "$MINGW" = 1; then
- AC_CHECK_LIB(gnurx,regexec,,AC_MSG_ERROR([libgnurx is required to build file(1) with MinGW]))
+ AC_CHECK_LIB([pcre2-8], [pcre2_config_8])
fi

dnl See if we are cross-compiling
diff -ur a/src/file.h b/src/file.h
--- a/src/file.h 2017-09-02 11:54:09.000000000 +0300
+++ b/src/file.h 2017-11-21 14:21:51.523974346 +0200
@@ -63,7 +63,7 @@
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
-#include <regex.h>
+#include <pcre2posix.h>
#include <time.h>
#include <sys/types.h>
#ifndef WIN32
diff -ur a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am 2017-09-02 11:54:09.000000000 +0300
+++ b/src/Makefile.am 2017-11-21 14:22:12.487307679 +0200
@@ -13,7 +13,7 @@
file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h
libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0
if MINGW
-MINGWLIBS = -lgnurx -lshlwapi
+MINGWLIBS = -lpcre2-8 -lpcre2-posix -lshlwapi
else
MINGWLIBS =
endif
diff -ur a/magic/Makefile.am b/magic/Makefile.am
--- a/magic/Makefile.am 2017-09-02 11:54:09.000000000 +0300
+++ b/magic/Makefile.am 2017-11-21 14:42:31.667594346 +0200
@@ -301,7 +301,7 @@
# FIXME: Build file natively as well so that it can be used to compile
# the target's magic file; for now we bail if the local version does not match
if IS_CROSS_COMPILE
-FILE_COMPILE = file${EXEEXT}
+FILE_COMPILE = file
FILE_COMPILE_DEP =
else
FILE_COMPILE = $(top_builddir)/src/file${EXEEXT}
6 changes: 6 additions & 0 deletions file/patches/apply-patches
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

BASE=$(cd $(dirname $0); pwd -P)
ls "$BASE"/*.patch | sort | while read p; do
patch -p1 -t -N < $p
done
Loading

0 comments on commit bd46edb

Please sign in to comment.