Add Windows support and clean up toolchain #10

Open
harraiken wants to merge 37 commits from multiplatform into master
16 changed files with 783 additions and 3446 deletions

View File

@ -3,18 +3,27 @@ run-name: ${{ github.actor }} runs Gitea Actions
on: [push]
jobs:
XTChain:
XTchain:
strategy:
matrix:
target: [linux, windows]
build: [full, minimal]
runs-on: oscw
container:
image: codingworkshop/oscw-runner:latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Build XTChain
run: CORES=10 ./build-linux.sh
- name: Build XTchain
run: |
if [ "${{ matrix.build }}" == "minimal" ]; then
./build.sh --jobs=10 --target=${{ matrix.target }} --minimal
else
./build.sh --jobs=10 --target=${{ matrix.target }}
fi
- name: Publish binaries
if: startsWith(github.ref, 'refs/tags/')
env:
OSCW_GITHUB_USERNAME: ${{ secrets.OSCW_GITHUB_USERNAME }}
OSCW_GITHUB_PASSWORD: ${{ secrets.OSCW_GITHUB_PASSWORD }}
run: github_publish $OSCW_GITHUB_USERNAME $OSCW_GITHUB_PASSWORD $(ls xtchain-*-linux.tar.zst)
run: github_publish $OSCW_GITHUB_USERNAME $OSCW_GITHUB_PASSWORD $(ls xtchain-*-${{ matrix.target }}.*)

View File

@ -22,31 +22,28 @@
---
## XT Toolchain
This is a LLVM/Clang/LLD based mingw-w64 toolchain. It currently supports C and C++, and provides
a variety of tools including IDL, message and resource compilers. The XT Toolchain is also the
official build environment for compiling XT software, including the XT OS. Currently, it is
targeted at Linux host only, however it should be possible to build it in MSYS2 as well.
The XT Toolchain is a build environment based on LLVM/Clang/LLD. It currently supports C and C++, and includes
a variety of auxiliary tools such as IDL, message, and resource compilers. The XT Toolchain is the official
build system for compiling XT software, including the XT OS. It is currently available for Linux and Windows
host systems.
Benefits of a LLVM based MinGW toolchain are:
* Single toolchain targeting all architectures (i686, x86_64, armv7 and aarch64),
* Support for generating debug info in PDB format,
* Support for targeting ARM/AARCH64 architectures and ability to produce Windows ARM binaries.
Key Benefits of using an LLVM-based Toolchain:
* Unified toolchain for multiple target architectures: i686, x86_64, armv7, and aarch64
* Support for generating debug information in PDB format
* Ability to target ARM/AArch64 architectures and produce ARM binaries
This software includes:
This toolchain includes the following software:
* CMake
* GNU Assembler
* LLVM
* Make
* Mingw-w64
* Ninja
* Wine
This software is based on [LLVM MinGW Toolchain](https://github.com/mstorsjo/llvm-mingw).
**Note:** This toolchain is based on the [LLVM MinGW Toolchain](https://github.com/mstorsjo/llvm-mingw).
## Licensing
The XTchain project includes the scripts for building and assembling a toolchain as well as wrappers
for LLVM tools and environmental shell. These are licensed under the GPLv3 license. It covers only
mentioned components that are provided by XTchain directly. For more information on that, refer to
the COPYING.md file. The final pre-built toolchain is covered by the licenses of the individual,
external projects. The full list of software incorporated into this toolchain is available in the
README.md file.
The XTchain project includes scripts for building and assembling the toolchain, as well as the environment
shell. These components are licensed under the GNU GPLv3 license. This license applies only to the parts
provided directly by XTchain. For detailed information, please refer to the COPYING.md file.
The final pre-built toolchain is subject to the licenses of the individual third-party projects it includes.
A complete list of the external software used in this toolchain can be found in the README.md file.

View File

@ -1,566 +0,0 @@
#!/bin/bash
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: build-linux.sh
# DESCRIPTION: Toolchain building and assembly script
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
# Working Directories
BINDIR="$(pwd)/binaries"
PCHDIR="$(pwd)/patches"
SRCDIR="$(pwd)/sources"
WRKDIR="$(pwd)"
# Architecture Settings
ARCHS="aarch64 armv7 i686 x86_64"
GENERIC="generic-w64-mingw32"
# CMake Settings
CMAKEDIR="${SRCDIR}/cmake"
CMAKETAG="v3.31.3"
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
# LLVM Settings
LLVMDIR="${SRCDIR}/llvm"
LLVMTAG="llvmorg-19.1.6"
LLVMVCS="https://github.com/llvm/llvm-project.git"
# Make Settings
MAKEDIR="${SRCDIR}/make"
MAKETAG="4.4.1"
MAKEVCS="git://git.savannah.gnu.org/make"
# Mingw-w64 Settings
MINGWDIR="${SRCDIR}/mingw-w64"
MINGWLIB="ucrt"
MINGWTAG="master"
MINGWNTV="0x601"
MINGWVCS="https://github.com/mirror/mingw-w64.git"
# Ninja Settings
NINJADIR="${SRCDIR}/ninja"
NINJATAG="v1.12.1"
NINJAVCS="https://github.com/ninja-build/ninja.git"
# Wine Settings
WINEDIR="${SRCDIR}/wine"
WINETAG="wine-9.8"
WINEVCS="https://github.com/wine-mirror/wine.git"
# This function applies a patches to the 3rd party project
apply_patches()
{
local PACKAGE="${1}"
local VERSION="${2}"
if [ -d "${PCHDIR}/${PACKAGE}/${VERSION}" ]; then
PATCHES="$(find ${PCHDIR}/${PACKAGE}/${VERSION} -name '*.diff' -o -name '*.patch' | sort -n)"
echo ">>> Applying custom patches ..."
for PATCH in ${PATCHES}; do
if [ -f "${PATCH}" ] && [ -r "${PATCH}" ]; then
for PREFIX in {0..5}; do
if patch -i${PATCH} -p${PREFIX} --silent --dry-run >/dev/null; then
patch -i${PATCH} -p${PREFIX} --silent
echo ">>> Patch ${PATCH} applied ..."
break;
elif [ ${PREFIX} -ge 5 ]; then
echo "Patch ${PATCH} does not fit. Failed applying patch ..."
return 1
fi
done
fi
done
fi
}
# This function compiles and installs CMAKE
cmake_build()
{
echo ">>> Building CMAKE ..."
[ -z ${CLEAN} ] || rm -rf ${CMAKEDIR}/build-${GENERIC}
mkdir -p ${CMAKEDIR}/build-${GENERIC}
cd ${CMAKEDIR}/build-${GENERIC}
../bootstrap \
--prefix=${BINDIR} \
--parallel=${CORES} \
-- -DCMAKE_USE_OPENSSL=OFF
make -j${CORES}
make install
cd ${WRKDIR}
}
# This function downloads CMAKE from VCS
cmake_fetch()
{
if [ ! -d ${CMAKEDIR} ]; then
echo ">>> Downloading CMAKE ..."
git clone --depth 1 --branch ${CMAKETAG} ${CMAKEVCS} ${CMAKEDIR}
cd ${CMAKEDIR}
apply_patches ${CMAKEDIR##*/} ${CMAKETAG}
cd ${WRKDIR}
fi
}
# This function compiles and install LLVM
llvm_build()
{
echo ">>> Building LLVM ..."
[ -z ${CLEAN} ] || rm -rf ${LLVMDIR}/llvm/build
LLVM_ARCHS=()
for ARCH in ${ARCHS}; do
case ${ARCH} in
"aarch64")
LLVM_ARCHS+=( "AArch64" )
;;
"armv7")
LLVM_ARCHS+=( "ARM" )
;;
"i686"|"x86_64")
LLVM_ARCHS+=( "X86" )
;;
esac
done
LLVM_ARCHS=( $(for ARCH in ${LLVM_ARCHS[@]}; do echo ${ARCH}; done | sort -u) )
cd ${LLVMDIR}/llvm/tools
for UTIL in clang lld; do
if [ ! -e ${UTIL} ]; then
ln -sf ../../${UTIL} .
fi
done
mkdir -p ${LLVMDIR}/llvm/build
cd ${LLVMDIR}/llvm/build
cmake -G Ninja \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_INSTALL_PREFIX=${BINDIR} \
-DLLDB_INCLUDE_TESTS=FALSE \
-DLLVM_ENABLE_ASSERTIONS=FALSE \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb" \
-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
-DLLVM_LINK_LLVM_DYLIB=ON \
-DLLVM_TARGETS_TO_BUILD="$(echo ${LLVM_ARCHS[@]} | tr ' ' ';')" \
-DLLVM_TOOLCHAIN_TOOLS="llvm-addr2line;llvm-ar;llvm-as;llvm-cov;llvm-cvtres;llvm-dlltool;llvm-lib;llvm-ml;llvm-nm;llvm-objdump;llvm-objcopy;llvm-pdbutil;llvm-profdata;llvm-ranlib;llvm-rc;llvm-readelf;llvm-readobj;llvm-strings;llvm-strip;llvm-symbolizer;llvm-windres" \
..
ninja install/strip
cd ${WRKDIR}
}
# This function compiles and install LIBCXX & LIBUNWIND
llvm_build_libs()
{
echo ">>> Building LLVM libraries (libcxx) ..."
for ARCH in ${ARCHS}; do
[ -z ${CLEAN} ] || rm -rf ${LLVMDIR}/runtimes/build-${ARCH}
mkdir -p ${LLVMDIR}/runtimes/build-${ARCH}
cd ${LLVMDIR}/runtimes/build-${ARCH}
cmake -G Ninja \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_INSTALL_PREFIX="${BINDIR}/${ARCH}-w64-mingw32" \
-DCMAKE_AR="${BINDIR}/bin/llvm-ar" \
-DCMAKE_C_COMPILER="${BINDIR}/bin/${ARCH}-w64-mingw32-clang" \
-DCMAKE_C_COMPILER_WORKS=1 \
-DCMAKE_C_FLAGS_INIT=-mguard=cf \
-DCMAKE_CXX_COMPILER="${BINDIR}/bin/${ARCH}-w64-mingw32-clang++" \
-DCMAKE_CXX_COMPILER_TARGET=${ARCH}-w64-windows-gnu \
-DCMAKE_CXX_COMPILER_WORKS=1 \
-DCMAKE_CXX_FLAGS_INIT=-mguard=cf \
-DCMAKE_CROSSCOMPILING=TRUE \
-DCMAKE_RANLIB="${BINDIR}/bin/llvm-ranlib" \
-DCMAKE_SYSTEM_NAME="Windows" \
-DLLVM_PATH="${LLVMDIR}/llvm" \
-DLLVM_ENABLE_RUNTIMES="libunwind;libcxxabi;libcxx" \
-DLIBUNWIND_USE_COMPILER_RT=TRUE \
-DLIBUNWIND_ENABLE_SHARED=TRUE \
-DLIBUNWIND_ENABLE_STATIC=TRUE \
-DLIBCXX_USE_COMPILER_RT=ON \
-DLIBCXX_ENABLE_SHARED=TRUE \
-DLIBCXX_ENABLE_STATIC=TRUE \
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE \
-DLIBCXX_CXX_ABI="libcxxabi" \
-DLIBCXX_LIBDIR_SUFFIX="" \
-DLIBCXX_INCLUDE_TESTS=FALSE \
-DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=FALSE \
-DLIBCXXABI_USE_COMPILER_RT=ON \
-DLIBCXXABI_ENABLE_SHARED=OFF \
-DLIBCXXABI_LIBDIR_SUFFIX="" \
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
..
ninja
ninja install
done
cd ${WRKDIR}
}
# This function compiles and install LLVM runtime
llvm_build_runtime()
{
echo ">>> Building LLVM compiler runtime ..."
for ARCH in ${ARCHS}; do
[ -z ${CLEAN} ] || rm -rf ${LLVMDIR}/compiler-rt/build-${ARCH}
mkdir -p ${LLVMDIR}/compiler-rt/build-${ARCH}
cd ${LLVMDIR}/compiler-rt/build-${ARCH}
cmake -G Ninja \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_AR="${BINDIR}/bin/llvm-ar" \
-DCMAKE_C_COMPILER="${BINDIR}/bin/${ARCH}-w64-mingw32-clang" \
-DCMAKE_C_COMPILER_TARGET="${ARCH}-windows-gnu" \
-DCMAKE_C_FLAGS_INIT="-mguard=cf" \
-DCMAKE_CXX_COMPILER="${BINDIR}/bin/${ARCH}-w64-mingw32-clang++" \
-DCMAKE_CXX_FLAGS_INIT="-mguard=cf" \
-DCMAKE_FIND_ROOT_PATH="${BINDIR}/${ARCH}-w64-mingw32" \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
-DCMAKE_INSTALL_PREFIX=$(${BINDIR}/bin/${ARCH}-w64-mingw32-clang --print-resource-dir) \
-DCMAKE_RANLIB="${BINDIR}/bin/llvm-ranlib" \
-DCMAKE_SYSTEM_NAME="Windows" \
-DCOMPILER_RT_BUILD_BUILTINS=TRUE \
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=TRUE \
-DCOMPILER_RT_USE_BUILTINS_LIBRARY=TRUE \
-DLLVM_CONFIG_PATH="" \
-DSANITIZER_CXX_ABI="libc++" \
../lib/builtins
ninja
ninja install
done
cd ${WRKDIR}
}
# This function downloads LLVM from VCS
llvm_fetch()
{
if [ ! -d ${LLVMDIR} ]; then
echo ">>> Downloading LLVM ..."
git clone --depth 1 --branch ${LLVMTAG} ${LLVMVCS} ${LLVMDIR}
cd ${LLVMDIR}
apply_patches ${LLVMDIR##*/} ${LLVMTAG##*-}
cd ${WRKDIR}
fi
}
# This function compiles and install MAKE
make_build()
{
echo ">>> Building Make ..."
[ -z ${CLEAN} ] || rm -rf ${MAKEDIR}/build
cd ${MAKEDIR}
./bootstrap
sed -i "s/-Werror//" maintMakefile
mkdir -p ${MAKEDIR}/build
cd ${MAKEDIR}/build
../configure \
--prefix=${BINDIR} \
--disable-dependency-tracking \
--disable-silent-rules \
--program-prefix=g \
--without-guile
make -j${CORES}
make install
if [ ! -e ${BINDIR}/bin/make ]; then
ln -sf gmake ${BINDIR}/bin/make
fi
cd ${WRKDIR}
}
# This function downloads MAKE from VCS
make_fetch()
{
if [ ! -d ${MAKEDIR} ]; then
echo ">>> Downloading Make ..."
git clone --depth 1 --branch ${MAKETAG} ${MAKEVCS} ${MAKEDIR}
cd ${MAKEDIR}
apply_patches ${MAKEDIR##*/} ${MAKETAG}
cd ${WRKDIR}
fi
}
# This function compiles and installs MINGW CRT
mingw_build_crt()
{
for ARCH in ${ARCHS}; do
echo ">>> Building Mingw-W64 (CRT) for ${ARCH} ..."
[ -z ${CLEAN} ] || rm -rf ${MINGWDIR}/mingw-w64-crt/build-${ARCH}
mkdir -p ${MINGWDIR}/mingw-w64-crt/build-${ARCH}
cd ${MINGWDIR}/mingw-w64-crt/build-${ARCH}
case ${ARCH} in
"aarch64")
FLAGS="--disable-lib32 --disable-lib64 --enable-libarm64"
;;
"armv7")
FLAGS="--disable-lib32 --disable-lib64 --enable-libarm32"
;;
"i686")
FLAGS="--enable-lib32 --disable-lib64"
;;
"x86_64")
FLAGS="--disable-lib32 --enable-lib64"
;;
esac
ORIGPATH="${PATH}"
PATH="${BINDIR}/bin:${PATH}"
../configure \
--host=${ARCH}-w64-mingw32 \
--prefix=${BINDIR}/${ARCH}-w64-mingw32 \
--with-sysroot=${BINDIR} \
--with-default-msvcrt=${MINGWLIB} \
--enable-cfguard \
${FLAGS}
make -j${CORES}
make install
PATH="${ORIGPATH}"
done
cd ${WRKDIR}
}
# This function compiles and installs MINGW headers
mingw_build_headers()
{
echo ">>> Building Mingw-W64 (headers) ..."
[ -z ${CLEAN} ] || rm -rf ${MINGWDIR}/mingw-w64-headers/build-${GENERIC}
mkdir -p ${MINGWDIR}/mingw-w64-headers/build-${GENERIC}
cd ${MINGWDIR}/mingw-w64-headers/build-${GENERIC}
../configure \
--prefix=${BINDIR}/${GENERIC} \
--enable-idl \
--with-default-msvcrt=${MINGWLIB} \
--with-default-win32-winnt=${MINGWNTV}
make -j${CORES}
make install
for ARCH in ${ARCHS}; do
mkdir -p ${BINDIR}/${ARCH}-w64-mingw32
if [ ! -e ${BINDIR}/${ARCH}-w64-mingw32/include ]; then
ln -sfn ../${GENERIC}/include ${BINDIR}/${ARCH}-w64-mingw32/include
fi
done
cd ${WRKDIR}
}
# This function compiles and install MINGW libraries
mingw_build_libs()
{
for LIB in libmangle winpthreads winstorecompat; do
echo ">>> Building Mingw-w64 (libs) for ${ARCH} ..."
for ARCH in ${ARCHS}; do
[ -z ${CLEAN} ] || rm -rf ${MINGWDIR}/mingw-w64-libraries/${LIB}/build-${ARCH}
mkdir -p ${MINGWDIR}/mingw-w64-libraries/${LIB}/build-${ARCH}
cd ${MINGWDIR}/mingw-w64-libraries/${LIB}/build-${ARCH}
ORIGPATH="${PATH}"
PATH="${BINDIR}/bin:${PATH}"
../configure \
--host=${ARCH}-w64-mingw32 \
--prefix=${BINDIR}/${ARCH}-w64-mingw32 \
--libdir=${BINDIR}/${ARCH}-w64-mingw32/lib \
CFLAGS="-O2 -mguard=cf" \
CXXFLAGS="-O2 -mguard=cf"
make -j${CORES}
make install
PATH="${ORIGPATH}"
done
done
cd ${WRKDIR}
}
# This function compiles and installs MINGW tools
mingw_build_tools()
{
for TOOL in gendef genidl genpeimg widl; do
for ARCH in ${ARCHS}; do
echo ">>> Building Mingw-w64 (tools) for ${ARCH} ..."
[ -z ${CLEAN} ] || rm -rf ${MINGWDIR}/mingw-w64-tools/${TOOL}/build-${ARCH}
mkdir -p ${MINGWDIR}/mingw-w64-tools/${TOOL}/build-${ARCH}
cd ${MINGWDIR}/mingw-w64-tools/${TOOL}/build-${ARCH}
../configure \
--target=${ARCH}-w64-mingw32 \
--prefix=${BINDIR}
make -j${CORES}
make install
if [ -e ${BINDIR}/bin/${TOOL} ]; then
mv ${BINDIR}/bin/${TOOL} ${BINDIR}/bin/${ARCH}-w64-mingw32-${TOOL}
fi
done
done
cd ${WRKDIR}
}
# This function downloads MINGW from VCS
mingw_fetch()
{
if [ ! -d ${MINGWDIR} ]; then
echo ">>> Downloading MinGW-w64 ..."
git clone --depth 1 --branch ${MINGWTAG} ${MINGWVCS} ${MINGWDIR}
cd ${MINGWDIR}
apply_patches ${MINGWDIR##*/} ${MINGWTAG}
cd ${WRKDIR}
fi
}
# This function compiles and installs NINJA
ninja_build()
{
echo ">>> Building NINJA ..."
[ -z ${CLEAN} ] || rm -rf ${NINJADIR}/build-${GENERIC}
mkdir -p ${NINJADIR}/build-${GENERIC}
cd ${NINJADIR}/build-${GENERIC}
../configure.py --bootstrap
install ninja ${BINDIR}/bin/
cd ${WRKDIR}
}
# This function downloads NINJA from VCS
ninja_fetch()
{
if [ ! -d ${NINJADIR} ]; then
echo ">>> Downloading NINJA ..."
git clone --depth 1 --branch ${NINJATAG} ${NINJAVCS} ${NINJADIR}
cd ${NINJADIR}
apply_patches ${NINJADIR##*/} ${NINJATAG}
cd ${WRKDIR}
fi
}
# This function compiles and install WINE tools
wine_build()
{
echo ">>> Building Wine ..."
mkdir -p ${WINEDIR}/build
cd ${WINEDIR}/build
../configure \
-enable-win64 \
--without-freetype \
--without-x
for TOOL in winedump wmc wrc; do
make -j${CORES} tools/${TOOL}/all
cp tools/${TOOL}/${TOOL} ${BINDIR}/bin/
for ARCH in ${ARCHS}; do
if [ ! -e ${BINDIR}/bin/${ARCH}-w64-mingw32-${TOOL} ]; then
ln -sf ${TOOL} ${BINDIR}/bin/${ARCH}-w64-mingw32-${TOOL}
fi
done
done
cd ${WRKDIR}
}
# This function downloads WINE from VCS
wine_fetch()
{
if [ ! -d ${WINEDIR} ]; then
echo ">>> Downloading WINE ..."
git clone --depth 1 --branch ${WINETAG} ${WINEVCS} ${WINEDIR}
cd ${WINEDIR}
apply_patches ${WINEDIR##*/} ${WINETAG##*-}
cd ${WRKDIR}
fi
}
# This function installs XTCHAIN scripts, wrappers and symlinks
xtchain_build()
{
echo ">>> Building XTchain ..."
mkdir -p ${BINDIR}/bin
mkdir -p ${BINDIR}/lib/xtchain
mkdir -p ${BINDIR}/${GENERIC}/bin
cp ${WRKDIR}/scripts/*-wrapper ${BINDIR}/${GENERIC}/bin
for ARCH in ${ARCHS}; do
for EXEC in c++ c11 c99 cc clang clang++ g++ gcc; do
ln -sf ../${GENERIC}/bin/clang-target-wrapper ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC}
done
for EXEC in addr2line ar as nm objcopy pdbutil ranlib rc strings strip; do
ln -sf llvm-${EXEC} ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC}
done
for EXEC in dlltool ld objdump; do
ln -sf ../${GENERIC}/bin/${EXEC}-wrapper ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC}
done
for EXEC in bin2c exetool windres xtcspecc; do
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
gcc ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
fi
ln -sf ${EXEC} ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC}
done
done
cp ${WRKDIR}/scripts/xtclib ${BINDIR}/lib/xtchain/
cp ${WRKDIR}/scripts/xtchain ${BINDIR}/
}
# Exit immediately on any failure
set -e
# Check number of CPU cores available
if [[ ! -n ${CORES} ]]; then
: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)}
: ${CORES:=$(nproc 2>/dev/null)}
: ${CORES:=1}
fi
# Create working directories
mkdir -p ${BINDIR}
mkdir -p ${SRCDIR}
# XTchain
xtchain_build
# Download LLVM
llvm_fetch
# Build and install LLVM
llvm_build
# Download Mingw-W64
mingw_fetch
# Build and install Mingw-W64 headers
mingw_build_headers
# Build and install Mingw-W64 CRT
mingw_build_crt
# Build and install LLVM compiler runtime
llvm_build_runtime
# Build and install LLVM compiler libraries
llvm_build_libs
# Build and install Mingw-W64 libraries
mingw_build_libs
# Build and install Mingw-W64 tools
mingw_build_tools
# Download Wine
wine_fetch
# Build and install Wine tools
wine_build
# Download Make
make_fetch
# Build and install Make
make_build
# Download CMake
cmake_fetch
# Build and install CMake
cmake_build
# Download Ninja
ninja_fetch
# Build and install Ninja
ninja_build
# Remove unneeded files to save disk space
echo ">>> Removing unneeded files to save disk space ..."
rm -rf ${BINDIR}/{doc,include,share/{bash-completion,emacs,info,locale,man,vim}}
rm -rf ${BINDIR}/bin/amdgpu-arch,{clang-{check,exdef-mapping,import-test,offload-*,rename,scan-deps},diagtool,hmaptool,ld64.lld,modularize,nxptx-arch,wasm-ld}
# Save XT Toolchain version
cd ${WRKDIR}
: ${XTCVER:=$(git describe --exact-match --tags 2>/dev/null)}
: ${XTCVER:=DEVEL}
echo "${XTCVER}" > ${BINDIR}/Version
# Prepare archive
echo ">>> Creating toolchain archive ..."
tar -I 'zstd -19' -cpf xtchain-${XTCVER}-linux.tar.zst -C ${BINDIR} .

499
build.sh Executable file
View File

@ -0,0 +1,499 @@
#!/bin/bash
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: build.sh
# DESCRIPTION: Toolchain crosscompilation and assembly script
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
# Aiken Harris <harraiken91@gmail.com>
# Working Directories
BINDIR="$(pwd)/binaries"
PCHDIR="$(pwd)/patches"
SRCDIR="$(pwd)/sources"
WRKDIR="$(pwd)"
# Architecture Settings
ARCHS="aarch64 armv7 i686 x86_64"
# Default Configuration
BUILD_JOBS=0
BUILD_MINIMAL=0
CLEAN_BUILD=0
ENABLE_LLVM_ASSEMBLY=0
LLVM_DYNAMIC_LINK=ON
SYSTEM_NAME=Linux
TARGET_SYSTEM=linux
# CMake Settings
CMAKEDIR="${SRCDIR}/cmake"
CMAKETAG="v4.0.3"
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
# LLVM Settings
LLVMDIR="${SRCDIR}/llvm"
LLVMTAG="llvmorg-20.1.7"
LLVMVCS="https://github.com/llvm/llvm-project.git"
# Ninja Settings
NINJADIR="${SRCDIR}/ninja"
NINJATAG="v1.13.0"
NINJAVCS="https://github.com/ninja-build/ninja.git"
# Wine Settings
WINEDIR="${SRCDIR}/wine"
WINETAG="wine-10.11"
WINEVCS="https://github.com/wine-mirror/wine.git"
# This function applies a patches to the 3rd party project
apply_patches()
{
local PACKAGE="${1}"
local VERSION="${2}"
if [ -d "${PCHDIR}/${PACKAGE}/${VERSION}" ]; then
PATCHES="$(find ${PCHDIR}/${PACKAGE}/${VERSION} -name '*.diff' -o -name '*.patch' | sort -n)"
echo ">>> Applying custom patches ..."
for PATCH in ${PATCHES}; do
if [ -f "${PATCH}" ] && [ -r "${PATCH}" ]; then
for PREFIX in {0..5}; do
if patch -i${PATCH} -p${PREFIX} --silent --dry-run >/dev/null; then
patch -i${PATCH} -p${PREFIX} --silent
echo ">>> Patch ${PATCH} applied ..."
break;
elif [ ${PREFIX} -ge 5 ]; then
echo "Patch ${PATCH} does not fit. Failed applying patch ..."
return 1
fi
done
fi
done
fi
}
# This function compiles and installs CMAKE
cmake_build()
{
local CMAKE_PARAMETERS=""
# Clean old build if necessary
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${WINEDIR}/build-${SYSTEM_NAME}
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_C_COMPILER=${SYSTEM_HOST}-gcc -DCMAKE_CXX_COMPILER=${SYSTEM_HOST}-g++"
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_RC_COMPILER=${SYSTEM_HOST}-windres"
;;
esac
# Build CMake
echo ">>> Building CMAKE ..."
mkdir -p ${CMAKEDIR}/build-${SYSTEM_NAME}
cd ${CMAKEDIR}/build-${SYSTEM_NAME}
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
-DCMAKE_INSTALL_PREFIX=${BINDIR} \
-DCMAKE_SYSTEM_NAME=${SYSTEM_NAME} \
-DCMAKE_USE_OPENSSL=OFF \
${CMAKE_PARAMETERS} \
..
cmake --build . --parallel ${BUILD_JOBS}
cmake --install .
cd ${WRKDIR}
}
# This function downloads CMAKE from VCS
cmake_fetch()
{
if [ ! -d ${CMAKEDIR} ]; then
echo ">>> Downloading CMAKE ..."
git clone --depth 1 --branch ${CMAKETAG} ${CMAKEVCS} ${CMAKEDIR}
cd ${CMAKEDIR}
apply_patches ${CMAKEDIR##*/} ${CMAKETAG}
cd ${WRKDIR}
fi
}
# This function compiles and install LLVM
llvm_build()
{
local CMAKE_PARAMETERS=""
local LLVM_ARCHS=()
# Clean old build if necessary
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${LLVMDIR}/llvm/build-${SYSTEM_NAME}
# Set supported architectures
for ARCH in ${ARCHS}; do
case ${ARCH} in
"aarch64")
LLVM_ARCHS+=( "AArch64" )
;;
"armv7")
LLVM_ARCHS+=( "ARM" )
;;
"i686"|"x86_64")
LLVM_ARCHS+=( "X86" )
;;
esac
done
LLVM_ARCHS=( $(for ARCH in ${LLVM_ARCHS[@]}; do echo ${ARCH}; done | sort -u) )
# Disable LLVM assembly files (like BLAKE3 support) if not specified otherwise
if [ "${ENABLE_LLVM_ASSEMBLY}" -ne 1 ]; then
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DLLVM_DISABLE_ASSEMBLY_FILES=ON"
fi
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_EXE_LINKER_FLAGS=-lpthread -DCMAKE_SHARED_LINKER_FLAGS=-lpthread"
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_C_COMPILER_TARGET=${SYSTEM_HOST} -DCMAKE_CXX_COMPILER_TARGET=${SYSTEM_HOST}"
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_RC_COMPILER=${SYSTEM_HOST}-windres -DLLVM_HOST_TRIPLE=${SYSTEM_HOST}"
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_FIND_ROOT=$(dirname $(readlink -f $(command -v ${SYSTEM_HOST}-windres)))/../${SYSTEM_HOST}"
CMAKE_PARAMETERS="${CMAKE_PARAMETERS} -DCMAKE_CXX_FLAGS=-femulated-tls"
;;
esac
# Build LLVM
echo ">>> Building LLVM ..."
cd ${LLVMDIR}/llvm/tools
for UTIL in clang lld; do
if [ ! -e ${UTIL} ]; then
ln -sf ../../${UTIL} .
fi
done
mkdir -p ${LLVMDIR}/llvm/build-${SYSTEM_NAME}
cd ${LLVMDIR}/llvm/build-${SYSTEM_NAME}
cmake -G Ninja \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
-DCMAKE_INSTALL_PREFIX=${BINDIR} \
-DCMAKE_SYSTEM_NAME="${SYSTEM_NAME}" \
-DLLDB_INCLUDE_TESTS=OFF \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb" \
-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
-DLLVM_BUILD_INSTRUMENTED=OFF \
-DLLVM_LINK_LLVM_DYLIB=${LLVM_DYNAMIC_LINK} \
-DLLVM_TARGETS_TO_BUILD="$(echo ${LLVM_ARCHS[@]} | tr ' ' ';')" \
-DLLVM_TOOLCHAIN_TOOLS="llvm-addr2line;llvm-ar;llvm-as;llvm-cov;llvm-cvtres;llvm-cxxfilt;llvm-dlltool;llvm-lib;llvm-ml;llvm-nm;llvm-objdump;llvm-objcopy;llvm-pdbutil;llvm-profdata;llvm-ranlib;llvm-rc;llvm-readelf;llvm-readobj;llvm-size;llvm-strings;llvm-strip;llvm-symbolizer;llvm-windres" \
-DLLVM_USE_LINKER=lld \
-DLLDB_ENABLE_PYTHON=OFF \
${CMAKE_PARAMETERS} \
..
ninja -j ${BUILD_JOBS} install/strip
cd ${WRKDIR}
}
# This function downloads LLVM from VCS
llvm_fetch()
{
if [ ! -d ${LLVMDIR} ]; then
echo ">>> Downloading LLVM ..."
git clone --depth 1 --branch ${LLVMTAG} ${LLVMVCS} ${LLVMDIR}
cd ${LLVMDIR}
apply_patches ${LLVMDIR##*/} ${LLVMTAG##*-}
cd ${WRKDIR}
fi
}
# This function compiles and installs NINJA
ninja_build()
{
local EXTENSION=""
local NINJA_CXX_COMPILER=""
local NINJA_PLATFORM=""
# Clean old build if necessary
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${NINJADIR}/build-${SYSTEM_NAME}
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
EXTENSION=".exe"
NINJA_CXX_COMPILER="${SYSTEM_HOST}-g++"
NINJA_PLATFORM="mingw"
;;
*)
NINJA_CXX_COMPILER="clang++"
NINJA_PLATFORM="linux"
;;
esac
# Build Ninja
echo ">>> Building NINJA ..."
mkdir -p ${NINJADIR}/build-${SYSTEM_NAME}
cd ${NINJADIR}/build-${SYSTEM_NAME}
CXX=${NINJA_CXX_COMPILER} ../configure.py --platform=${NINJA_PLATFORM}
ninja -j ${BUILD_JOBS}
install ninja${EXTENSION} ${BINDIR}/bin/
cd ${WRKDIR}
}
# This function downloads NINJA from VCS
ninja_fetch()
{
if [ ! -d ${NINJADIR} ]; then
echo ">>> Downloading NINJA ..."
git clone --depth 1 --branch ${NINJATAG} ${NINJAVCS} ${NINJADIR}
cd ${NINJADIR}
apply_patches ${NINJADIR##*/} ${NINJATAG}
cd ${WRKDIR}
fi
}
# Performs requirements check and prepares environment
prepare_environment()
{
# Verify that the number of build jobs is a positive integer
if [ -z "${BUILD_JOBS##*[!0-9]*}" ]; then
echo "ERROR: Invalid number of jobs provided. Please enter a positive integer."
exit 1
fi
# Verify that all required tools are installed
for APP in {clang,clang++,cmake,lld,ninja,x86_64-w64-mingw32-windres}; do
which ${APP} &> /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: ${APP} not found. Please install the required tool."
exit 2
fi
done
# Set target-specific options
case "${TARGET_SYSTEM}" in
windows|*-mingw32)
SYSTEM_NAME="Windows"
SYSTEM_HOST="x86_64-w64-mingw32"
;;
linux|*-linux-*)
SYSTEM_NAME="Linux"
;;
*)
echo "ERROR: Invalid target system specified. Please choose a valid target system."
exit 3
;;
esac
}
# Prints usage help
print_usage()
{
echo "USAGE: ${0} [--clean] [--enable-llvm-assembly] [--jobs=N] [--minimal] [--static-llvm] [--target={linux,windows}]"
exit 1
}
# This function compiles and install WINE tools
wine_build()
{
local CONFIGURE_PARAMETERS=""
local EXTENSION=""
# Clean old build if necessary
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${WINEDIR}/{build-${SYSTEM_NAME},build-tools}
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
CONFIGURE_PARAMETERS="${CONFIGURE_PARAMETERS} --host=${SYSTEM_HOST}"
EXTENSION=".exe"
;;
esac
# Build Wine (first configuration builds makedep)
echo ">>> Building Wine ..."
mkdir -p ${WINEDIR}/{build-${SYSTEM_NAME},build-tools}
cd ${WINEDIR}/build-tools
../configure \
--enable-win64 \
--without-freetype \
--without-x
cd ${WINEDIR}/build-${SYSTEM_NAME}
../configure \
--enable-tools \
--enable-win64 \
--with-wine-tools=${WINEDIR}/build-tools \
--without-freetype \
--without-x \
${CONFIGURE_PARAMETERS}
for TOOL in widl wmc wrc; do
make -j ${BUILD_JOBS} tools/${TOOL}/all
cp tools/${TOOL}/${TOOL}${EXTENSION} ${BINDIR}/bin/
done
cd ${WRKDIR}
}
# This function downloads WINE from VCS
wine_fetch()
{
if [ ! -d ${WINEDIR} ]; then
echo ">>> Downloading WINE ..."
git clone --depth 1 --branch ${WINETAG} ${WINEVCS} ${WINEDIR}
cd ${WINEDIR}
apply_patches ${WINEDIR##*/} ${WINETAG##*-}
cd ${WRKDIR}
fi
}
# This function installs XTCHAIN tools and scripts
xtchain_build()
{
# Target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
CCOMPILER="${SYSTEM_HOST}-gcc"
EXTENSION=".ps1"
;;
*)
CCOMPILER="clang"
EXTENSION=""
esac
# Build XTchain tools
echo ">>> Building XTchain tools ..."
mkdir -p ${BINDIR}/bin
mkdir -p ${BINDIR}/lib/xtchain
for EXEC in bin2c exetool xtcspecc; do
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
${CCOMPILER} ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
fi
done
cp ${WRKDIR}/scripts/xtclib${EXTENSION} ${BINDIR}/lib/xtchain/
cp ${WRKDIR}/scripts/xtchain${EXTENSION} ${BINDIR}/
}
# This function generates XTCHAIN version file and produces tarball archive
xtchain_tarball()
{
local EXTENSION=""
local LIBDIR=""
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
EXTENSION=".exe"
;;
esac
# Remove unneeded files to save disk space
echo ">>> Removing unneeded files to save disk space ..."
rm -rf ${BINDIR}/{doc,include,share/{bash-completion,emacs,info,locale,man,vim}}
for EXEC in amdgpu-arch clang-check clang-exdef-mapping clang-import-test clang-offload-* clang-rename clang-scan-deps diagtool hmaptool ld64.lld modularize nxptx-arch wasm-ld; do
rm -f ${BINDIR}/bin/${EXEC}${EXTENSION}
done
# Generate version file
cd ${WRKDIR}
: ${XTCVER:=$(git describe --exact-match --tags 2>/dev/null)}
: ${XTCVER:=DEVEL}
[ ${BUILD_MINIMAL} -eq 1 ] && XTCVER="${XTCVER}-min"
echo "${XTCVER}" > ${BINDIR}/Version
# Windows target specific actions
if [ "${SYSTEM_NAME}" == "Windows" ]; then
# Replace symlinks with original files
for LINK in $(find ${BINDIR}/bin -maxdepth 1 -type l); do
cp -f --remove-destination $(readlink -e ${LINK}) ${LINK}
done
# Copy dynamic libraries
if [ ${BUILD_MINIMAL} -eq 0 ]; then
LIBDIR="$(dirname $(readlink -f $(command -v ${SYSTEM_HOST}-windres)))/../${SYSTEM_HOST}"
for DLL in $(${SYSTEM_HOST}-objdump --private-headers ${BINDIR}/bin/cmake.exe | grep "DLL Name:" | cut -d' ' -f3 | grep "lib.*.dll"); do
find ${LIBDIR} -type f -name ${DLL} -exec cp {} ${BINDIR}/bin \;
done
fi
fi
# Build tarball
echo ">>> Creating toolchain archive ..."
tar -I 'zstd -19' -cpf xtchain-${XTCVER}-${TARGET_SYSTEM}.tar.zst -C ${BINDIR} .
}
# Parse all arguments provided to the script
while [ $# -gt 0 ]; do
case "$1" in
--clean)
# Performs clean build
CLEAN_BUILD=1
;;
--enable-llvm-assembly)
# Enables LLVM asembly files compilation (like BLAKE3)
ENABLE_LLVM_ASSEMBLY=1
;;
--jobs=*)
# Sets number of CPU cores used for compilation
BUILD_JOBS="${1#*=}"
;;
--minimal)
BUILD_MINIMAL=1
;;
--static-llvm)
# Compiles LLVM statically
LLVM_DYNAMIC_LINK=OFF
;;
--target=*)
# Sets the target system for built toolchain (Linux or Windows)
TARGET_SYSTEM="${1#*=}"
;;
*)
# Prints help if any other parameter given
print_usage
;;
esac
shift
done
# Prepare environment
prepare_environment
# Exit immediately on any failure
set -e
# Check number of CPU cores available
if [ ${BUILD_JOBS} -eq 0 ]; then
unset BUILD_JOBS
: ${BUILD_JOBS:=$(sysctl -n hw.ncpu 2>/dev/null)}
: ${BUILD_JOBS:=$(nproc 2>/dev/null)}
: ${BUILD_JOBS:=1}
fi
# Create working directories
mkdir -p ${BINDIR}
mkdir -p ${SRCDIR}
# Build XTchain tools
xtchain_build
# Download and build Wine tools
wine_fetch
wine_build
if [ ${BUILD_MINIMAL} -eq 0 ]; then
# Download and build LLVM
llvm_fetch
llvm_build
# Download and build CMake
cmake_fetch
cmake_build
# Download and build Ninja
ninja_fetch
ninja_build
fi
# Generate tarball archive
xtchain_tarball

View File

@ -1,13 +0,0 @@
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 818109f0b7..749377d193 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -7,7 +7,7 @@ set(CMake_VERSION_IS_DIRTY 0)
# Start with the full version number used in tags. It has no dev info.
set(CMake_VERSION
- "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+ "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}-XTC")
if(DEFINED CMake_VERSION_RC)
set(CMake_VERSION "${CMake_VERSION}-rc${CMake_VERSION_RC}")
endif()

View File

@ -1,13 +0,0 @@
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 818109f0b7..749377d193 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -7,7 +7,7 @@ set(CMake_VERSION_IS_DIRTY 0)
# Start with the full version number used in tags. It has no dev info.
set(CMake_VERSION
- "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+ "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}-XTC")
if(DEFINED CMake_VERSION_RC)
set(CMake_VERSION "${CMake_VERSION}-rc${CMake_VERSION_RC}")
endif()

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
#!/bin/sh
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/clang-target-wrapper
# DESCRIPTION: CLANG Wrapper
# DEVELOPERS: Martin Storsjo <martin@martin.st>
# Rafal Kupiec <belliash@codingworkshop.eu.org>
# Set basic variables
DIR="$(cd $(dirname $0) && pwd)"
CLANG="$DIR/clang"
BASENAME="$(basename $0)"
TARGET="${BASENAME%-*}"
EXECUTABLE="${BASENAME##*-}"
DEFAULT_TARGET="x86_64-w64-mingw32"
ARCH="${TARGET%%-*}"
# Set proper target
if [ "${TARGET}" = "${BASENAME}" ]; then
TARGET="${DEFAULT_TARGET}"
fi
# Set lang-specific flags
case ${EXECUTABLE} in
"clang++"|"g++"|"c++")
FLAGS="$FLAGS --driver-mode=g++"
;;
*)
FLAGS=""
;;
esac
# Set compiler flags
FLAGS="${FLAGS} -target ${TARGET}"
FLAGS="${FLAGS} -rtlib=compiler-rt"
FLAGS="${FLAGS} -stdlib=libc++"
FLAGS="${FLAGS} -fuse-ld=lld"
FLAGS="${FLAGS} -Qunused-arguments"
# Launch the compiler
$CLANG $FLAGS "$@"

View File

@ -1,42 +0,0 @@
#!/bin/sh
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/dlltool-wrapper
# DESCRIPTION: DLLTOOL Wrapper
# DEVELOPERS: Martin Storsjo <martin@martin.st>
# Rafal Kupiec <belliash@codingworkshop.eu.org>
# Set basic variables
DIR="$(cd $(dirname $0) && pwd)"
BASENAME="$(basename $0)"
TARGET="${BASENAME%-*}"
DEFAULT_TARGET="x86_64-w64-mingw32"
# Update PATH
export PATH="$DIR":"$PATH"
# Set proper target
if [ "${TARGET}" = "${BASENAME}" ]; then
TARGET="${DEFAULT_TARGET}"
fi
# Set target machine
ARCH="${TARGET%%-*}"
case $ARCH in
aarch64)
M="arm64"
;;
armv7)
M="arm"
;;
i686)
M="i386"
;;
x86_64)
M="i386:x86-64"
;;
esac
# Launch the utility
llvm-dlltool -m ${M} "$@"

View File

@ -1,42 +0,0 @@
#!/bin/sh
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/ld-wrapper
# DESCRIPTION: LLD Wrapper
# DEVELOPERS: Martin Storsjo <martin@martin.st>
# Rafal Kupiec <belliash@codingworkshop.eu.org>
# Set basic variables
DIR="$(cd $(dirname $0) && pwd)"
BASENAME="$(basename $0)"
TARGET="${BASENAME%-*}"
DEFAULT_TARGET="x86_64-w64-mingw32"
# Update PATH
export PATH="${DIR}":"${PATH}"
# Set proper target
if [ "${TARGET}" = "${BASENAME}" ]; then
TARGET="${DEFAULT_TARGET}"
fi
# Set target machine
ARCH="${TARGET%%-*}"
case ${ARCH} in
aarch64)
M="arm64pe"
;;
armv7)
M="thumb2pe"
;;
i686)
M="i386pe"
;;
x86_64)
M="i386pep"
;;
esac
# Launch the linker
ld.lld -m ${M} "$@"

View File

@ -1,46 +0,0 @@
#!/bin/sh
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/objdump-wrapper
# DESCRIPTION: OBJDUMP Wrapper
# DEVELOPERS: Martin Storsjo <martin@martin.st>
# Rafal Kupiec <belliash@codingworkshop.eu.org>
# Set basic variables
DIR="$(cd $(dirname $0) && pwd)"
# Update PATH
export PATH="$DIR":"$PATH"
# Libtool can try to run objdump -f and wants to see certain strings in
# the output, to accept it being a valid windows (import) library
if [ "$1" = "-f" ]; then
llvm-readobj $2 | while read -r line; do
case $line in
File:*)
file=$(echo $line | awk '{print $2}')
;;
Format:*)
format=$(echo $line | awk '{print $2}')
case $format in
COFF-i386)
format=pe-i386
;;
COFF-x86-64)
format=pe-x86-64
;;
COFF-ARM*)
# This is wrong; modern COFF armv7 isn't pe-arm-wince, and
# arm64 definitely isn't, but libtool wants to see this
# string (or some of the others) in order to accept it.
format=pe-arm-wince
;;
esac
echo $file: file format $format
;;
esac
done
else
llvm-objdump "$@"
fi

47
scripts/xtchain.ps1 Normal file
View File

@ -0,0 +1,47 @@
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/xtchain.ps1
# DESCRIPTION: XTchain Entry Script
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
# Get the absolute path to the XTchain
$XTCDIR = (Get-Item -Path ".\").FullName
# Read the XTchain version
$env:XTCVER = Get-Content "${XTCDIR}\Version"
# Load the library (Make sure the xtclib.ps1 file is PowerShell compatible)
. "${XTCDIR}\lib\xtchain\xtclib.ps1"
# Set the target architecture
$env:TARGET = $args[0]
if (-not $env:TARGET) { $env:TARGET = "amd64" }
# Save the source directory
$SRCDIR = $args[1]
if (-not $SRCDIR) { $SRCDIR = (Get-Location).Path }
# Make sure the compiler flags are clean
$env:HOST = $null
$env:CFLAGS = $null
$env:CXXFLAGS = $null
$env:LDFLAGS = $null
# Update PATH
$env:PATH = "${XTCDIR}\bin;" + $env:PATH
# Display banner
version
# Invoke shell with fancy prompt
function global:prompt {
$esc = [char]27
$resetColor = "$esc[0m"
$pathColor = "$esc[1;34m"
$toolchainColor = "$esc[1;97;44m"
$toolchainText = "${toolchainColor} XT Toolchain "
$pathText = "${pathColor}$($PWD.ProviderPath) "
$arrow = ""
"${toolchainText}$arrow$pathText$resetColor> "
}
Set-Location -Path $SRCDIR

View File

@ -4,8 +4,20 @@
# FILE: scripts/xtclib
# DESCRIPTION: XTchain library
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
# Aiken Harris <harraiken91@gmail.com>
# Prints XTChain banner
banner()
{
local XTC_BANNER="XT Toolchain v${XTCVER} for Linux"
printf "###############################################################################\n\n"
printf "%*s\n\n" $(( (${#XTC_BANNER} + 80) / 2)) "${XTC_BANNER}"
printf "###############################################################################\n\n\n"
}
export -f banner
# Sets the target architecture
charch()
{
@ -54,51 +66,67 @@ export -f chbuild
# Prints help
help()
{
version
echo "XTChain defines an internal list of commands:"
echo " * charch [arch] - sets the target CPU architecture [aarch64/armv7/i686/amd64]"
echo " * chbuild [type] - sets build type [debug/release]"
echo " * help - prints this message"
echo " * version - prints XTChain and its components version"
echo " * xbuild - builds an application with a Ninja build system"
banner
echo "XTChain defines an internal list of commands:"
echo " * banner - prints XTChain banner"
echo " * charch [arch] - sets the target CPU architecture [aarch64/armv7/i686/amd64]"
echo " * chbuild [type] - sets build type [debug/release]"
echo " * help - prints this message"
echo " * version - prints XTChain and its components version"
echo " * xbuild - builds an application with a Ninja build system"
}
export -f help
# Displays version banner
version()
{
echo "###############################################################################"
echo "# XT Toolchain v${XTCVER} for Linux #"
echo "# by Rafal Kupiec <belliash@codingworkshop.eu.org> #"
echo "###############################################################################"
echo
echo
echo "LLVM Compiler Version: $(${XTCDIR}/bin/clang --version | grep 'clang version' | cut -d' ' -f3)"
echo "LLVM Windres Utility Version: $(${XTCDIR}/bin/i686-w64-mingw32-windres -V | cut -d' ' -f6)"
echo "Mingw IDL Compiler Version: $(${XTCDIR}/bin/i686-w64-mingw32-widl -V | grep 'version' | cut -d' ' -f5)"
echo "Wine Message Compiler Version: $(${XTCDIR}/bin/wmc -V | grep 'version' | cut -d' ' -f5)"
echo "Wine Resource Compiler Version: $(${XTCDIR}/bin/wrc --version | grep 'version' | cut -d' ' -f5)"
echo
local XTCHAIN_EXTTOOLS=false
if [ ! -f ${XTCDIR}/bin/clang ] || [ "$(which clang)" != "${XTCDIR}/bin/clang" ] || [ $(echo ${XTCVER} | grep "min") ]; then
XTCHAIN_EXTTOOLS=true
for TOOL in {clang,clang++,cmake,lld-link,ninja}; do
which ${TOOL} &> /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: You are using minimal version of XTChain and '${TOOL}' has been not found in your system!"
echo "ERROR: Please install all required tools."
exit 1
fi
done
fi
banner
echo -en "\nLLVM/Clang Compiler: $(clang --version | grep 'clang version' | cut -d' ' -f3) ($(which clang))"
echo -en "\nLLVM/LLD Linker: $(lld-link --version | cut -d' ' -f2) ($(which lld-link))"
echo -en "\nLLVM Resource Compiler: $(windres --version | grep version | cut -d' ' -f5) ($(which windres))"
echo -en "\nWine IDL Compiler: $(widl -V | grep 'version' | cut -d' ' -f5) ($(which widl))"
echo -en "\nWine Message Compiler: $(wmc -V | grep 'version' | cut -d' ' -f5) ($(which wmc))"
echo -en "\nWine Resource Compiler: $(wrc --version | grep 'version' | cut -d' ' -f5) ($(which wrc))"
echo -en "\nXT SPEC Compiler: $(xtcspecc --help | grep Version | cut -d' ' -f5) ($(which xtcspecc))"
echo -en "\nCMake Build System: $(cmake --version | grep 'cmake version' | cut -d' ' -f3) ($(which cmake))"
echo -en "\nNinja Build System: $(ninja --version) ($(which ninja))"
echo -en "\n\n"
charch ${TARGET:-amd64}
chbuild ${BUILD_TYPE:-DEBUG}
echo
echo
echo -en "\n\nFor a list of all supported commands, type 'help'"
echo -en "\n-------------------------------------------------\n\n"
}
export -f version
# Builds application (wrapper to Ninja)
xbuild()
{
if [ ! -f build.arch ]; then
ninja "$@"
else
ARCH=$(cat build.arch)
if [ x"${ARCH}" != x"${TARGET}" ]; then
echo "Build is configured for '${ARCH}' while current target set to '${TARGET}'!"
echo "Cannot continue until conflict is resolved ..."
return 1
fi
ninja "$@"
fi
if [ ! -f build.arch ]; then
ninja "$@"
else
ARCH=$(cat build.arch)
if [ x"${ARCH}" != x"${TARGET}" ]; then
echo "Build is configured for '${ARCH}' while current target set to '${TARGET}'!"
echo "Cannot continue until conflict is resolved ..."
return 1
fi
ninja "$@"
fi
}
export -f xbuild

148
scripts/xtclib.ps1 Normal file
View File

@ -0,0 +1,148 @@
# PROJECT: XTchain
# LICENSE: See the COPYING.md in the top level directory
# FILE: scripts/xtclib.ps1
# DESCRIPTION: XTchain library
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
# Prints XTChain banner
function banner {
param()
$XTC_BANNER = "XT Toolchain v${Env:XTCVER} for Windows"
Write-Host "################################################################################"
Write-Host
Write-Host (' ' * [math]::Floor((80 - $XTC_BANNER.Length) / 2) + $XTC_BANNER) -ForegroundColor Yellow
Write-Host
Write-Host "################################################################################"
Write-Host
}
# Sets the target architecture
function charch {
param (
[string]$arch
)
if ([string]::IsNullOrWhiteSpace($arch)) {
Write-Host "Syntax: charch [architecture]"
return
}
switch -Regex ($arch) {
"aarch64|arm64" {
$Env:TARGET = "aarch64"
}
"arm|armv7" {
$Env:TARGET = "armv7"
}
"i386|i486|i586|i686|x86" {
$Env:TARGET = "i686"
}
"amd64|x64|x86_64" {
$Env:TARGET = "amd64"
}
default {
$Env:TARGET = "UNKNOWN"
}
}
Write-Host "Target Architecture: $($Env:TARGET)"
}
# Sets the build type
function chbuild {
param (
[string]$buildType
)
if ([string]::IsNullOrWhiteSpace($buildType)) {
Write-Host "Syntax: chbuild [DEBUG|RELEASE]"
return
}
switch -Regex ($buildType.ToUpper()) {
"RELEASE" {
$Env:BUILD_TYPE = "RELEASE"
}
default {
$Env:BUILD_TYPE = "DEBUG"
}
}
Write-Host "Target build type: $($Env:BUILD_TYPE)"
}
# Prints help
function help {
banner
Write-Host "XTChain defines an internal list of commands:"
Write-Host " * banner - prints XTChain banner"
Write-Host " * charch [arch] - sets the target CPU architecture [aarch64/armv7/i686/amd64]"
Write-Host " * chbuild [type] - sets build type [debug/release]"
Write-Host " * help - prints this message"
Write-Host " * version - prints XTChain and its components version"
Write-Host " * xbuild - builds an application with a Ninja build system"
}
# Displays version banner
function version {
param()
[bool]$XTCHAIN_EXTTOOLS = $false
if ((Test-Path "${Env:XTCDIR}/bin/clang") -and
((Get-Command clang).Source -eq "${Env:XTCDIR}/bin/clang") -and
($Env:XTCVER -match "min")) {
$XTCHAIN_EXTTOOLS = $true
foreach ($TOOL in @("clang", "clang++", "cmake", "lld-link", "ninja")) {
if (!(Get-Command $TOOL -ErrorAction SilentlyContinue)) {
Write-Error "You are using minimal version of XTChain and '${TOOL}' has been not found in your system!"
Write-Error "Please install all required tools."
return
}
}
}
banner
Write-Host
Write-Host "LLVM/Clang Compiler: $(clang --version | Select-String -Pattern "version (\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command clang).Source))"
Write-Host "LLVM/LLD Linker: $(lld-link --version | Select-String -Pattern "(\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command lld-link).Source))"
Write-Host "LLVM Resource Compiler: $(windres --version | Select-String -Pattern "version (\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command windres).Source))"
Write-Host "Wine IDL Compiler: $(widl -V | Select-String -Pattern "version (\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command widl).Source))"
Write-Host "Wine Message Compiler: $(wmc -V | Select-String -Pattern "version (\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command wmc).Source))"
Write-Host "Wine Resource Compiler: $(wrc --version | Select-String -Pattern "version (\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command wrc).Source))"
Write-Host "XT SPEC Compiler: $(xtcspecc --help | Select-String -Pattern "Version (\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command xtcspecc).Source))"
Write-Host "CMake Build System: $(cmake --version | Select-String -Pattern "version (\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) ($($(Get-Command cmake).Source))"
Write-Host "Ninja Build System: $(ninja --version) ($($(Get-Command ninja).Source))"
Write-Host
$BUILD_TYPE = if ($null -eq $env:BUILD_TYPE -or $env:BUILD_TYPE -eq '') { 'DEBUG' } else { $env:BUILD_TYPE }
$TARGET = if ($null -eq $env:TARGET -or $env:TARGET -eq '') { 'amd64' } else { $env:TARGET }
charch $TARGET
chbuild $BUILD_TYPE
Write-Host
Write-Host
Write-Host "For a list of all supported commands, type 'help'"
Write-Host "-------------------------------------------------"
Write-Host
Write-Host
Write-Host
}
# Builds application (wrapper to Ninja)
function xbuild {
param(
[string[]]$args
)
if (-not (Test-Path build.arch)) {
& ninja @args
} else {
$ARCH = Get-Content build.arch
if ($ARCH -ne $Env:TARGET) {
Write-Host "Build is configured for '$ARCH' while current target set to '$($Env:TARGET)'!"
Write-Host "Cannot continue until conflict is resolved ..."
return 1
}
& ninja @args
}
}

View File

@ -1,558 +0,0 @@
/**
* PROJECT: XTchain
* LICENSE: See COPYING.md in the top level directory
* FILE: tools/windres.c
* DESCRIPTION: WINDRES compatible interface to LLVM
* DEVELOPERS: Josh de Kock <josh@itanimul.li>
* Martin Storsjo <martin@martin.st>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include "xtchain.h"
#define WINDRES_VERSION "1.0"
#ifndef DEFAULT_TARGET
#define DEFAULT_TARGET "x86_64-w64-mingw32"
#endif
#include <stdarg.h>
#define _tspawnvp_escape _spawnvp
#include <sys/wait.h>
#include <errno.h>
#define _P_WAIT 0
static
int
_spawnvp(int mode,
const char *filename,
const char * const *argv)
{
pid_t pid;
if(!(pid = fork()))
{
execvp(filename, (char **) argv);
perror(filename);
exit(1);
}
int stat = 0;
if(waitpid(pid, &stat, 0) == -1)
{
return -1;
}
if(WIFEXITED(stat))
{
return WEXITSTATUS(stat);
}
errno = EIO;
return -1;
}
static
const
char *unescape_cpp(const char *str)
{
char *out = strdup(str);
int len = strlen(str);
int i, outpos = 0;
for(i = 0; i < len - 1; i++)
{
if(str[i] == '\\' && str[i + 1] == '"')
{
continue;
}
out[outpos++] = str[i];
}
while(i < len)
{
out[outpos++] = str[i++];
}
out[outpos++] = '\0';
return out;
}
static
void print_version(void)
{
printf("XTchain windres (GNU windres compatible) %s\n", WINDRES_VERSION);
exit(0);
}
static
void print_help(void)
{
printf(
"usage: llvm-windres <OPTION> [INPUT-FILE] [OUTPUT-FILE]\n"
"\n"
"LLVM Tool to manipulate Windows resources with a GNU windres interface.\n"
"\n"
"Options:\n"
" -i, --input <arg> Name of the input file.\n"
" -o, --output <arg> Name of the output file.\n"
" -J, --input-format <arg> Input format to read.\n"
" -O, --output-format <arg> Output format to generate.\n"
" --preprocessor <arg> Custom preprocessor command.\n"
" --preprocessor-arg <arg> Preprocessor command arguments.\n"
" -F, --target <arg> Target for COFF objects to be compiled for.\n"
" -I, --include-dir <arg> Include directory to pass to preprocessor and resource compiler.\n"
" -D, --define <arg[=val]> Define to pass to preprocessor.\n"
" -U, --undefine <arg[=val]> Undefine to pass to preprocessor.\n"
" -c, --codepage <arg> Default codepage to use when reading an rc file (0x0-0xffff).\n"
" -l, --language <arg> Specify default language (0x0-0xffff).\n"
" --use-temp-file Use a temporary file for the preprocessing output.\n"
" -v, --verbose Enable verbose output.\n"
" -V, --version Display version.\n"
" -h, --help Display this message and exit.\n"
"Input Formats:\n"
" rc Text Windows Resource\n"
" res Binary Windows Resource\n"
"Output Formats:\n"
" res Binary Windows Resource\n"
" coff COFF object\n"
"Targets:\n"
" pe-x86-64\n"
" pei-x86-64\n"
" pe-i386\n"
" pei-i386\n");
exit(0);
}
static
void error(const char *basename,
const char *fmt,
...)
{
fprintf(stderr, _T(TS": error: "), basename);
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fprintf(stderr, _T("\n"));
va_end(ap);
exit(1);
}
static
void print_argv(const char **exec_argv)
{
while(*exec_argv)
{
fprintf(stderr, _T(TS" "), *exec_argv);
exec_argv++;
}
fprintf(stderr, _T("\n"));
}
static
void check_num_args(int arg,
int max_arg)
{
if(arg > max_arg)
{
fprintf(stderr, "Too many options added\n");
abort();
}
}
int main(int argc,
char* argv[])
{
char *dir;
char *basename;
char *target;
split_argv(argv[0], &dir, &basename, &target, NULL);
if (!target)
target = _T(DEFAULT_TARGET);
const char *bfd_target = NULL;
const char *input = _T("-");
const char *output = _T("/dev/stdout");
const char *input_format = _T("rc");
const char *output_format = _T("coff");
const char **includes = malloc(argc * sizeof(*includes));
int nb_includes = 0;
const char *codepage = _T("1252");
const char *language = NULL;
const char **cpp_options = malloc(argc * sizeof(*cpp_options));
int nb_cpp_options = 0;
int verbose = 0;
#define _tcslen_const(a) (sizeof(a)/sizeof(char) - 1)
#define _tcsstart(a, b) !strncmp(a, b, _tcslen_const(b))
#define IF_MATCH_EITHER(short, long) \
if(!strcmp(argv[i], _T(short)) || !strcmp(argv[i], _T(long)))
#define IF_MATCH_THREE(first, second, third) \
if(!strcmp(argv[i], _T(first)) || !strcmp(argv[i], _T(second)) || !strcmp(argv[i], _T(third)))
#define OPTION(short, long, var) \
if(_tcsstart(argv[i], _T(short)) && argv[i][_tcslen_const(_T(short))]) { \
var = argv[i] + _tcslen_const(_T(short)); \
} else if(_tcsstart(argv[i], _T(long "="))) { \
var = strchr(argv[i], '=') + 1; \
} else IF_MATCH_EITHER(short, long) { \
if(i + 1 < argc) \
var = argv[++i]; \
else \
error(basename, _T(TS" missing argument"), argv[i]); \
}
#define SEPARATE_ARG(var) do { \
if(i + 1 < argc) \
var = argv[++i]; \
else \
error(basename, _T(TS" missing argument"), argv[i]); \
} while (0)
#define SEPARATE_ARG_PREFIX(var, prefix) do { \
if(i + 1 < argc) \
var = concat(_T(prefix), argv[++i]); \
else \
error(basename, _T(TS" missing argument"), argv[i]); \
} while (0)
for(int i = 1; i < argc; i++)
{
OPTION("-i", "--input", input)
else OPTION("-o", "--output", output)
else OPTION("-J", "--input-format", input_format)
else OPTION("-O", "--output-format", output_format)
else OPTION("-F", "--target", bfd_target)
else IF_MATCH_THREE("-I", "--include-dir", "--include") {
SEPARATE_ARG(includes[nb_includes++]);
}
else if(_tcsstart(argv[i], _T("--include-dir=")) ||
_tcsstart(argv[i], _T("--include=")))
{
includes[nb_includes++] = strchr(argv[i], '=') + 1;
}
else if(_tcsstart(argv[i], _T("-I")))
{
includes[nb_includes++] = argv[i] + 2;
}
else OPTION("-c", "--codepage", codepage)
else OPTION("-l", "--language", language)
else if(!strcmp(argv[i], _T("--preprocessor")))
{
error(basename, _T("ENOSYS"));
}
else if(_tcsstart(argv[i], _T("--preprocessor-arg=")))
{
cpp_options[nb_cpp_options++] = strchr(argv[i], '=') + 1;
}
else if(!strcmp(argv[i], _T("--preprocessor-arg")))
{
SEPARATE_ARG(cpp_options[nb_cpp_options++]);
}
else IF_MATCH_EITHER("-D", "--define")
{
SEPARATE_ARG_PREFIX(cpp_options[nb_cpp_options++], "-D");
}
else if(_tcsstart(argv[i], _T("-D")))
{
cpp_options[nb_cpp_options++] = argv[i];
}
else IF_MATCH_EITHER("-U", "--undefine")
{
SEPARATE_ARG_PREFIX(cpp_options[nb_cpp_options++], "-U");
}
else if(_tcsstart(argv[i], _T("-U")))
{
cpp_options[nb_cpp_options++] = argv[i];
}
else IF_MATCH_EITHER("-v", "--verbose")
{
verbose = 1;
}
else IF_MATCH_EITHER("-V", "--version")
{
print_version();
}
else IF_MATCH_EITHER("-h", "--help")
{
print_help();
}
else if(!strcmp(argv[i], _T("--use-temp-file")))
{
// No-op, we use a temp file by default.
}
else if(_tcsstart(argv[i], _T("-")))
{
error(basename, _T("unrecognized option: `"TS"'"), argv[i]);
}
else
{
if(!strcmp(input, _T("-")))
{
input = argv[i];
}
else if(!strcmp(output, _T("/dev/stdout")))
{
output = argv[i];
}
else
{
error(basename, _T("rip: `"TS"'"), argv[i]);
}
}
}
if(bfd_target)
{
if(!strcmp(bfd_target, _T("pe-x86-64")) ||
!strcmp(bfd_target, _T("pei-x86-64")))
{
target = _T("x86_64-w64-mingw32");
}
else if(!strcmp(bfd_target, _T("pe-i386")) ||
!strcmp(bfd_target, _T("pei-i386")))
{
target = _T("i686-w64-mingw32");
}
else
{
error(basename, _T("unsupported target: `"TS"'"), bfd_target);
}
}
char *arch = strdup(target);
char *dash = strchr(arch, '-');
if(dash)
{
*dash = '\0';
}
const char *machine = _T("unknown");
if(!strcmp(arch, _T("i686")))
{
machine = _T("X86");
}
else if(!strcmp(arch, _T("x86_64")))
{
machine = _T("X64");
}
else if(!strcmp(arch, _T("armv7")))
{
machine = _T("ARM");
}
else if(!strcmp(arch, _T("aarch64")))
{
machine = _T("ARM64");
}
const char *CC = concat(target, _T("-clang"));
const char **rc_options = malloc(2 * argc * sizeof(*cpp_options));
int nb_rc_options = 0;
for(int i = 0; i < nb_includes; i++)
{
cpp_options[nb_cpp_options++] = concat(_T("-I"), includes[i]);
rc_options[nb_rc_options++] = _T("-I");
rc_options[nb_rc_options++] = includes[i];
}
for(int i = 0; i < nb_cpp_options; i++)
{
cpp_options[i] = unescape_cpp(cpp_options[i]);
}
const char *preproc_rc = concat(output, _T(".preproc.rc"));
const char *res = concat(output, _T(".out.res"));
char *inputdir = strdup(input);
{
char *sep = _tcsrchrs(inputdir, '/', '\\');
if(sep)
{
*sep = '\0';
}
else
{
inputdir = strdup(_T("."));
}
}
int max_arg = 2 * argc + 20;
const char **exec_argv = malloc((max_arg + 1) * sizeof(*exec_argv));
int arg = 0;
if(!_tcsicmp(input_format, _T("rc")))
{
exec_argv[arg++] = concat(dir, CC);
exec_argv[arg++] = _T("-E");
for(int i = 0; i < nb_cpp_options; i++)
{
exec_argv[arg++] = cpp_options[i];
}
exec_argv[arg++] = _T("-xc");
exec_argv[arg++] = _T("-DRC_INVOKED=1");
exec_argv[arg++] = input;
exec_argv[arg++] = _T("-o");
exec_argv[arg++] = preproc_rc;
exec_argv[arg] = NULL;
check_num_args(arg, max_arg);
if(verbose)
{
print_argv(exec_argv);
}
int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv);
if(ret == -1)
{
perror(exec_argv[0]);
return 1;
}
if(ret != 0)
{
error(basename, _T("preprocessor failed"));
return ret;
}
arg = 0;
exec_argv[arg++] = concat(dir, _T("llvm-rc"));
for(int i = 0; i < nb_rc_options; i++)
{
exec_argv[arg++] = rc_options[i];
}
exec_argv[arg++] = _T("-I");
exec_argv[arg++] = inputdir;
exec_argv[arg++] = preproc_rc;
exec_argv[arg++] = _T("-c");
exec_argv[arg++] = codepage;
if(language)
{
exec_argv[arg++] = _T("-l");
exec_argv[arg++] = language;
}
exec_argv[arg++] = _T("-fo");
if(!_tcsicmp(output_format, _T("res")))
{
exec_argv[arg++] = output;
}
else
{
exec_argv[arg++] = res;
}
exec_argv[arg] = NULL;
check_num_args(arg, max_arg);
if(verbose)
{
print_argv(exec_argv);
}
ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv);
if(ret == -1)
{
perror(exec_argv[0]);
return 1;
}
if(ret != 0)
{
error(basename, _T("llvm-rc failed"));
if(!verbose)
{
unlink(preproc_rc);
}
return ret;
}
if(!_tcsicmp(output_format, _T("res")))
{
// All done
}
else if(!_tcsicmp(output_format, _T("coff")))
{
arg = 0;
exec_argv[arg++] = concat(dir, _T("llvm-cvtres"));
exec_argv[arg++] = res;
exec_argv[arg++] = concat(_T("-machine:"), machine);
exec_argv[arg++] = concat(_T("-out:"), output);
exec_argv[arg] = NULL;
check_num_args(arg, max_arg);
if(verbose)
{
print_argv(exec_argv);
}
int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv);
if(ret == -1)
{
perror(exec_argv[0]);
return 1;
}
if(!verbose)
{
unlink(preproc_rc);
unlink(res);
}
return ret;
} else {
error(basename, _T("invalid output format: `"TS"'"), output_format);
}
}
else if(!_tcsicmp(input_format, _T("res")))
{
exec_argv[arg++] = concat(dir, _T("llvm-cvtres"));
exec_argv[arg++] = input;
exec_argv[arg++] = concat(_T("-machine:"), machine);
exec_argv[arg++] = concat(_T("-out:"), output);
exec_argv[arg] = NULL;
check_num_args(arg, max_arg);
if(verbose)
{
print_argv(exec_argv);
}
int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv);
if(ret == -1)
{
perror(exec_argv[0]);
return 1;
}
return ret;
}
else
{
error(basename, _T("invalid input format: `"TS"'"), input_format);
}
return 0;
}

View File

@ -7,57 +7,13 @@
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifdef UNICODE
#define _UNICODE
#endif
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define _T(x) x
#ifdef _UNICODE
#define TS "%ls"
#else
#define TS "%s"
#endif
static
inline
int
_tcsicmp(const char *a,
const char *b)
{
while(*a && tolower(*a) == tolower(*b))
{
a++;
b++;
}
return *a - *b;
}
static
inline
char *
concat(const char *prefix,
const char *suffix)
{
int prefixlen = strlen(prefix);
int suffixlen = strlen(suffix);
char *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf));
strcpy(buf, prefix);
strcpy(buf + prefixlen, suffix);
return buf;
}
static
inline
char *
@ -148,15 +104,3 @@ split_argv(const char *argv0,
*exe_ptr = exe;
}
}
static
inline
int
run_final(const char *executable,
const char *const *argv)
{
execvp(executable, (char **) argv);
perror(executable);
return 1;
}