Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91ff09f7d2
|
||
|
|
4a042370b0
|
||
|
|
afa9926f6c
|
||
|
|
71cde519cb
|
||
|
|
85aacf9adf
|
||
|
|
8ed69629c0
|
||
|
|
a2c597b1bc
|
||
|
|
7c0e0b3a53
|
||
|
|
6a44f74ff8
|
||
|
|
bbb5a07443
|
||
|
|
2ee332e437
|
||
|
|
2ba34cbee2
|
||
|
|
8395dd7e9c
|
||
|
|
464cc8b090
|
||
|
|
b3c8f93cb1
|
||
|
|
a04ae78d23
|
||
|
|
55519d72e9
|
||
|
|
ef78d173cb
|
||
|
|
4ab8beba6d
|
||
|
|
1cc7c79339
|
||
|
|
a8ad222100
|
||
|
|
251f48ec88
|
@@ -1,29 +0,0 @@
|
|||||||
name: Builds
|
|
||||||
run-name: ${{ github.actor }} runs Gitea Actions
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
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: |
|
|
||||||
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-*-${{ matrix.target }}.*)
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
binaries/*
|
|
||||||
sources/*
|
|
||||||
xtchain-*.zst
|
|
||||||
@@ -1,49 +1,22 @@
|
|||||||
<p align=center>
|
|
||||||
<a href="https://git.codingworkshop.eu.org/xt-sys/xtchain">
|
|
||||||
<img alt="GIT Repository" src="https://img.shields.io/badge/Source-GIT-purple">
|
|
||||||
</a>
|
|
||||||
<a href="https://git.codingworkshop.eu.org/xt-sys/xtchain/actions">
|
|
||||||
<img alt="Build Status" src="https://codingworkshop.eu.org/actions.php?project=xt-sys/xtchain">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/xt-sys/xtchain/releases">
|
|
||||||
<img alt="Releases" src="https://img.shields.io/github/v/release/xt-sys/xtchain?label=Release&color=blueviolet">
|
|
||||||
</a>
|
|
||||||
<a href="https://git.codingworkshop.eu.org/xt-sys/xtchain/src/branch/master/COPYING.md">
|
|
||||||
<img alt="License" src="https://img.shields.io/badge/License-GPLv3-blue.svg">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/sponsors/xt-sys/">
|
|
||||||
<img alt="Sponsors" src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=GitHub">
|
|
||||||
</a>
|
|
||||||
<a href="https://discord.com/invite/zBzJ5qMGX7">
|
|
||||||
<img alt="Discord" src="https://img.shields.io/badge/Chat-Join%20Discord-success">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## XT Toolchain
|
## XT Toolchain
|
||||||
The XT Toolchain is a build environment based on LLVM/Clang/LLD. It currently supports C and C++, and includes
|
This is a GNU-based mingw-w64 toolchain. It currently supports C and C++, and provides a variety of
|
||||||
a variety of auxiliary tools such as IDL, message, and resource compilers. The XT Toolchain is the official
|
tools including IDL, message and resource compilers. The XT Toolchain is also the official build
|
||||||
build system for compiling XT software, including the XT OS. It is currently available for Linux and Windows
|
environment for compiling XT software, including the FerretOS. Currently, it is targeted at Linux
|
||||||
host systems.
|
host only, however it should be possible to build it in MSYS2 as well.
|
||||||
|
|
||||||
Key Benefits of using an LLVM-based Toolchain:
|
This software includes:
|
||||||
* Unified toolchain for multiple target architectures: i686, x86_64, armv7, and aarch64
|
* Binutils
|
||||||
* Support for generating debug information in PDB format
|
|
||||||
* Ability to target ARM/AArch64 architectures and produce ARM binaries
|
|
||||||
|
|
||||||
This toolchain includes the following software:
|
|
||||||
* CMake
|
* CMake
|
||||||
* LLVM
|
* GCC
|
||||||
|
* Make
|
||||||
|
* Mingw-w64
|
||||||
* Ninja
|
* Ninja
|
||||||
* Wine
|
* Wine
|
||||||
|
|
||||||
**Note:** This toolchain is based on the [LLVM MinGW Toolchain](https://github.com/mstorsjo/llvm-mingw).
|
|
||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
The XTchain project includes scripts for building and assembling the toolchain, as well as the environment
|
The XTchain project includes the scripts for building and assembling a toolchain as well as
|
||||||
shell. These components are licensed under the GNU GPLv3 license. This license applies only to the parts
|
environmental shell. These are licensed under the GPLv3 license. It covers only mentioned
|
||||||
provided directly by XTchain. For detailed information, please refer to the COPYING.md file.
|
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,
|
||||||
The final pre-built toolchain is subject to the licenses of the individual third-party projects it includes.
|
external projects. The full list of software incorporated into this toolchain is available in the
|
||||||
A complete list of the external software used in this toolchain can be found in the README.md file.
|
README.md file.
|
||||||
|
|||||||
Executable
+535
@@ -0,0 +1,535 @@
|
|||||||
|
#!/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="i686 x86_64"
|
||||||
|
GENERIC="generic-w64-mingw32"
|
||||||
|
|
||||||
|
# Compiler Flags
|
||||||
|
CFLAGS="-march=x86-64 -mtune=generic -O2 -s -pipe"
|
||||||
|
CXXFLAGS="${CFLAGS}"
|
||||||
|
|
||||||
|
# Binutils Settings
|
||||||
|
BINUTILSDIR="${SRCDIR}/binutils"
|
||||||
|
BINUTILSTAG="binutils-2_35"
|
||||||
|
BINUTILSVCS="git://sourceware.org/git/binutils-gdb.git"
|
||||||
|
|
||||||
|
# CMake Settings
|
||||||
|
CMAKEDIR="${SRCDIR}/cmake"
|
||||||
|
CMAKETAG="v3.18.1"
|
||||||
|
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
|
||||||
|
|
||||||
|
# GCC Settings
|
||||||
|
GCCDIR="${SRCDIR}/gcc"
|
||||||
|
GCCTAG="releases/gcc-10.2.0"
|
||||||
|
GCCVCS="git://gcc.gnu.org/git/gcc.git"
|
||||||
|
|
||||||
|
# Make Settings
|
||||||
|
MAKEDIR="${SRCDIR}/make"
|
||||||
|
MAKETAG="4.3"
|
||||||
|
MAKEVCS="git://git.savannah.gnu.org/make"
|
||||||
|
|
||||||
|
# Mingw-w64 Settings
|
||||||
|
MINGWDIR="${SRCDIR}/mingw-w64"
|
||||||
|
MINGWLIB="ucrt"
|
||||||
|
MINGWTAG="v7.0.0"
|
||||||
|
MINGWNTV="0x601"
|
||||||
|
MINGWVCS="https://github.com/mirror/mingw-w64.git"
|
||||||
|
|
||||||
|
# Ninja Settings
|
||||||
|
NINJADIR="${SRCDIR}/ninja"
|
||||||
|
NINJATAG="v1.10.0"
|
||||||
|
NINJAVCS="https://github.com/ninja-build/ninja.git"
|
||||||
|
|
||||||
|
# Wine Settings
|
||||||
|
WINEDIR="${SRCDIR}/wine"
|
||||||
|
WINETAG="wine-5.15"
|
||||||
|
WINEVCS="git://source.winehq.org/git/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 BINUTILS
|
||||||
|
binutils_build()
|
||||||
|
{
|
||||||
|
for ARCH in ${ARCHS}; do
|
||||||
|
echo ">>> Building BINUTILS for ${ARCH} ..."
|
||||||
|
[ -z ${CLEAN} ] || rm -rf ${BINUTILSDIR}/build-${ARCH}
|
||||||
|
mkdir -p ${BINUTILSDIR}/build-${ARCH}
|
||||||
|
cd ${BINUTILSDIR}/build-${ARCH}
|
||||||
|
../configure \
|
||||||
|
--target=${ARCH}-w64-mingw32 \
|
||||||
|
--prefix=${BINDIR} \
|
||||||
|
--with-sysroot=${BINDIR} \
|
||||||
|
--with-zlib=yes \
|
||||||
|
--disable-multilib \
|
||||||
|
--disable-nls \
|
||||||
|
--disable-werror \
|
||||||
|
--enable-gold \
|
||||||
|
--enable-lto \
|
||||||
|
--enable-plugins
|
||||||
|
make -j${CORES}
|
||||||
|
make install
|
||||||
|
done
|
||||||
|
cd ${WRKDIR}
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function downloads BINUTILS from VCS
|
||||||
|
binutils_fetch()
|
||||||
|
{
|
||||||
|
if [ ! -d ${BINUTILSDIR} ]; then
|
||||||
|
echo ">>> Downloading BINUTILS ..."
|
||||||
|
git clone ${BINUTILSVCS} ${BINUTILSDIR}
|
||||||
|
cd ${BINUTILSDIR}
|
||||||
|
git checkout tags/${BINUTILSTAG}
|
||||||
|
apply_patches ${BINUTILSDIR##*/} ${BINUTILSTAG##*-}
|
||||||
|
cd ${WRKDIR}
|
||||||
|
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 ${CMAKEVCS} ${CMAKEDIR}
|
||||||
|
cd ${CMAKEDIR}
|
||||||
|
git checkout tags/${CMAKETAG}
|
||||||
|
apply_patches ${CMAKEDIR##*/} ${CMAKETAG}
|
||||||
|
cd ${WRKDIR}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function compiles and install GCC (phase 1)
|
||||||
|
gcc_build_phase1()
|
||||||
|
{
|
||||||
|
for ARCH in ${ARCHS}; do
|
||||||
|
echo ">>> Building GCC (phase1) for ${ARCH} ..."
|
||||||
|
[ -z ${CLEAN} ] || rm -rf ${GCCDIR}/build-${ARCH}
|
||||||
|
mkdir -p ${GCCDIR}/build-${ARCH}
|
||||||
|
cd ${GCCDIR}/build-${ARCH}
|
||||||
|
../configure \
|
||||||
|
--target=${ARCH}-w64-mingw32 \
|
||||||
|
--prefix=${BINDIR} \
|
||||||
|
--with-sysroot=${BINDIR} \
|
||||||
|
--with-pkgversion="FerretOS Build Environment" \
|
||||||
|
--without-zstd \
|
||||||
|
--disable-libstdcxx-verbose \
|
||||||
|
--disable-multilib \
|
||||||
|
--disable-nls \
|
||||||
|
--disable-shared \
|
||||||
|
--disable-werror \
|
||||||
|
--disable-win32-registry \
|
||||||
|
--enable-fully-dynamic-string \
|
||||||
|
--enable-languages=c,c++ \
|
||||||
|
--enable-lto \
|
||||||
|
--enable-sjlj-exceptions \
|
||||||
|
--enable-version-specific-runtime-libs
|
||||||
|
make -j${CORES} all-gcc
|
||||||
|
make install-gcc
|
||||||
|
make install-lto-plugin
|
||||||
|
done
|
||||||
|
cd ${WRKDIR}
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function compiles and install GCC (phase 2)
|
||||||
|
gcc_build_phase2()
|
||||||
|
{
|
||||||
|
for ARCH in ${ARCHS}; do
|
||||||
|
echo ">>> Building GCC (phase2) for ${ARCH} ..."
|
||||||
|
cd ${GCCDIR}/build-${ARCH}
|
||||||
|
make -j${CORES}
|
||||||
|
make install
|
||||||
|
done
|
||||||
|
cd ${WRKDIR}
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function downloads GCC from VCS
|
||||||
|
gcc_fetch()
|
||||||
|
{
|
||||||
|
if [ ! -d ${GCCDIR} ]; then
|
||||||
|
echo ">>> Downloading GCC ..."
|
||||||
|
git clone ${GCCVCS} ${GCCDIR}
|
||||||
|
cd ${GCCDIR}
|
||||||
|
git checkout tags/${GCCTAG}
|
||||||
|
apply_patches ${GCCDIR##*/} ${GCCTAG##*-}
|
||||||
|
./contrib/download_prerequisites
|
||||||
|
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 ${MAKEVCS} ${MAKEDIR}
|
||||||
|
cd ${MAKEDIR}
|
||||||
|
git checkout tags/${MAKETAG}
|
||||||
|
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
|
||||||
|
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} \
|
||||||
|
${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
|
||||||
|
mkdir -p ${BINDIR}/mingw
|
||||||
|
if [ ! -e ${BINDIR}/mingw/include ]; then
|
||||||
|
ln -sfn ../${GENERIC}/include ${BINDIR}/mingw/include
|
||||||
|
fi
|
||||||
|
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 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
|
||||||
|
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 genlib 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 ${MINGWVCS} ${MINGWDIR}
|
||||||
|
cd ${MINGWDIR}
|
||||||
|
git checkout tags/${MINGWTAG}
|
||||||
|
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 ${NINJAVCS} ${NINJADIR}
|
||||||
|
cd ${NINJADIR}
|
||||||
|
git checkout tags/${NINJATAG}
|
||||||
|
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-x
|
||||||
|
for TOOL in winedump wmc wrc; do
|
||||||
|
make -j${CORES} tools/${TOOL}
|
||||||
|
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 ${WINEVCS} ${WINEDIR}
|
||||||
|
cd ${WINEDIR}
|
||||||
|
git checkout tags/${WINETAG}
|
||||||
|
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
|
||||||
|
for ARCH in ${ARCHS}; do
|
||||||
|
for EXEC in 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}/
|
||||||
|
cd ${WRKDIR}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Exit immediately on any failure
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check if script launched as root
|
||||||
|
if [ "$(whoami)" = "root" ]; then
|
||||||
|
echo "This script cannot be run as root!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check number of CPU cores available
|
||||||
|
: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)}
|
||||||
|
: ${CORES:=$(nproc 2>/dev/null)}
|
||||||
|
: ${CORES:=1}
|
||||||
|
|
||||||
|
# Create working directories
|
||||||
|
mkdir -p ${BINDIR}
|
||||||
|
mkdir -p ${SRCDIR}
|
||||||
|
|
||||||
|
# Export compiler flags
|
||||||
|
export CFLAGS
|
||||||
|
export CXXFLAGS
|
||||||
|
|
||||||
|
# XTchain
|
||||||
|
xtchain_build
|
||||||
|
|
||||||
|
# Download Mingw-W64
|
||||||
|
mingw_fetch
|
||||||
|
|
||||||
|
# Build and install Mingw-W64 headers
|
||||||
|
mingw_build_headers
|
||||||
|
|
||||||
|
# Download Binutils
|
||||||
|
binutils_fetch
|
||||||
|
|
||||||
|
# Build and install Binutils
|
||||||
|
binutils_build
|
||||||
|
|
||||||
|
# Download GCC
|
||||||
|
gcc_fetch
|
||||||
|
|
||||||
|
# Build and install minimal GCC
|
||||||
|
gcc_build_phase1
|
||||||
|
|
||||||
|
# Build and install MSVCRT
|
||||||
|
mingw_build_crt
|
||||||
|
|
||||||
|
# Build and install GCC
|
||||||
|
gcc_build_phase2
|
||||||
|
|
||||||
|
# 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,mingw,share/{bash-completion,emacs,gcc*,info,man,vim}}
|
||||||
|
|
||||||
|
# Save XT Toolchain version
|
||||||
|
cd ${WRKDIR}
|
||||||
|
: ${XTCVER:=$(git describe --exact-match --tags 2>/dev/null)}
|
||||||
|
: ${XTCVER:=DEV}
|
||||||
|
echo "${XTCVER}" > ${BINDIR}/Version
|
||||||
|
|
||||||
|
# Prepare archive
|
||||||
|
echo ">>> Creating toolchain archive ..."
|
||||||
|
tar -I 'zstd -19' -cpf xtchain-${XTCVER}-linux.tar.zst -C ${BINDIR} .
|
||||||
@@ -1,548 +0,0 @@
|
|||||||
#!/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.4.3"
|
|
||||||
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
|
|
||||||
|
|
||||||
# LLVM Settings
|
|
||||||
LLVMDIR="${SRCDIR}/llvm"
|
|
||||||
LLVMTAG="llvmorg-23.1.2"
|
|
||||||
LLVMVCS="https://github.com/llvm/llvm-project.git"
|
|
||||||
|
|
||||||
# Mtools Settings
|
|
||||||
MTOOLSDIR="${SRCDIR}/mtools"
|
|
||||||
MTOOLSTAG="v4.0.49"
|
|
||||||
MTOOLSVCS="https://github.com/xt-sys/mtools.git"
|
|
||||||
|
|
||||||
# Ninja Settings
|
|
||||||
NINJADIR="${SRCDIR}/ninja"
|
|
||||||
NINJATAG="v1.13.2"
|
|
||||||
NINJAVCS="https://github.com/ninja-build/ninja.git"
|
|
||||||
|
|
||||||
# Wine Settings
|
|
||||||
WINEDIR="${SRCDIR}/wine"
|
|
||||||
WINETAG="wine-10.19"
|
|
||||||
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 MTOOLS
|
|
||||||
mtools_build()
|
|
||||||
{
|
|
||||||
local CONFIGURE_PARAMETERS=""
|
|
||||||
local EXTENSION=""
|
|
||||||
|
|
||||||
# Clean old build if necessary
|
|
||||||
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${MTOOLSDIR}/build-${SYSTEM_NAME}
|
|
||||||
|
|
||||||
# Additional, target-specific configuration options
|
|
||||||
case "${SYSTEM_NAME}" in
|
|
||||||
Windows)
|
|
||||||
CONFIGURE_PARAMETERS="${CONFIGURE_PARAMETERS} --host=${SYSTEM_HOST}"
|
|
||||||
EXTENSION=".exe"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Build Mtools
|
|
||||||
echo ">>> Building MTOOLS ..."
|
|
||||||
mkdir -p ${MTOOLSDIR}/build-${SYSTEM_NAME}
|
|
||||||
cd ${MTOOLSDIR}/build-${SYSTEM_NAME}
|
|
||||||
../configure ${CONFIGURE_PARAMETERS}
|
|
||||||
make -j ${BUILD_JOBS}
|
|
||||||
cp mtools${EXTENSION} ${BINDIR}/bin/
|
|
||||||
for TOOL in mcat mcd mcopy mdel mdir mformat minfo mlabel mmd mmove mpartition mrd mren mshowfat mtype mzip; do
|
|
||||||
cp mtools${EXTENSION} ${BINDIR}/bin/${TOOL}${EXTENSION}
|
|
||||||
done
|
|
||||||
cd ${WRKDIR}
|
|
||||||
}
|
|
||||||
|
|
||||||
# This function downloads MTOOLS from VCS
|
|
||||||
mtools_fetch()
|
|
||||||
{
|
|
||||||
if [ ! -d ${MTOOLSDIR} ]; then
|
|
||||||
echo ">>> Downloading MTOOLS ..."
|
|
||||||
git clone --depth 1 --branch ${MTOOLSTAG} ${MTOOLSVCS} ${MTOOLSDIR}
|
|
||||||
cd ${MTOOLSDIR}
|
|
||||||
apply_patches ${MTOOLSDIR##*/} ${MTOOLSTAG}
|
|
||||||
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"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
CCOMPILER="clang"
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Build XTchain tools
|
|
||||||
echo ">>> Building XTchain tools ..."
|
|
||||||
mkdir -p ${BINDIR}/bin
|
|
||||||
mkdir -p ${BINDIR}/lib/xtchain
|
|
||||||
for EXEC in bin2c diskimg exetool mkxthv xtadkgen xtcspecc xtnlsc; do
|
|
||||||
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
|
|
||||||
${CCOMPILER} -I${WRKDIR}/tools/includes ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
cp ${WRKDIR}/scripts/xtclib* ${BINDIR}/lib/xtchain/
|
|
||||||
cp ${WRKDIR}/scripts/xtchain* ${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}-lite"
|
|
||||||
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
|
|
||||||
|
|
||||||
# Download and build GNU Mtools
|
|
||||||
mtools_fetch
|
|
||||||
mtools_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
|
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
|
||||||
|
index 5149ef582b..f09e4b7382 100644
|
||||||
|
--- a/bfd/peXXigen.c
|
||||||
|
+++ b/bfd/peXXigen.c
|
||||||
|
@@ -2952,6 +2952,25 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
|
||||||
|
case IMAGE_SUBSYSTEM_XBOX:
|
||||||
|
subsystem_name = "XBOX";
|
||||||
|
break;
|
||||||
|
+ /* These are the XT specific subsystems */
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_DRIVER:
|
||||||
|
+ subsystem_name = "XT driver";
|
||||||
|
+ break;
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_NATIVE:
|
||||||
|
+ subsystem_name = "XT native";
|
||||||
|
+ break;
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_GDIAPP:
|
||||||
|
+ subsystem_name = "XT GDI application";
|
||||||
|
+ break;
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_CLIAPP:
|
||||||
|
+ subsystem_name = "XT CLI application";
|
||||||
|
+ break;
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_PSXAPP:
|
||||||
|
+ subsystem_name = "XT PSX application";
|
||||||
|
+ break;
|
||||||
|
+ case IMAGE_SUBSYSTEM_XT_DYNLIB:
|
||||||
|
+ subsystem_name = "XT dynamic library";
|
||||||
|
+ break;
|
||||||
|
/* Added default case for clarity - subsystem_name is NULL anyway. */
|
||||||
|
default:
|
||||||
|
subsystem_name = NULL;
|
||||||
|
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
|
||||||
|
index 3866c7f458..55e069831b 100644
|
||||||
|
--- a/binutils/objcopy.c
|
||||||
|
+++ b/binutils/objcopy.c
|
||||||
|
@@ -4860,7 +4860,13 @@ set_pe_subsystem (const char *s)
|
||||||
|
{ "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER },
|
||||||
|
{ "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER },
|
||||||
|
{ "sal-rtd", 1, IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER },
|
||||||
|
- { "xbox", 0, IMAGE_SUBSYSTEM_XBOX }
|
||||||
|
+ { "xbox", 0, IMAGE_SUBSYSTEM_XBOX },
|
||||||
|
+ { "xt-driver", 0, IMAGE_SUBSYSTEM_XT_DRIVER },
|
||||||
|
+ { "xt-native", 0, IMAGE_SUBSYSTEM_XT_NATIVE },
|
||||||
|
+ { "xt-gdiapp", 0, IMAGE_SUBSYSTEM_XT_GDIAPP },
|
||||||
|
+ { "xt-cliapp", 0, IMAGE_SUBSYSTEM_XT_CLIAPP },
|
||||||
|
+ { "xt-psxapp", 0, IMAGE_SUBSYSTEM_XT_PSXAPP },
|
||||||
|
+ { "xt-dynlib", 0, IMAGE_SUBSYSTEM_XT_DYNLIB }
|
||||||
|
};
|
||||||
|
short value;
|
||||||
|
char *copy;
|
||||||
|
diff --git a/include/coff/pe.h b/include/coff/pe.h
|
||||||
|
index c83a958eee..deeea6b49a 100644
|
||||||
|
--- a/include/coff/pe.h
|
||||||
|
+++ b/include/coff/pe.h
|
||||||
|
@@ -169,6 +169,12 @@
|
||||||
|
#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
|
||||||
|
#define IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
|
||||||
|
#define IMAGE_SUBSYSTEM_XBOX 14
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_DRIVER 21
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_NATIVE 22
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_GDIAPP 23
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_CLIAPP 24
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_PSXAPP 25
|
||||||
|
+#define IMAGE_SUBSYSTEM_XT_DYNLIB 26
|
||||||
|
|
||||||
|
/* NT allows long filenames, we want to accommodate this.
|
||||||
|
This may break some of the bfd functions. */
|
||||||
|
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
|
||||||
|
index 3899c9d92c..c9277ded20 100644
|
||||||
|
--- a/ld/emultempl/pe.em
|
||||||
|
+++ b/ld/emultempl/pe.em
|
||||||
|
@@ -539,6 +539,12 @@ set_entry_point (void)
|
||||||
|
{ 7, "__PosixProcessStartup"},
|
||||||
|
{ 9, "WinMainCRTStartup" },
|
||||||
|
{14, "mainCRTStartup" },
|
||||||
|
+ {21, "XtDriverStartup" },
|
||||||
|
+ {22, "XtProcessStartup" },
|
||||||
|
+ {23, "XtgMainProcessStartup" },
|
||||||
|
+ {24, "XtcMainProcessStartup" },
|
||||||
|
+ {25, "XtpMainProcessStartup" },
|
||||||
|
+ {26, "XtlMainLibraryStartup" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -606,6 +611,12 @@ set_pe_subsystem (void)
|
||||||
|
{ "posix", 7},
|
||||||
|
{ "wince", 9},
|
||||||
|
{ "xbox", 14},
|
||||||
|
+ { "xt-driver", 21},
|
||||||
|
+ { "xt-native", 22},
|
||||||
|
+ { "xt-gdiapp", 23},
|
||||||
|
+ { "xt-cliapp", 24},
|
||||||
|
+ { "xt-psxapp", 25},
|
||||||
|
+ { "xt-dynlib", 26},
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
|
||||||
|
index a0a7023e70..001aa34769 100644
|
||||||
|
--- a/ld/emultempl/pep.em
|
||||||
|
+++ b/ld/emultempl/pep.em
|
||||||
|
@@ -504,6 +504,12 @@ set_entry_point (void)
|
||||||
|
{ 7, "__PosixProcessStartup" },
|
||||||
|
{ 9, "WinMainCRTStartup" },
|
||||||
|
{14, "mainCRTStartup" },
|
||||||
|
+ {21, "XtDriverStartup" },
|
||||||
|
+ {22, "XtProcessStartup" },
|
||||||
|
+ {23, "XtgMainProcessStartup" },
|
||||||
|
+ {24, "XtcMainProcessStartup" },
|
||||||
|
+ {25, "XtpMainProcessStartup" },
|
||||||
|
+ {26, "XtlMainLibraryStartup" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -568,6 +573,12 @@ set_pep_subsystem (void)
|
||||||
|
{ "posix", 7 },
|
||||||
|
{ "wince", 9 },
|
||||||
|
{ "xbox", 14 },
|
||||||
|
+ { "xt-driver", 21},
|
||||||
|
+ { "xt-native", 22},
|
||||||
|
+ { "xt-gdiapp", 23},
|
||||||
|
+ { "xt-cliapp", 24},
|
||||||
|
+ { "xt-psxapp", 25},
|
||||||
|
+ { "xt-dynlib", 26},
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
Though GOLD is not yet enabled for TDM-GCC, this patch will help
|
||||||
|
|
||||||
|
From: J.M. Eubank <john@thesnappy.net>
|
||||||
|
|
||||||
|
From
|
||||||
|
<https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-binutils/0001-enable-gold-on.mingw32.patch>
|
||||||
|
---
|
||||||
|
0 files changed
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 6a9719f6..f07a3b7f 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -3001,6 +3001,7 @@ case "${ENABLE_GOLD}" in
|
||||||
|
yes|default)
|
||||||
|
# Check for ELF target.
|
||||||
|
is_elf=no
|
||||||
|
+ is_pe=no
|
||||||
|
case "${target}" in
|
||||||
|
*-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \
|
||||||
|
| *-*-linux* | *-*-gnu* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \
|
||||||
|
@@ -3012,10 +3013,12 @@ case "${ENABLE_GOLD}" in
|
||||||
|
*)
|
||||||
|
is_elf=yes
|
||||||
|
;;
|
||||||
|
- esac
|
||||||
|
+ esac;;
|
||||||
|
+ *-*-mingw*)
|
||||||
|
+ is_pe=yes;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
- if test "$is_elf" = "yes"; then
|
||||||
|
+ if test "$is_elf" = "yes" -o "$is_pe" = "yes"; then
|
||||||
|
# Check for target supported by gold.
|
||||||
|
case "${target}" in
|
||||||
|
i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-* \
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
Make GCC fully relocatable, not searching any fixed paths
|
||||||
|
|
||||||
|
From: J.M. Eubank <john@thesnappy.net>
|
||||||
|
|
||||||
|
that aren't relative to the current installation path
|
||||||
|
|
||||||
|
# HG changeset patch
|
||||||
|
# Parent 2a1167ee4ed20c6ff3558a104218585837e9963f
|
||||||
|
---
|
||||||
|
0 files changed
|
||||||
|
|
||||||
|
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
|
||||||
|
index 086c0e460..f0ceca42b 100644
|
||||||
|
--- a/gcc/config/i386/mingw32.h
|
||||||
|
+++ b/gcc/config/i386/mingw32.h
|
||||||
|
@@ -78,7 +78,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef NATIVE_SYSTEM_HEADER_COMPONENT
|
||||||
|
-#define NATIVE_SYSTEM_HEADER_COMPONENT "MINGW"
|
||||||
|
+#undef NATIVE_SYSTEM_HEADER_DIR
|
||||||
|
|
||||||
|
#undef CPP_SPEC
|
||||||
|
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} " \
|
||||||
|
@@ -183,17 +183,12 @@ along with GCC; see the file COPYING3. If not see
|
||||||
|
|
||||||
|
/* Override startfile prefix defaults. */
|
||||||
|
#ifndef STANDARD_STARTFILE_PREFIX_1
|
||||||
|
-#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/"
|
||||||
|
+#define STANDARD_STARTFILE_PREFIX_1 ""
|
||||||
|
#endif
|
||||||
|
#ifndef STANDARD_STARTFILE_PREFIX_2
|
||||||
|
#define STANDARD_STARTFILE_PREFIX_2 ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-/* For native mingw-version we need to take care that NATIVE_SYSTEM_HEADER_DIR
|
||||||
|
- macro contains POSIX-style path. See bug 52947. */
|
||||||
|
-#undef NATIVE_SYSTEM_HEADER_DIR
|
||||||
|
-#define NATIVE_SYSTEM_HEADER_DIR "/mingw/include"
|
||||||
|
-
|
||||||
|
/* Output STRING, a string representing a filename, to FILE.
|
||||||
|
We canonicalize it to be in Unix format (backslashes are replaced
|
||||||
|
forward slashes. */
|
||||||
|
diff --git a/gcc/incpath.c b/gcc/incpath.c
|
||||||
|
index bcbe20829..c5d4453d8 100644
|
||||||
|
--- a/gcc/incpath.c
|
||||||
|
+++ b/gcc/incpath.c
|
||||||
|
@@ -183,8 +183,7 @@ add_standard_paths (const char *sysroot, const char *iprefix,
|
||||||
|
str = concat (sysroot_no_trailing_dir_separator, p->fname, NULL);
|
||||||
|
free (sysroot_no_trailing_dir_separator);
|
||||||
|
}
|
||||||
|
- else if (!p->add_sysroot && relocated
|
||||||
|
- && !filename_ncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len))
|
||||||
|
+ if (relocated && !filename_ncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len))
|
||||||
|
{
|
||||||
|
static const char *relocated_prefix;
|
||||||
|
char *ostr;
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
index c0b10797e..e971b8cfd 100644
|
|
||||||
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
@@ -58,7 +58,7 @@ public:
|
|
||||||
// Keep trying to cancel ReadFile() until the thread exits.
|
|
||||||
do {
|
|
||||||
CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
|
|
||||||
- } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
|
|
||||||
+ } while (WaitForSingleObject((HANDLE)m_monitor_thread.native_handle(), 1) ==
|
|
||||||
WAIT_TIMEOUT);
|
|
||||||
m_monitor_thread.join();
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
index c0b10797e..e971b8cfd 100644
|
|
||||||
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
|
|
||||||
@@ -58,7 +58,7 @@ public:
|
|
||||||
// Keep trying to cancel ReadFile() until the thread exits.
|
|
||||||
do {
|
|
||||||
CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
|
|
||||||
- } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
|
|
||||||
+ } while (WaitForSingleObject((HANDLE)m_monitor_thread.native_handle(), 1) ==
|
|
||||||
WAIT_TIMEOUT);
|
|
||||||
m_monitor_thread.join();
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
+10
-4
@@ -6,14 +6,20 @@
|
|||||||
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
|
||||||
|
|
||||||
|
# Check if script launched as root
|
||||||
|
if [ "$(whoami)" = "root" ]; then
|
||||||
|
echo "This script cannot be run as root!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Get the absolute path to the XTchain
|
# Get the absolute path to the XTchain
|
||||||
export XTCDIR="$(realpath $(dirname "${0}"))"
|
export XTCDIR="$(realpath $(dirname ${0}))"
|
||||||
|
|
||||||
# Read the XTchain version
|
# Read the XTchain version
|
||||||
export XTCVER="$(cat "${XTCDIR}/Version")"
|
export XTCVER="$(cat ${XTCDIR}/Version)"
|
||||||
|
|
||||||
# Load the library
|
# Load the library
|
||||||
source "${XTCDIR}/lib/xtchain/xtclib"
|
source ${XTCDIR}/lib/xtchain/xtclib
|
||||||
|
|
||||||
# Set the target architecture
|
# Set the target architecture
|
||||||
: ${TARGET:=${1}}
|
: ${TARGET:=${1}}
|
||||||
@@ -41,4 +47,4 @@ export PFMAT3="\[\033[0;1;97;104m\]"
|
|||||||
export PFMAT4="\[\033[0;94;49m\]"
|
export PFMAT4="\[\033[0;94;49m\]"
|
||||||
export PFMAT5="\[\033[1;38;5;74m\]"
|
export PFMAT5="\[\033[1;38;5;74m\]"
|
||||||
export PROMPT="\n${PFMAT1} XT Toolchain ${PFMAT2}${PFMAT3} \w ${PFMAT4}${PFMAT5} "
|
export PROMPT="\n${PFMAT1} XT Toolchain ${PFMAT2}${PFMAT3} \w ${PFMAT4}${PFMAT5} "
|
||||||
bash --rcfile <(echo 'export PS1="${PROMPT}" && cd "${SRCDIR}"')
|
bash --rcfile <(echo 'source ~/.bashrc && export PS1="${PROMPT}" && cd ${SRCDIR}')
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
powershell.exe -ExecutionPolicy Bypass -NoExit -File "%~dp0xtchain.ps1"
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# 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 = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
|
||||||
|
|
||||||
# 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 {
|
|
||||||
$PROMPT = " XT Toolchain "
|
|
||||||
$CWD = (Get-Location).Path
|
|
||||||
$CHEVRON = [char]0xE0B0
|
|
||||||
$SEGMENTS = @(
|
|
||||||
@{ TEXT = $PROMPT; BGCOLOR = "Blue"; FGCOLOR = "White" },
|
|
||||||
@{ TEXT = " $CWD "; BGCOLOR = "DarkCyan"; FGCOLOR = "White" }
|
|
||||||
)
|
|
||||||
for ($INDEX = 0; $INDEX -lt $SEGMENTS.Count; $INDEX++) {
|
|
||||||
$SEGMENT = $SEGMENTS[$INDEX]
|
|
||||||
$NEXTBG = if ($INDEX + 1 -lt $SEGMENTS.Count) { $SEGMENTS[$INDEX + 1].BGCOLOR } else { "Default" }
|
|
||||||
Write-Host $SEGMENT.TEXT -NoNewLine -ForegroundColor $SEGMENT.FGCOLOR -BackgroundColor $SEGMENT.BGCOLOR
|
|
||||||
if ($NEXTBG -ne "Default") {
|
|
||||||
Write-Host $CHEVRON -NoNewLine -ForegroundColor $SEGMENT.BGCOLOR -BackgroundColor $NEXTBG
|
|
||||||
} else {
|
|
||||||
Write-Host $CHEVRON -NoNewLine -ForegroundColor $SEGMENT.BGCOLOR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return " "
|
|
||||||
}
|
|
||||||
Set-Location -Path $SRCDIR
|
|
||||||
+16
-98
@@ -4,20 +4,8 @@
|
|||||||
# FILE: scripts/xtclib
|
# FILE: scripts/xtclib
|
||||||
# DESCRIPTION: XTchain library
|
# DESCRIPTION: XTchain library
|
||||||
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
# 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 "\033[33m%*s\033[00m\n\n" $(( (${#XTC_BANNER} + 80) / 2)) "${XTC_BANNER}"
|
|
||||||
printf "###############################################################################\n\n"
|
|
||||||
}
|
|
||||||
export -f banner
|
|
||||||
|
|
||||||
# Sets the target architecture
|
# Sets the target architecture
|
||||||
charch()
|
charch()
|
||||||
{
|
{
|
||||||
@@ -26,14 +14,8 @@ charch()
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
case ${1} in
|
case ${1} in
|
||||||
"aarch64"|"arm64")
|
|
||||||
export TARGET="aarch64"
|
|
||||||
;;
|
|
||||||
"arm"|"armv7")
|
|
||||||
export TARGET="armv7"
|
|
||||||
;;
|
|
||||||
"i386"|"i486"|"i586"|"i686"|"x86")
|
"i386"|"i486"|"i586"|"i686"|"x86")
|
||||||
export TARGET="i686"
|
export TARGET="i386"
|
||||||
;;
|
;;
|
||||||
"amd64"|"x64"|"x86_64")
|
"amd64"|"x64"|"x86_64")
|
||||||
export TARGET="amd64"
|
export TARGET="amd64"
|
||||||
@@ -45,87 +27,23 @@ charch()
|
|||||||
}
|
}
|
||||||
export -f charch
|
export -f charch
|
||||||
|
|
||||||
# Sets the build type
|
|
||||||
chbuild()
|
|
||||||
{
|
|
||||||
if [ "x${1}" == "x" ]; then
|
|
||||||
echo "Syntax: chbuild [DEBUG|RELEASE]"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
case ${1} in
|
|
||||||
[Rr][Ee][Ll][Ee][Aa][Ss][Ee])
|
|
||||||
export BUILD_TYPE="RELEASE"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
export BUILD_TYPE="DEBUG"
|
|
||||||
esac
|
|
||||||
echo "Target build type: ${BUILD_TYPE}"
|
|
||||||
}
|
|
||||||
export -f chbuild
|
|
||||||
|
|
||||||
# Prints help
|
|
||||||
help()
|
|
||||||
{
|
|
||||||
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
|
# Displays version banner
|
||||||
version()
|
version()
|
||||||
{
|
{
|
||||||
local XTCHAIN_EXTTOOLS=false
|
echo "###############################################################################"
|
||||||
|
echo "# XT Toolchain v${XTCVER} for Linux #"
|
||||||
if [ ! -f "${XTCDIR}/bin/clang" ] || [ "$(which clang)" != "${XTCDIR}/bin/clang" ] || [ $(echo ${XTCVER} | grep "min") ]; then
|
echo "# by Rafal Kupiec <belliash@codingworkshop.eu.org> #"
|
||||||
XTCHAIN_EXTTOOLS=true
|
echo "###############################################################################"
|
||||||
for TOOL in {clang,clang++,cmake,lld-link,ninja}; do
|
echo
|
||||||
which ${TOOL} &> /dev/null
|
echo
|
||||||
if [ $? -ne 0 ]; then
|
echo "Binutils Version: $(${XTCDIR}/bin/i686-w64-mingw32-ld -v | cut -d' ' -f5)"
|
||||||
echo "ERROR: You are using minimal version of XTChain and '${TOOL}' has been not found in your system!"
|
echo "GCC Version: $(${XTCDIR}/bin/i686-w64-mingw32-gcc -v 2>&1| grep 'gcc version' | cut -d' ' -f3)"
|
||||||
echo "ERROR: Please install all required tools."
|
echo "IDL Compiler Version: $(${XTCDIR}/bin/i686-w64-mingw32-widl -V | grep 'version' | cut -d' ' -f5)"
|
||||||
exit 1
|
echo "Wine Message Compiler Version: $(${XTCDIR}/bin/wmc -V | grep 'version' | cut -d' ' -f5)"
|
||||||
fi
|
echo "Wine Resource Compiler Version: $(${XTCDIR}/bin/wrc --version | grep 'version' | cut -d' ' -f5)"
|
||||||
done
|
echo
|
||||||
fi
|
charch ${TARGET}
|
||||||
|
echo
|
||||||
banner
|
echo
|
||||||
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 "\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 -en "\n\nFor a list of all supported commands, type 'help'"
|
|
||||||
echo -en "\n-------------------------------------------------\n\n\n"
|
|
||||||
}
|
}
|
||||||
export -f version
|
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
|
|
||||||
}
|
|
||||||
export -f xbuild
|
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
# 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 "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 {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: XTchain
|
|
||||||
* LICENSE: See COPYING.md in the top level directory
|
|
||||||
* FILE: tools/bin2c.c
|
|
||||||
* DESCRIPTION: Binary to C converter
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xtchain.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
/* Check for proper number of arguments */
|
|
||||||
if(argc != 4)
|
|
||||||
{
|
|
||||||
printf("Usage: %s <input binary> <output file> <structure name>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the input binary file in binary mode */
|
|
||||||
FILE *inputFile = fopen(argv[1], "rb");
|
|
||||||
if(inputFile == NULL)
|
|
||||||
{
|
|
||||||
printf("Error: unable to open file %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the destination source code file in text mode */
|
|
||||||
FILE *outputFile = fopen(argv[2], "w");
|
|
||||||
if(outputFile == NULL)
|
|
||||||
{
|
|
||||||
printf("Error: unable to open file %s\n", argv[2]);
|
|
||||||
fclose(inputFile);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the size of the binary file */
|
|
||||||
fseek(inputFile, 0, SEEK_END);
|
|
||||||
long binSize = ftell(inputFile);
|
|
||||||
rewind(inputFile);
|
|
||||||
|
|
||||||
/* Allocate memory for the binary data */
|
|
||||||
unsigned char *binData = (unsigned char *)malloc(binSize);
|
|
||||||
if(binData == NULL)
|
|
||||||
{
|
|
||||||
printf("Error: unable to allocate memory for binary data\n");
|
|
||||||
fclose(inputFile);
|
|
||||||
fclose(outputFile);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the binary data into memory */
|
|
||||||
fread(binData, sizeof(unsigned char), binSize, inputFile);
|
|
||||||
|
|
||||||
/* Write the C structure to the header file */
|
|
||||||
fprintf(outputFile, "unsigned char %s[] = {", argv[3]);
|
|
||||||
for(int i = 0; i < binSize; i++)
|
|
||||||
{
|
|
||||||
fprintf(outputFile, "0x%02X", binData[i]);
|
|
||||||
if(i < binSize - 1)
|
|
||||||
{
|
|
||||||
fprintf(outputFile, ",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(outputFile, "};\nunsigned int %s_size = %ld;\n", argv[3], binSize);
|
|
||||||
free(binData);
|
|
||||||
|
|
||||||
/* Close all open files */
|
|
||||||
fclose(inputFile);
|
|
||||||
fclose(outputFile);
|
|
||||||
|
|
||||||
printf("Binary data converted to C structure successfully.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
-759
@@ -1,759 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: XTchain
|
|
||||||
* LICENSE: See COPYING.md in the top level directory
|
|
||||||
* FILE: tools/diskimg.c
|
|
||||||
* DESCRIPTION: Disk Image manipulation tool
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xtchain.h"
|
|
||||||
|
|
||||||
|
|
||||||
static RESERVED_SECTOR_INFO Fat32ReservedMap[] =
|
|
||||||
{
|
|
||||||
{0, "Main VBR"},
|
|
||||||
{1, "FSInfo Sector"},
|
|
||||||
{6, "Backup VBR"},
|
|
||||||
{7, "Backup FSInfo Sector"},
|
|
||||||
{-1, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Forward references */
|
|
||||||
static void CopyData(const char *Image, long Offset, const char *SourceDir, const char *Relative);
|
|
||||||
static void CopyImageFile(const char *Image, long Offset, const char *SourceFile, const char *Relative);
|
|
||||||
static long DetermineExtraSector(long sectors_to_write);
|
|
||||||
long GetSectorFileSize(const char *FileName);
|
|
||||||
int LoadSectors(const char *FileName, uint8_t *Buffer, int SectorCount);
|
|
||||||
static void MakeDirectory(const char *Image, long Offset, const char *Relative);
|
|
||||||
|
|
||||||
/* Copies a directory recursively to the image */
|
|
||||||
static void CopyData(const char *Image, long Offset, const char *SourceDir, const char *Relative)
|
|
||||||
{
|
|
||||||
char Path[2048];
|
|
||||||
struct dirent *Entry;
|
|
||||||
DIR *Directory;
|
|
||||||
struct stat Stat;
|
|
||||||
char new_rel[2048];
|
|
||||||
|
|
||||||
/* Create the directory in the image */
|
|
||||||
if(Relative[0] != '\0')
|
|
||||||
{
|
|
||||||
MakeDirectory(Image, Offset, Relative);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the source directory */
|
|
||||||
Directory = opendir(SourceDir);
|
|
||||||
if(!Directory)
|
|
||||||
{
|
|
||||||
/* Failed to open directory */
|
|
||||||
perror("Failed to open source directory");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read all entries in the directory */
|
|
||||||
while((Entry = readdir(Directory)))
|
|
||||||
{
|
|
||||||
/* Skip . and .. entries */
|
|
||||||
if(strcmp(Entry->d_name, ".") == 0 || strcmp(Entry->d_name, "..") == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the full path to the entry */
|
|
||||||
snprintf(Path, sizeof(Path), "%s%c%s", SourceDir, PATH_SEP, Entry->d_name);
|
|
||||||
|
|
||||||
/* Stat the entry */
|
|
||||||
if(stat(Path, &Stat) == -1)
|
|
||||||
{
|
|
||||||
/* Failed to stat entry */
|
|
||||||
perror("Failed to stat file or directory");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the relative path to the entry */
|
|
||||||
if(Relative[0] != '\0')
|
|
||||||
{
|
|
||||||
snprintf(new_rel, sizeof(new_rel), "%s/%s", Relative, Entry->d_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(new_rel, sizeof(new_rel), "%s", Entry->d_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the entry to the image */
|
|
||||||
if(S_ISDIR(Stat.st_mode))
|
|
||||||
{
|
|
||||||
/* Entry is a directory, copy it recursively */
|
|
||||||
CopyData(Image, Offset, Path, new_rel);
|
|
||||||
}
|
|
||||||
else if(S_ISREG(Stat.st_mode))
|
|
||||||
{
|
|
||||||
/* Entry is a file, copy it */
|
|
||||||
CopyImageFile(Image, Offset, Path, new_rel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the directory */
|
|
||||||
closedir(Directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copies a file to the image */
|
|
||||||
static void CopyImageFile(const char *Image, long Offset, const char *SourceFile, const char *Relative)
|
|
||||||
{
|
|
||||||
char Command[4096];
|
|
||||||
|
|
||||||
/* Copy the file to the image */
|
|
||||||
snprintf(Command, sizeof(Command), "mcopy -i \"%s@@%ld\" \"%s\" \"::/%s\"", Image, Offset, SourceFile, Relative);
|
|
||||||
if(system(Command) != 0)
|
|
||||||
{
|
|
||||||
/* Failed to copy file */
|
|
||||||
fprintf(stderr, "Faile to copy file '%s' to image\n", SourceFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determines a safe sector to write extra VBR data to */
|
|
||||||
static long DetermineExtraSector(long sectors_to_write)
|
|
||||||
{
|
|
||||||
long Candidate;
|
|
||||||
long Conflict;
|
|
||||||
long Index;
|
|
||||||
long LastSector;
|
|
||||||
|
|
||||||
/* Start search from sector 1 (sector 0 is the main VBR) */
|
|
||||||
for(Candidate = 1; Candidate < 32; Candidate++)
|
|
||||||
{
|
|
||||||
/* Calculate the last sector to write */
|
|
||||||
LastSector = Candidate + sectors_to_write - 1;
|
|
||||||
Conflict = 0;
|
|
||||||
|
|
||||||
/* Check if it fits within the reserved region (32 sectors) */
|
|
||||||
if(LastSector >= 32)
|
|
||||||
{
|
|
||||||
/* The remaining space is not large enough */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for conflicts with critical sectors */
|
|
||||||
for(Index = 0; Fat32ReservedMap[Index].SectorNumber != -1; Index++)
|
|
||||||
{
|
|
||||||
if(Candidate <= Fat32ReservedMap[Index].SectorNumber && LastSector >= Fat32ReservedMap[Index].SectorNumber)
|
|
||||||
{
|
|
||||||
/* Found a conflict */
|
|
||||||
Conflict = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure there are no conflicts */
|
|
||||||
if(!Conflict)
|
|
||||||
{
|
|
||||||
/* Found a suitable slot */
|
|
||||||
return Candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No suitable slot found */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gets the size of a file */
|
|
||||||
long GetSectorFileSize(const char *FileName)
|
|
||||||
{
|
|
||||||
FILE *File;
|
|
||||||
long Size;
|
|
||||||
|
|
||||||
/* Open the file in binary mode */
|
|
||||||
File = fopen(FileName, "rb");
|
|
||||||
if(!File)
|
|
||||||
{
|
|
||||||
/* Failed to open file */
|
|
||||||
perror("Failed to open file for size check");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the file size */
|
|
||||||
fseek(File, 0, SEEK_END);
|
|
||||||
Size = ftell(File);
|
|
||||||
|
|
||||||
/* Close the file and return the size */
|
|
||||||
fclose(File);
|
|
||||||
return Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loads one or more sectors from a file */
|
|
||||||
int LoadSectors(const char *FileName, uint8_t *Buffer, int SectorCount)
|
|
||||||
{
|
|
||||||
FILE *File;
|
|
||||||
long FileSize;
|
|
||||||
long BytesToRead = SectorCount * SECTOR_SIZE;
|
|
||||||
|
|
||||||
/* Get and validate file size */
|
|
||||||
FileSize = GetSectorFileSize(FileName);
|
|
||||||
if(FileSize < 0)
|
|
||||||
{
|
|
||||||
/* Failed to get file size */
|
|
||||||
perror("Failed to get file size");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(FileSize != BytesToRead)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: file '%s' must be exactly %ld bytes, but is %ld bytes.\n", FileName, BytesToRead, FileSize);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file in binary mode for reading */
|
|
||||||
File = fopen(FileName, "rb");
|
|
||||||
if(!File) {
|
|
||||||
/* Failed to open file */
|
|
||||||
perror("Failed to open sector file for reading");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read sectors to buffer */
|
|
||||||
if(fread(Buffer, 1, BytesToRead, File) != BytesToRead)
|
|
||||||
{
|
|
||||||
/* Failed to read sectors */
|
|
||||||
perror("Failed to read sectors from file");
|
|
||||||
fclose(File);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the file */
|
|
||||||
fclose(File);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Creates a directory in the image */
|
|
||||||
static void MakeDirectory(const char *Image, long Offset, const char *Relative)
|
|
||||||
{
|
|
||||||
char Command[4096];
|
|
||||||
|
|
||||||
/* Create the directory in the image */
|
|
||||||
snprintf(Command, sizeof(Command), "mmd -i \"%s@@%ld\" \"::/%s\"", Image, Offset, Relative);
|
|
||||||
system(Command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main function */
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
FILE *File;
|
|
||||||
long Index;
|
|
||||||
long FatFormat = 32;
|
|
||||||
char FormatCommand[512];
|
|
||||||
long FormatPartition = 0;
|
|
||||||
long DiskSizeBytes = 0;
|
|
||||||
long DiskSizeMB = 0;
|
|
||||||
long MergedSize = 0;
|
|
||||||
long PreloaderSize = 0;
|
|
||||||
long SectorsToWrite = 0;
|
|
||||||
long VbrExtraSector = -1;
|
|
||||||
long VbrFileSize = -1;
|
|
||||||
long VbrTotalSectors = 0;
|
|
||||||
long VbrLastSector = 99;
|
|
||||||
char VbrInfo[128] = "";
|
|
||||||
MBR_PARTITION Partition = {0};
|
|
||||||
char Zero[SECTOR_SIZE] = {0};
|
|
||||||
uint8_t Mbr[SECTOR_SIZE] = {0};
|
|
||||||
uint8_t ImageVbr[SECTOR_SIZE * 2] = {0};
|
|
||||||
uint8_t *MergedData = NULL;
|
|
||||||
uint8_t *PreloaderData = NULL;
|
|
||||||
uint8_t *FullVbrData = NULL;
|
|
||||||
const char *FileName = NULL;
|
|
||||||
const char *MbrFile = NULL;
|
|
||||||
const char *PreloadFile = NULL;
|
|
||||||
const char *VbrFile = NULL;
|
|
||||||
const char *CopyDir = NULL;
|
|
||||||
|
|
||||||
/* Parse command line arguments */
|
|
||||||
for(Index = 1; Index < argc; Index++)
|
|
||||||
{
|
|
||||||
if(strcmp(argv[Index], "-c") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* Copy directory */
|
|
||||||
CopyDir = argv[++Index];
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-e") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* VBR extra data sector */
|
|
||||||
VbrExtraSector = atol(argv[++Index]);
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-f") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* Format partition */
|
|
||||||
FormatPartition = 1;
|
|
||||||
FatFormat = atoi(argv[++Index]);
|
|
||||||
if(FatFormat != 16 && FatFormat != 32)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: FAT format (-f) must be 16 or 32\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-m") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* MBR file */
|
|
||||||
MbrFile = argv[++Index];
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-o") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* Output file */
|
|
||||||
FileName = argv[++Index];
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-p") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* Preloader file */
|
|
||||||
PreloadFile = argv[++Index];
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-s") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* Disk size */
|
|
||||||
DiskSizeMB = atol(argv[++Index]);
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[Index], "-v") == 0 && Index + 1 < argc)
|
|
||||||
{
|
|
||||||
/* VBR file */
|
|
||||||
VbrFile = argv[++Index];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Unknown argument */
|
|
||||||
fprintf(stderr, "Unknown argument: %s\n", argv[Index]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for required arguments */
|
|
||||||
if(DiskSizeMB <= 0 || FileName == NULL)
|
|
||||||
{
|
|
||||||
/* Missing required arguments, print usage */
|
|
||||||
fprintf(stderr, "Usage: %s -o <output.img> -s <size_MB> [-b <sector>] [-c <dir>] [-f 16|32] [-m <mbr.img>] [-p <preload.bin>] [-v <vbr.img>]\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate preload usage */
|
|
||||||
if(PreloadFile && !VbrFile)
|
|
||||||
{
|
|
||||||
/* Preloader code specified without VBR */
|
|
||||||
fprintf(stderr, "Error: Option -p (PRELOADER code) requires -v (VBR code) to be specified as well.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate disk size in bytes */
|
|
||||||
DiskSizeBytes = DiskSizeMB * 1024 * 1024;
|
|
||||||
|
|
||||||
/* Open the output file in binary mode */
|
|
||||||
File = fopen(FileName, "wb");
|
|
||||||
if(!File) {
|
|
||||||
/* Failed to open file */
|
|
||||||
perror("Failed to open disk image file");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write zeros to the disk image file */
|
|
||||||
for(Index = 0; Index < DiskSizeBytes / SECTOR_SIZE; Index++)
|
|
||||||
{
|
|
||||||
if(fwrite(Zero, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to write to disk image file */
|
|
||||||
perror("Failed to write to disk image file");
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load MBR if provided */
|
|
||||||
if(MbrFile)
|
|
||||||
{
|
|
||||||
if(LoadSectors(MbrFile, Mbr, 1) != 0)
|
|
||||||
{
|
|
||||||
/* Failed to load MBR from file */
|
|
||||||
perror("Failed to load MBR from file");
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup MBR partition as W95 FAT16 or FAT32 */
|
|
||||||
Partition.BootFlag = 0x80;
|
|
||||||
Partition.Type = (FatFormat == 16) ? 0x06 : 0x0B;
|
|
||||||
Partition.StartLBA = 2048;
|
|
||||||
Partition.Size = (DiskSizeBytes / SECTOR_SIZE) - Partition.StartLBA;
|
|
||||||
|
|
||||||
/* Write MBR */
|
|
||||||
memcpy(&Mbr[446], &Partition, sizeof(MBR_PARTITION));
|
|
||||||
Mbr[510] = 0x55;
|
|
||||||
Mbr[511] = 0xAA;
|
|
||||||
|
|
||||||
/* Write the MBR to the beginning of the disk image */
|
|
||||||
fseek(File, 0, SEEK_SET);
|
|
||||||
if(fwrite(Mbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to write MBR to disk image */
|
|
||||||
perror("Failed to write MBR to disk image");
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we need to format the partition */
|
|
||||||
if(FormatPartition)
|
|
||||||
{
|
|
||||||
/* Close file before calling external formatter */
|
|
||||||
fclose(File);
|
|
||||||
|
|
||||||
/* Build mformat command */
|
|
||||||
if(FatFormat == 16)
|
|
||||||
{
|
|
||||||
/* Format partition as FAT16 */
|
|
||||||
snprintf(FormatCommand, sizeof(FormatCommand),
|
|
||||||
"mformat -i %s@@%ld",
|
|
||||||
FileName, (long)(Partition.StartLBA * SECTOR_SIZE));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Format partition as FAT32 */
|
|
||||||
snprintf(FormatCommand, sizeof(FormatCommand),
|
|
||||||
"mformat -i %s@@%ld -F",
|
|
||||||
FileName, (long)(Partition.StartLBA * SECTOR_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Format the partition */
|
|
||||||
if(system(FormatCommand) != 0)
|
|
||||||
{
|
|
||||||
/* Failed to format partition */
|
|
||||||
perror("Failed to format partition");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reopen disk image */
|
|
||||||
File = fopen(FileName, "r+b");
|
|
||||||
if(!File) {
|
|
||||||
/* Failed to open file */
|
|
||||||
perror("Failed to reopen disk image");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the VBR created by mformat */
|
|
||||||
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
|
||||||
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to read VBR */
|
|
||||||
perror("Failed to read VBR from disk image");
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the number of hidden sectors, as mformat sets it to 0 */
|
|
||||||
if(*(uint32_t*)&ImageVbr[0x1C] == 0)
|
|
||||||
{
|
|
||||||
memcpy(&ImageVbr[0x1C], &Partition.StartLBA, sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FAT format */
|
|
||||||
if(FatFormat == 32)
|
|
||||||
{
|
|
||||||
/* For FAT32, TotalSectors32 must be set */
|
|
||||||
*(uint16_t*)&ImageVbr[0x13] = 0;
|
|
||||||
if(*(uint32_t*)&ImageVbr[0x20] == 0)
|
|
||||||
{
|
|
||||||
/* Mformat did not set the field, update it */
|
|
||||||
memcpy(&ImageVbr[0x20], &Partition.Size, sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For FAT16, check if parition size exceeds 65535 sectors */
|
|
||||||
if(Partition.Size < 65536)
|
|
||||||
{
|
|
||||||
/* Partition smaller than 32MB (65536 sectors), use 16-bit field TotalSectors16 */
|
|
||||||
if(*(uint16_t*)&ImageVbr[0x13] == 0)
|
|
||||||
{
|
|
||||||
/* Mformat did not set the field, update it */
|
|
||||||
memcpy(&ImageVbr[0x13], &((uint16_t){Partition.Size}), sizeof(uint16_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Partition larger than 32MB (65536 sectors), use 32-bit field TotalSectors32 */
|
|
||||||
*(uint16_t*)&ImageVbr[0x13] = 0;
|
|
||||||
if(*(uint32_t*)&ImageVbr[0x20] == 0)
|
|
||||||
{
|
|
||||||
/* Mformat did not set the field, update it */
|
|
||||||
memcpy(&ImageVbr[0x20], &Partition.Size, sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set DriveNumber to emulate hard disk */
|
|
||||||
ImageVbr[0x40] = 0x80;
|
|
||||||
|
|
||||||
/* Write the corrected VBR back to the disk image */
|
|
||||||
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
|
||||||
if(fwrite(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to write VBR */
|
|
||||||
perror("Failed to write VBR to disk image");
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write VBR to the start of the partition, if provided */
|
|
||||||
if(VbrFile)
|
|
||||||
{
|
|
||||||
VbrFileSize = GetSectorFileSize(VbrFile);
|
|
||||||
if(VbrFileSize < 0)
|
|
||||||
{
|
|
||||||
/* Unable to determine VBR file size */
|
|
||||||
perror("Could not get size of VBR file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if VBR file size is a multiple of sector size */
|
|
||||||
if(VbrFileSize % SECTOR_SIZE != 0)
|
|
||||||
{
|
|
||||||
/* Unable to determine VBR file size */
|
|
||||||
perror("VBR file size is not a multiple of sector size\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate number of VBR sectors */
|
|
||||||
VbrTotalSectors = VbrFileSize / SECTOR_SIZE;
|
|
||||||
|
|
||||||
/* Allocate memory for the entire VBR file */
|
|
||||||
FullVbrData = malloc(VbrFileSize);
|
|
||||||
if(!FullVbrData)
|
|
||||||
{
|
|
||||||
/* Memory allocation failed */
|
|
||||||
perror("Failed to allocate memory for VBR file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the entire VBR file into the buffer */
|
|
||||||
if(LoadSectors(VbrFile, FullVbrData, VbrTotalSectors) != 0)
|
|
||||||
{
|
|
||||||
/* Failed to load VBR from file */
|
|
||||||
perror("Failed to load VBR from file\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the existing VBR from the formatted partition to get the correct BPB */
|
|
||||||
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
|
||||||
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to read VBR from disk image */
|
|
||||||
perror("Failed to read BPB from disk image\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the BPB from the image's VBR to VBR buffer */
|
|
||||||
if(FatFormat == 32)
|
|
||||||
{
|
|
||||||
/* For FAT32, BPB is larger (up to offset 89) */
|
|
||||||
memcpy(&FullVbrData[3], &ImageVbr[3], 87);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For FAT16, BPB is smaller (up to offset 61) */
|
|
||||||
memcpy(&FullVbrData[3], &ImageVbr[3], 59);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the first 512 bytes of the final, merged VBR to the start of the partition */
|
|
||||||
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
|
||||||
if(fwrite(FullVbrData, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
/* Failed to write VBR to disk image */
|
|
||||||
perror("Failed to write VBR to disk image\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle extra VBR data if it exists */
|
|
||||||
if(FatFormat == 32)
|
|
||||||
{
|
|
||||||
/* Check if a preloader file was provided */
|
|
||||||
if(PreloadFile)
|
|
||||||
{
|
|
||||||
/* Get the size of the preloader file */
|
|
||||||
PreloaderSize = GetSectorFileSize(PreloadFile);
|
|
||||||
if(PreloaderSize < 0)
|
|
||||||
{
|
|
||||||
/* Unable to determine preloader file size */
|
|
||||||
perror("Could not get size of preloader file.\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if preloader size is multiple of 512 bytes */
|
|
||||||
if(PreloaderSize % SECTOR_SIZE != 0)
|
|
||||||
{
|
|
||||||
/* Preloader file size is not a multiple of 512 bytes */
|
|
||||||
perror("Preloader file size is not a multiple of sector size\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate buffer for preloader */
|
|
||||||
PreloaderData = malloc((size_t)PreloaderSize);
|
|
||||||
if(!PreloaderData)
|
|
||||||
{
|
|
||||||
/* Memory allocation failed */
|
|
||||||
perror("Failed to allocate memory for preloader");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load preloader data */
|
|
||||||
if(LoadSectors(PreloadFile, PreloaderData, PreloaderSize / SECTOR_SIZE) != 0)
|
|
||||||
{
|
|
||||||
/* Failed to load preloader data */
|
|
||||||
perror("Failed to load Preloader code from file\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate new buffer for the first 512 bytes of VBR and preloader */
|
|
||||||
MergedSize = SECTOR_SIZE + PreloaderSize;
|
|
||||||
MergedData = malloc(MergedSize);
|
|
||||||
if(!MergedData)
|
|
||||||
{
|
|
||||||
/* Memory allocation failed */
|
|
||||||
perror("Failed to allocate memory for Preloader file\n");
|
|
||||||
free(PreloaderData);
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge VBR and preloader data */
|
|
||||||
memcpy(MergedData, FullVbrData, SECTOR_SIZE);
|
|
||||||
memcpy(MergedData + SECTOR_SIZE, PreloaderData, PreloaderSize);
|
|
||||||
|
|
||||||
/* Free old buffers and replace with merged data */
|
|
||||||
free(FullVbrData);
|
|
||||||
free(PreloaderData);
|
|
||||||
FullVbrData = MergedData;
|
|
||||||
|
|
||||||
/* Update VBR sectors count */
|
|
||||||
VbrTotalSectors = (MergedSize + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if there is extra VBR data to write */
|
|
||||||
if(VbrTotalSectors > 1)
|
|
||||||
{
|
|
||||||
/* Check if extra sector has been provided by the user */
|
|
||||||
if(VbrExtraSector == -1)
|
|
||||||
{
|
|
||||||
/* Determine a safe sector to write extra VBR data to */
|
|
||||||
long sectors_to_write = VbrTotalSectors - 1;
|
|
||||||
VbrExtraSector = DetermineExtraSector(sectors_to_write);
|
|
||||||
if(VbrExtraSector == -1)
|
|
||||||
{
|
|
||||||
/* Failed to find a safe sector */
|
|
||||||
fprintf(stderr, "Error: Could not automatically find a safe space in the FAT32 reserved region for %ld extra VBR sectors.\n",
|
|
||||||
sectors_to_write);
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate number of sectors and last sector to write */
|
|
||||||
SectorsToWrite = VbrTotalSectors - 1;
|
|
||||||
VbrLastSector = VbrExtraSector + SectorsToWrite - 1;
|
|
||||||
|
|
||||||
/* Ensure VBR will not be writen outside the reserved region (32 sectors for FAT32) */
|
|
||||||
if(VbrLastSector >= 32)
|
|
||||||
{
|
|
||||||
/* The remaining space is not large enough to fit the extra VBR data */
|
|
||||||
fprintf(stderr, "Error: VBR file is too large. Writing to sector %ld would exceed the FAT32 reserved region (32 sectors).\n", VbrLastSector);
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Safety check: ensure we do not overwrite critical sectors */
|
|
||||||
for(Index = 0; Fat32ReservedMap[Index].SectorNumber != -1; Index++)
|
|
||||||
{
|
|
||||||
/* Check if we are about to overwrite a critical sector */
|
|
||||||
if(VbrExtraSector <= Fat32ReservedMap[Index].SectorNumber && VbrLastSector >= Fat32ReservedMap[Index].SectorNumber)
|
|
||||||
{
|
|
||||||
/* We are about to overwrite a critical sector */
|
|
||||||
fprintf(stderr, "Error: Writing VBR extra data would overwrite critical sector %d (%s).\n",
|
|
||||||
Fat32ReservedMap[Index].SectorNumber, Fat32ReservedMap[Index].Description);
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the rest of the VBR data */
|
|
||||||
fseek(File, (Partition.StartLBA + VbrExtraSector) * SECTOR_SIZE, SEEK_SET);
|
|
||||||
if(fwrite(FullVbrData + SECTOR_SIZE, 1, SectorsToWrite * SECTOR_SIZE, File) != (size_t)(SectorsToWrite * SECTOR_SIZE))
|
|
||||||
{
|
|
||||||
/* Failed to write extra VBR data to disk image */
|
|
||||||
perror("Failed to write extra VBR data to disk image");
|
|
||||||
free(FullVbrData);
|
|
||||||
fclose(File);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* FatFormat == 16 */
|
|
||||||
{
|
|
||||||
/* Check if there is extra VBR data to write */
|
|
||||||
if(VbrTotalSectors > 1 || PreloadFile)
|
|
||||||
{
|
|
||||||
/* FAT16 only supports a 1-sector VBR */
|
|
||||||
fprintf(stderr, "Error: FAT16 does not support multi-sector VBR or preloader data.\n");
|
|
||||||
free(FullVbrData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free allocated memory */
|
|
||||||
free(FullVbrData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close file */
|
|
||||||
fclose(File);
|
|
||||||
|
|
||||||
/* Copy files if requested */
|
|
||||||
if(CopyDir)
|
|
||||||
{
|
|
||||||
CopyData(FileName, (long)(Partition.StartLBA * SECTOR_SIZE), CopyDir, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if VBR was written */
|
|
||||||
if(VbrFile)
|
|
||||||
{
|
|
||||||
/* Compose VBR info string */
|
|
||||||
if(VbrExtraSector != -1)
|
|
||||||
{
|
|
||||||
if(PreloadFile)
|
|
||||||
{
|
|
||||||
/* Preloader written */
|
|
||||||
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (preloader at sector %ld)", VbrExtraSector);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* VBR with extra data */
|
|
||||||
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (extra data at sector %ld)", VbrExtraSector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Standard VBR */
|
|
||||||
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print success message */
|
|
||||||
printf("Successfully created disk image '%s' (%ld MB) with bootable W95 FAT-%ld partition%s%s%s.\n",
|
|
||||||
FileName,
|
|
||||||
DiskSizeMB,
|
|
||||||
FatFormat,
|
|
||||||
MbrFile ? ", MBR written" : "",
|
|
||||||
VbrInfo,
|
|
||||||
CopyDir ? ", files copied" : "");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
-182
@@ -1,182 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: XTchain
|
|
||||||
* LICENSE: See COPYING.md in the top level directory
|
|
||||||
* FILE: tools/exetool.c
|
|
||||||
* DESCRIPTION: Portable Executable (PE) utility for changing its signature and subsystem
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xtchain.h"
|
|
||||||
|
|
||||||
typedef struct _PE_SUBSYSTEM
|
|
||||||
{
|
|
||||||
int Identifier;
|
|
||||||
char *Name;
|
|
||||||
} PE_SUBSYSTEM, *PPE_SUBSYSTEM;
|
|
||||||
|
|
||||||
static PE_SUBSYSTEM SubSystems[] = {
|
|
||||||
{0x00, "INVALID_SUBSYSTEM"},
|
|
||||||
{0x01, "NT_NATIVE"},
|
|
||||||
{0x02, "WINDOWS_GUI"},
|
|
||||||
{0x03, "WINDOWS_CLI"},
|
|
||||||
{0x04, "WINDOWS_CE_OLD"},
|
|
||||||
{0x05, "OS2_CUI"},
|
|
||||||
{0x07, "POSIX_CUI"},
|
|
||||||
{0x08, "NATIVE_WINDOWS"},
|
|
||||||
{0x09, "WINDOWS_CE_GUI"},
|
|
||||||
{0x0A, "EFI_APPLICATION"},
|
|
||||||
{0x0B, "EFI_BOOT_SERVICE_DRIVER"},
|
|
||||||
{0x0C, "EFI_RUNTIME_DRIVER"},
|
|
||||||
{0x0D, "EFI_ROM"},
|
|
||||||
{0x0E, "XBOX"},
|
|
||||||
{0x10, "WINDOWS_BOOT_APPLICATION"},
|
|
||||||
{0x14, "XT_NATIVE_KERNEL"},
|
|
||||||
{0x15, "XT_NATIVE_APPLICATION"},
|
|
||||||
{0x16, "XT_NATIVE_DRIVER"},
|
|
||||||
{0x17, "XT_DYNAMIC_LIBRARY"},
|
|
||||||
{0x18, "XT_APPLICATION_CLI"},
|
|
||||||
{0x19, "XT_APPLICATION_GDI"}
|
|
||||||
};
|
|
||||||
|
|
||||||
PPE_SUBSYSTEM getSubSystem(char *Name)
|
|
||||||
{
|
|
||||||
int Index;
|
|
||||||
int SubSystemsCount;
|
|
||||||
PPE_SUBSYSTEM SubSystem;
|
|
||||||
|
|
||||||
/* Count number of subsystems avaialble */
|
|
||||||
SubSystemsCount = sizeof(SubSystems) / sizeof(PE_SUBSYSTEM);
|
|
||||||
|
|
||||||
/* Find subsystem */
|
|
||||||
for(Index = 0; Index < SubSystemsCount; Index++)
|
|
||||||
{
|
|
||||||
SubSystem = &SubSystems[Index];
|
|
||||||
if(strcasecmp(SubSystem->Name, Name) == 0)
|
|
||||||
{
|
|
||||||
/* Subsystem found, return its ID */
|
|
||||||
return SubSystem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No valid subsystem found */
|
|
||||||
return &SubSystems[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
char *getSubSystemName(int Identifier)
|
|
||||||
{
|
|
||||||
int Index;
|
|
||||||
int SubSystemsCount;
|
|
||||||
PPE_SUBSYSTEM SubSystem;
|
|
||||||
|
|
||||||
/* Count number of subsystems avaialble */
|
|
||||||
SubSystemsCount = sizeof(SubSystems) / sizeof(PE_SUBSYSTEM);
|
|
||||||
|
|
||||||
/* Find subsystem */
|
|
||||||
for(Index = 0; Index < SubSystemsCount; Index++)
|
|
||||||
{
|
|
||||||
SubSystem = &SubSystems[Index];
|
|
||||||
if(SubSystem->Identifier == Identifier)
|
|
||||||
{
|
|
||||||
/* Subsystem found, return its ID */
|
|
||||||
return SubSystem->Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No valid subsystem found */
|
|
||||||
return SubSystems[0].Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
FILE *ExeFile;
|
|
||||||
unsigned char Signature[4];
|
|
||||||
unsigned int HeaderOffset;
|
|
||||||
unsigned int ImageSignature;
|
|
||||||
unsigned short SubSystem;
|
|
||||||
PPE_SUBSYSTEM NewSubSystem;
|
|
||||||
|
|
||||||
/* Check for proper number of arguments */
|
|
||||||
if(argc != 3)
|
|
||||||
{
|
|
||||||
printf("Usage: %s <filename> <new SubSystem>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the new SubSystem value from the command line argument */
|
|
||||||
NewSubSystem = getSubSystem(argv[2]);
|
|
||||||
if(NewSubSystem->Identifier == 0)
|
|
||||||
{
|
|
||||||
/* Invalid SubSystem provided */
|
|
||||||
printf("Error: %s is not a valid PE SubSystem\n", argv[2]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the EXE file in binary mode */
|
|
||||||
ExeFile = fopen(argv[1], "r+b");
|
|
||||||
if(ExeFile == NULL)
|
|
||||||
{
|
|
||||||
/* Failed to open PE file */
|
|
||||||
printf("ERROR: Unable to open file %s\n", argv[1]);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that the input file has a valid DOS header */
|
|
||||||
fread(Signature, sizeof(unsigned char), 4, ExeFile);
|
|
||||||
if(Signature[0] != 'M' || Signature[1] != 'Z')
|
|
||||||
{
|
|
||||||
/* Invalid DOS header */
|
|
||||||
printf("ERROR: %s is not a valid EXE file\n", argv[1]);
|
|
||||||
fclose(ExeFile);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that the input file has a valid PE header */
|
|
||||||
fseek(ExeFile, 0x3C, SEEK_SET);
|
|
||||||
fread(&HeaderOffset, sizeof(unsigned int), 1, ExeFile);
|
|
||||||
fseek(ExeFile, HeaderOffset, SEEK_SET);
|
|
||||||
fread(Signature, sizeof(unsigned char), 4, ExeFile);
|
|
||||||
if((Signature[0] != 'P' || Signature[1] != 'E' || Signature[2] != 0 || Signature[3] != 0) &&
|
|
||||||
(Signature[0] != 'P' || Signature[1] != 'E' || Signature[2] != 'X' || Signature[3] != 'T'))
|
|
||||||
{
|
|
||||||
/* Invalid PE header */
|
|
||||||
printf("Error: %s is not a valid PE file\n", argv[1]);
|
|
||||||
fclose(ExeFile);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if setting XT subsystem */
|
|
||||||
if(NewSubSystem->Identifier >= 0x14 && NewSubSystem->Identifier <= 0x19)
|
|
||||||
{
|
|
||||||
/* Write PEXT signature */
|
|
||||||
ImageSignature = 0x54584550;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Write PE00 signature */
|
|
||||||
ImageSignature = 0x00004550;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Seek back to header offset and write new signature */
|
|
||||||
fseek(ExeFile, HeaderOffset, SEEK_SET);
|
|
||||||
fwrite(&ImageSignature, sizeof(ImageSignature), 1, ExeFile);
|
|
||||||
|
|
||||||
/* Seek to the offset of the SubSystem field in the optional header */
|
|
||||||
fseek(ExeFile, HeaderOffset + 0x5C, SEEK_SET);
|
|
||||||
|
|
||||||
/* Read the current SubSystem value */
|
|
||||||
fread(&SubSystem, sizeof(unsigned short), 1, ExeFile);
|
|
||||||
|
|
||||||
/* Seek back to the SubSystem field in the optional header */
|
|
||||||
fseek(ExeFile, -(long)sizeof(unsigned short), SEEK_CUR);
|
|
||||||
|
|
||||||
/* Write the new SubSystem value */
|
|
||||||
fwrite(&NewSubSystem->Identifier, sizeof(unsigned short), 1, ExeFile);
|
|
||||||
|
|
||||||
/* Close the file */
|
|
||||||
fclose(ExeFile);
|
|
||||||
|
|
||||||
/* Finished successfully */
|
|
||||||
printf("PE SubSystem modified: 0x%02X <%s> to 0x%02X <%s>\n",
|
|
||||||
SubSystem, getSubSystemName(SubSystem), NewSubSystem->Identifier, NewSubSystem->Name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-2069
File diff suppressed because it is too large
Load Diff
@@ -1,167 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: XTchain
|
|
||||||
* LICENSE: See COPYING.md in the top level directory
|
|
||||||
* FILE: tools/xtadkgen.c
|
|
||||||
* DESCRIPTION: XT Assembly Development Kit generator
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xtchain.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_LINE_LEN 1024
|
|
||||||
#define MAGIC_MARKER "==> "
|
|
||||||
|
|
||||||
/* Prints usage */
|
|
||||||
void PrintUsage(const char* ProgramName)
|
|
||||||
{
|
|
||||||
/* Output usage instructions to stderr */
|
|
||||||
fprintf(stderr, "Usage: %s <input1.S> [input2.S ...] -o <output.h>\n", ProgramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Processes single .S file */
|
|
||||||
void ProcessSourceFile(FILE* InFile, FILE* OutFile)
|
|
||||||
{
|
|
||||||
char LineBuffer[MAX_LINE_LEN];
|
|
||||||
char SymbolName[256];
|
|
||||||
char ValueString[256];
|
|
||||||
char *ValuePointer;
|
|
||||||
char *Marker;
|
|
||||||
|
|
||||||
/* Iterate through the input stream until the end of the file */
|
|
||||||
while(fgets(LineBuffer, sizeof(LineBuffer), InFile))
|
|
||||||
{
|
|
||||||
Marker = strstr(LineBuffer, MAGIC_MARKER);
|
|
||||||
|
|
||||||
/* Search for the predefined translation marker */
|
|
||||||
if(Marker)
|
|
||||||
{
|
|
||||||
/* Extract the symbol identifier and its associated value */
|
|
||||||
if(sscanf(Marker, "==> %255s %255s", SymbolName, ValueString) == 2)
|
|
||||||
{
|
|
||||||
/* Initialize pointer for character-level cleanup */
|
|
||||||
ValuePointer = ValueString;
|
|
||||||
|
|
||||||
/* Strip architecture-specific immediate prefixes such as '$' (AT&T) or '#' (ARM) */
|
|
||||||
while(*ValuePointer == '$' || *ValuePointer == '#')
|
|
||||||
{
|
|
||||||
/* Advance pointer to the first alpha-numeric character */
|
|
||||||
ValuePointer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate the corresponding C-preprocessor macro definition */
|
|
||||||
fprintf(OutFile, "#undef %s\n", SymbolName);
|
|
||||||
fprintf(OutFile, "#define %s %s\n\n", SymbolName, ValuePointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main function */
|
|
||||||
int main(int Argc, char* Argv[])
|
|
||||||
{
|
|
||||||
FILE* InFile;
|
|
||||||
FILE* OutFile = stdout;
|
|
||||||
const char* OutputName = NULL;
|
|
||||||
int FirstInputIndex = -1;
|
|
||||||
int InputCount = 0;
|
|
||||||
|
|
||||||
/* Validate that a minimum set of command-line arguments is present */
|
|
||||||
if(Argc < 2)
|
|
||||||
{
|
|
||||||
/* Display usage information and terminate on insufficient arguments */
|
|
||||||
PrintUsage(Argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse command-line arguments */
|
|
||||||
for(int Index = 1; Index < Argc; Index++)
|
|
||||||
{
|
|
||||||
/* Identify the output file switch */
|
|
||||||
if((strcmp(Argv[Index], "-o") == 0 || strcmp(Argv[Index], "-O") == 0) && Index + 1 < Argc)
|
|
||||||
{
|
|
||||||
/* Assign the designated output path and skip the next argument */
|
|
||||||
OutputName = Argv[++Index];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Track the first occurrence of an input file for the processing loop */
|
|
||||||
if(FirstInputIndex == -1)
|
|
||||||
{
|
|
||||||
/* Store the argument index for the subsequent file operations */
|
|
||||||
FirstInputIndex = Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment the total count of input files */
|
|
||||||
InputCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure at least one input source is available for processing */
|
|
||||||
if(InputCount == 0 || (OutputName == NULL && FirstInputIndex == -1))
|
|
||||||
{
|
|
||||||
/* Print usage and exit */
|
|
||||||
PrintUsage(Argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the output stream either to a file or default to stdout */
|
|
||||||
if(OutputName)
|
|
||||||
{
|
|
||||||
/* Attempt to open the specified output header for write access */
|
|
||||||
OutFile = fopen(OutputName, "w");
|
|
||||||
if(!OutFile)
|
|
||||||
{
|
|
||||||
/* Emit fatal error if the destination file cannot be accessed */
|
|
||||||
fprintf(stderr, "%s: Failed to open output file '%s'\n", Argv[0], OutputName);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the auto-generation warning and inclusion guard */
|
|
||||||
fprintf(OutFile, "// FILE GENERATED AUTOMATICALLY BY '%s'. DO NOT EDIT!\n\n", Argv[0]);
|
|
||||||
fprintf(OutFile, "#ifndef __XTADK_H_\n");
|
|
||||||
fprintf(OutFile, "#define __XTADK_H_\n\n");
|
|
||||||
|
|
||||||
/* Loop through the arguments again to process each input file */
|
|
||||||
for(int Index = 1; Index < Argc; Index++)
|
|
||||||
{
|
|
||||||
/* Skip the output switch and its associated parameter */
|
|
||||||
if(strcmp(Argv[Index], "-o") == 0 || strcmp(Argv[Index], "-O") == 0)
|
|
||||||
{
|
|
||||||
/* Advance the loop counter and continue */
|
|
||||||
Index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the current assembly source file */
|
|
||||||
InFile = fopen(Argv[Index], "r");
|
|
||||||
if(!InFile)
|
|
||||||
{
|
|
||||||
/* Report error for the missing file and proceed to the next input file */
|
|
||||||
fprintf(stderr, "%s: Failed to open file '%s', skipping.\n", Argv[0], Argv[Index]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add source file data to the generated header */
|
|
||||||
fprintf(OutFile, "/* Source: %s */\n", Argv[Index]);
|
|
||||||
ProcessSourceFile(InFile, OutFile);
|
|
||||||
fprintf(OutFile, "\n");
|
|
||||||
|
|
||||||
/* Close the input file handle */
|
|
||||||
fclose(InFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the inclusion guard in the output */
|
|
||||||
fprintf(OutFile, "#endif /* __XTADK_H_ */\n");
|
|
||||||
|
|
||||||
/* Check if a file handle was utilized */
|
|
||||||
if(OutFile != stdout)
|
|
||||||
{
|
|
||||||
/* Commit buffered data and close the output file */
|
|
||||||
fclose(OutFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: XTchain
|
||||||
|
* LICENSE: See COPYING.md in the top level directory
|
||||||
|
* FILE: tools/xtchain.h
|
||||||
|
* DESCRIPTION: Common header for XTchain tools
|
||||||
|
* DEVELOPERS: Martin Storsjo <martin@martin.st>
|
||||||
|
* 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 *
|
||||||
|
_tcsrchrs(const char *str,
|
||||||
|
char char1,
|
||||||
|
char char2)
|
||||||
|
{
|
||||||
|
char *ptr1 = strrchr(str, char1);
|
||||||
|
char *ptr2 = strrchr(str, char2);
|
||||||
|
|
||||||
|
if(!ptr1)
|
||||||
|
{
|
||||||
|
return ptr2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ptr2)
|
||||||
|
{
|
||||||
|
return ptr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ptr1 < ptr2)
|
||||||
|
{
|
||||||
|
return ptr2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
split_argv(const char *argv0,
|
||||||
|
char **dir_ptr,
|
||||||
|
char **basename_ptr,
|
||||||
|
char **target_ptr,
|
||||||
|
char **exe_ptr)
|
||||||
|
{
|
||||||
|
const char *sep = _tcsrchrs(argv0, '/', '\\');
|
||||||
|
char *dir = strdup(_T(""));
|
||||||
|
const char *basename = argv0;
|
||||||
|
|
||||||
|
if(sep)
|
||||||
|
{
|
||||||
|
dir = strdup(argv0);
|
||||||
|
dir[sep + 1 - argv0] = '\0';
|
||||||
|
basename = sep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
basename = strdup(basename);
|
||||||
|
char *period = strchr(basename, '.');
|
||||||
|
|
||||||
|
if(period)
|
||||||
|
{
|
||||||
|
*period = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char *target = strdup(basename);
|
||||||
|
char *dash = strrchr(target, '-');
|
||||||
|
const char *exe = basename;
|
||||||
|
|
||||||
|
if(dash)
|
||||||
|
{
|
||||||
|
*dash = '\0';
|
||||||
|
exe = dash + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dir_ptr)
|
||||||
|
{
|
||||||
|
*dir_ptr = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(basename_ptr)
|
||||||
|
{
|
||||||
|
*basename_ptr = basename;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(target_ptr)
|
||||||
|
{
|
||||||
|
*target_ptr = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exe_ptr)
|
||||||
|
{
|
||||||
|
*exe_ptr = exe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
run_final(const char *executable,
|
||||||
|
const char *const *argv)
|
||||||
|
{
|
||||||
|
execvp(executable, (char **) argv);
|
||||||
|
perror(executable);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
+182
-37
@@ -14,9 +14,10 @@
|
|||||||
|
|
||||||
#include "xtchain.h"
|
#include "xtchain.h"
|
||||||
|
|
||||||
|
|
||||||
#define XTCSPECC_VERSION "1.2"
|
#define XTCSPECC_VERSION "1.2"
|
||||||
|
|
||||||
|
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
typedef struct _STRING
|
typedef struct _STRING
|
||||||
{
|
{
|
||||||
const char *buf;
|
const char *buf;
|
||||||
@@ -48,6 +49,7 @@ enum _ARCH
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
|
typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
|
||||||
|
int gbMSComp = 0;
|
||||||
int gbImportLib = 0;
|
int gbImportLib = 0;
|
||||||
int gbNotPrivateNoWarn = 0;
|
int gbNotPrivateNoWarn = 0;
|
||||||
int gbTracing = 0;
|
int gbTracing = 0;
|
||||||
@@ -76,12 +78,12 @@ enum
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CCONV_STDCALL,
|
CC_STDCALL,
|
||||||
CCONV_CDECL,
|
CC_CDECL,
|
||||||
CCONV_FASTCALL,
|
CC_FASTCALL,
|
||||||
CCONV_THISCALL,
|
CC_THISCALL,
|
||||||
CCONV_EXTERN,
|
CC_EXTERN,
|
||||||
CCONV_STUB,
|
CC_STUB,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -256,11 +258,11 @@ OutputLine_stub(FILE *file,
|
|||||||
int bRelay = 0;
|
int bRelay = 0;
|
||||||
int bInPrototype = 0;
|
int bInPrototype = 0;
|
||||||
|
|
||||||
if(pexp->nCallingConvention != CCONV_STUB &&
|
if(pexp->nCallingConvention != CC_STUB &&
|
||||||
(pexp->uFlags & FL_STUB) == 0)
|
(pexp->uFlags & FL_STUB) == 0)
|
||||||
{
|
{
|
||||||
/* Only relay trace stdcall C functions */
|
/* Only relay trace stdcall C functions */
|
||||||
if(!gbTracing || (pexp->nCallingConvention != CCONV_STDCALL) ||
|
if(!gbTracing || (pexp->nCallingConvention != CC_STDCALL) ||
|
||||||
(pexp->uFlags & FL_NORELAY) ||
|
(pexp->uFlags & FL_NORELAY) ||
|
||||||
(pexp->strName.buf[0] == '?'))
|
(pexp->strName.buf[0] == '?'))
|
||||||
{
|
{
|
||||||
@@ -293,7 +295,7 @@ OutputLine_stub(FILE *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((giArch == ARCH_X86) &&
|
if((giArch == ARCH_X86) &&
|
||||||
pexp->nCallingConvention == CCONV_STDCALL)
|
pexp->nCallingConvention == CC_STDCALL)
|
||||||
{
|
{
|
||||||
fprintf(file, "__stdcall ");
|
fprintf(file, "__stdcall ");
|
||||||
}
|
}
|
||||||
@@ -397,7 +399,7 @@ OutputLine_stub(FILE *file,
|
|||||||
}
|
}
|
||||||
fprintf(file, ");\n");
|
fprintf(file, ");\n");
|
||||||
|
|
||||||
if(pexp->nCallingConvention == CCONV_STUB)
|
if(pexp->nCallingConvention == CC_STUB)
|
||||||
{
|
{
|
||||||
fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
|
fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
|
||||||
}
|
}
|
||||||
@@ -509,8 +511,8 @@ PrintName(FILE *fileDest,
|
|||||||
fprintf(fileDest, "%.*s", nNameLength, pcName);
|
fprintf(fileDest, "%.*s", nNameLength, pcName);
|
||||||
}
|
}
|
||||||
else if(fDeco &&
|
else if(fDeco &&
|
||||||
((pexp->nCallingConvention == CCONV_STDCALL) ||
|
((pexp->nCallingConvention == CC_STDCALL) ||
|
||||||
(pexp->nCallingConvention == CCONV_FASTCALL)))
|
(pexp->nCallingConvention == CC_FASTCALL)))
|
||||||
{
|
{
|
||||||
/* Scan for a dll forwarding dot */
|
/* Scan for a dll forwarding dot */
|
||||||
pcDot = ScanToken(pcName, '.');
|
pcDot = ScanToken(pcName, '.');
|
||||||
@@ -529,15 +531,22 @@ PrintName(FILE *fileDest,
|
|||||||
pcAt = ScanToken(pcName, '@');
|
pcAt = ScanToken(pcName, '@');
|
||||||
if(pcAt && (pcAt < (pcName + nNameLength)))
|
if(pcAt && (pcAt < (pcName + nNameLength)))
|
||||||
{
|
{
|
||||||
|
/* On GCC, we need to remove the leading stdcall underscore */
|
||||||
|
if(!gbMSComp && (pexp->nCallingConvention == CC_STDCALL))
|
||||||
|
{
|
||||||
|
pcName++;
|
||||||
|
nNameLength--;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print the already decorated function name */
|
/* Print the already decorated function name */
|
||||||
fprintf(fileDest, "%.*s", nNameLength, pcName);
|
fprintf(fileDest, "%.*s", nNameLength, pcName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Print the prefix, but skip it for stdcall */
|
/* Print the prefix, but skip it for (GCC && stdcall) */
|
||||||
if(pexp->nCallingConvention != CCONV_STDCALL)
|
if(gbMSComp || (pexp->nCallingConvention != CC_STDCALL))
|
||||||
{
|
{
|
||||||
fprintf(fileDest, "%c", pexp->nCallingConvention == CCONV_FASTCALL ? '@' : '_');
|
fprintf(fileDest, "%c", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the name with trailing decoration */
|
/* Print the name with trailing decoration */
|
||||||
@@ -551,13 +560,10 @@ PrintName(FILE *fileDest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
OutputLine_def(FILE *fileDest,
|
OutputLine_def_MS(FILE *fileDest,
|
||||||
EXPORT *pexp)
|
EXPORT *pexp)
|
||||||
{
|
{
|
||||||
DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
|
|
||||||
fprintf(fileDest, " ");
|
|
||||||
|
|
||||||
PrintName(fileDest, pexp, &pexp->strName, 0);
|
PrintName(fileDest, pexp, &pexp->strName, 0);
|
||||||
|
|
||||||
if(gbImportLib)
|
if(gbImportLib)
|
||||||
@@ -580,8 +586,8 @@ OutputLine_def(FILE *fileDest,
|
|||||||
/* If the original name was decorated, use decoration in the forwarder as well */
|
/* If the original name was decorated, use decoration in the forwarder as well */
|
||||||
if((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
|
if((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
|
||||||
!ScanToken(pexp->strTarget.buf, '@') &&
|
!ScanToken(pexp->strTarget.buf, '@') &&
|
||||||
((pexp->nCallingConvention == CCONV_STDCALL) ||
|
((pexp->nCallingConvention == CC_STDCALL) ||
|
||||||
(pexp->nCallingConvention == CCONV_FASTCALL)) )
|
(pexp->nCallingConvention == CC_FASTCALL)) )
|
||||||
{
|
{
|
||||||
PrintName(fileDest, pexp, &pexp->strTarget, 1);
|
PrintName(fileDest, pexp, &pexp->strTarget, 1);
|
||||||
}
|
}
|
||||||
@@ -592,18 +598,104 @@ OutputLine_def(FILE *fileDest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CCONV_STUB)) &&
|
else if(((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
|
||||||
(pexp->strName.buf[0] == '?'))
|
(pexp->strName.buf[0] == '?'))
|
||||||
{
|
{
|
||||||
/* C++ stubs are forwarded to C stubs */
|
/* C++ stubs are forwarded to C stubs */
|
||||||
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
|
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
|
||||||
}
|
}
|
||||||
else if(gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CCONV_STDCALL) &&
|
else if(gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
|
||||||
(pexp->strName.buf[0] != '?'))
|
(pexp->strName.buf[0] != '?'))
|
||||||
{
|
{
|
||||||
/* Redirect it to the relay-tracing trampoline */
|
/* Redirect it to the relay-tracing trampoline */
|
||||||
fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
|
fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OutputLine_def_GCC(FILE *fileDest,
|
||||||
|
EXPORT *pexp)
|
||||||
|
{
|
||||||
|
int bTracing = 0;
|
||||||
|
/* Print the function name, with decoration for export libs */
|
||||||
|
PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
|
||||||
|
DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
|
||||||
|
|
||||||
|
/* Check if this is a forwarded export */
|
||||||
|
if(pexp->strTarget.buf)
|
||||||
|
{
|
||||||
|
int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
|
||||||
|
DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
|
||||||
|
|
||||||
|
/* print the target name, don't decorate if it is external */
|
||||||
|
fprintf(fileDest, "=");
|
||||||
|
PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
|
||||||
|
}
|
||||||
|
else if(((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
|
||||||
|
(pexp->strName.buf[0] == '?'))
|
||||||
|
{
|
||||||
|
/* C++ stubs are forwarded to C stubs */
|
||||||
|
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
|
||||||
|
}
|
||||||
|
else if(gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
|
||||||
|
(pexp->nCallingConvention == CC_STDCALL) &&
|
||||||
|
(pexp->strName.buf[0] != '?'))
|
||||||
|
{
|
||||||
|
/* Redirect it to the relay-tracing trampoline */
|
||||||
|
char buf[256];
|
||||||
|
STRING strTarget;
|
||||||
|
fprintf(fileDest, "=");
|
||||||
|
sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
|
||||||
|
strTarget.buf = buf;
|
||||||
|
strTarget.len = pexp->strName.len + 12;
|
||||||
|
PrintName(fileDest, pexp, &strTarget, 1);
|
||||||
|
bTracing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special handling for stdcall and fastcall */
|
||||||
|
if((giArch == ARCH_X86) &&
|
||||||
|
((pexp->nCallingConvention == CC_STDCALL) ||
|
||||||
|
(pexp->nCallingConvention == CC_FASTCALL)))
|
||||||
|
{
|
||||||
|
/* Is this the import lib? */
|
||||||
|
if(gbImportLib)
|
||||||
|
{
|
||||||
|
/* Is the name in the spec file decorated? */
|
||||||
|
const char* pcDeco = ScanToken(pexp->strName.buf, '@');
|
||||||
|
if(pcDeco &&
|
||||||
|
(pexp->strName.len > 1) &&
|
||||||
|
(pcDeco < pexp->strName.buf + pexp->strName.len))
|
||||||
|
{
|
||||||
|
/* Write the name including the leading @ */
|
||||||
|
fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((!pexp->strTarget.buf) && !(bTracing))
|
||||||
|
{
|
||||||
|
/* Write a forwarder to the actual decorated symbol */
|
||||||
|
fprintf(fileDest, "=");
|
||||||
|
PrintName(fileDest, pexp, &pexp->strName, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
OutputLine_def(FILE *fileDest,
|
||||||
|
EXPORT *pexp)
|
||||||
|
{
|
||||||
|
DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
|
||||||
|
fprintf(fileDest, " ");
|
||||||
|
|
||||||
|
if(gbMSComp)
|
||||||
|
OutputLine_def_MS(fileDest, pexp);
|
||||||
|
else
|
||||||
|
OutputLine_def_GCC(fileDest, pexp);
|
||||||
|
|
||||||
|
/* On GCC builds we force ordinals */
|
||||||
|
if((pexp->uFlags & FL_ORDINAL) || (!gbMSComp && !gbImportLib))
|
||||||
|
{
|
||||||
|
fprintf(fileDest, " @%d", pexp->nOrdinal);
|
||||||
|
}
|
||||||
|
|
||||||
if(pexp->uFlags & FL_NONAME)
|
if(pexp->uFlags & FL_NONAME)
|
||||||
{
|
{
|
||||||
@@ -615,7 +707,7 @@ OutputLine_def(FILE *fileDest,
|
|||||||
{
|
{
|
||||||
fprintf(fileDest, " PRIVATE");
|
fprintf(fileDest, " PRIVATE");
|
||||||
}
|
}
|
||||||
else if(pexp->nCallingConvention == CCONV_EXTERN)
|
else if(pexp->nCallingConvention == CC_EXTERN)
|
||||||
{
|
{
|
||||||
fprintf(fileDest, " DATA");
|
fprintf(fileDest, " DATA");
|
||||||
}
|
}
|
||||||
@@ -797,28 +889,28 @@ ParseFile(char* pcStart,
|
|||||||
/* Now we should get the type */
|
/* Now we should get the type */
|
||||||
if(CompareToken(pc, "stdcall"))
|
if(CompareToken(pc, "stdcall"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_STDCALL;
|
exp.nCallingConvention = CC_STDCALL;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "cdecl") ||
|
else if(CompareToken(pc, "cdecl") ||
|
||||||
CompareToken(pc, "varargs"))
|
CompareToken(pc, "varargs"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_CDECL;
|
exp.nCallingConvention = CC_CDECL;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "fastcall"))
|
else if(CompareToken(pc, "fastcall"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_FASTCALL;
|
exp.nCallingConvention = CC_FASTCALL;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "thiscall"))
|
else if(CompareToken(pc, "thiscall"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_THISCALL;
|
exp.nCallingConvention = CC_THISCALL;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "extern"))
|
else if(CompareToken(pc, "extern"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_EXTERN;
|
exp.nCallingConvention = CC_EXTERN;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "stub"))
|
else if(CompareToken(pc, "stub"))
|
||||||
{
|
{
|
||||||
exp.nCallingConvention = CCONV_STUB;
|
exp.nCallingConvention = CC_STUB;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -936,6 +1028,10 @@ ParseFile(char* pcStart,
|
|||||||
else if(CompareToken(pc, "-ordinal"))
|
else if(CompareToken(pc, "-ordinal"))
|
||||||
{
|
{
|
||||||
exp.uFlags |= FL_ORDINAL;
|
exp.uFlags |= FL_ORDINAL;
|
||||||
|
/* GCC doesn't automatically import by ordinal if an ordinal
|
||||||
|
* is found in the def file. Force it. */
|
||||||
|
if(gbImportLib && !gbMSComp)
|
||||||
|
exp.uFlags |= FL_NONAME;
|
||||||
}
|
}
|
||||||
else if(CompareToken(pc, "-stub"))
|
else if(CompareToken(pc, "-stub"))
|
||||||
{
|
{
|
||||||
@@ -985,8 +1081,8 @@ ParseFile(char* pcStart,
|
|||||||
|
|
||||||
/* Handle parameters */
|
/* Handle parameters */
|
||||||
exp.nStackBytes = 0;
|
exp.nStackBytes = 0;
|
||||||
if(exp.nCallingConvention != CCONV_EXTERN &&
|
if(exp.nCallingConvention != CC_EXTERN &&
|
||||||
exp.nCallingConvention != CCONV_STUB)
|
exp.nCallingConvention != CC_STUB)
|
||||||
{
|
{
|
||||||
/* Go to next token */
|
/* Go to next token */
|
||||||
if(!(pc = NextToken(pc)))
|
if(!(pc = NextToken(pc)))
|
||||||
@@ -1068,7 +1164,7 @@ ParseFile(char* pcStart,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle special stub cases */
|
/* Handle special stub cases */
|
||||||
if(exp.nCallingConvention == CCONV_STUB)
|
if(exp.nCallingConvention == CC_STUB)
|
||||||
{
|
{
|
||||||
/* Check for c++ mangled name */
|
/* Check for c++ mangled name */
|
||||||
if(pc[0] == '?')
|
if(pc[0] == '?')
|
||||||
@@ -1092,7 +1188,7 @@ ParseFile(char* pcStart,
|
|||||||
}
|
}
|
||||||
exp.nStackBytes = atoi(p + 1);
|
exp.nStackBytes = atoi(p + 1);
|
||||||
exp.nArgCount = exp.nStackBytes / 4;
|
exp.nArgCount = exp.nStackBytes / 4;
|
||||||
exp.nCallingConvention = CCONV_STDCALL;
|
exp.nCallingConvention = CC_STDCALL;
|
||||||
exp.uFlags |= FL_STUB;
|
exp.uFlags |= FL_STUB;
|
||||||
for(i = 0; i < exp.nArgCount; i++)
|
for(i = 0; i < exp.nArgCount; i++)
|
||||||
{
|
{
|
||||||
@@ -1130,6 +1226,41 @@ ParseFile(char* pcStart,
|
|||||||
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for special handling of OLE exports, only when MSVC
|
||||||
|
* is not used, since otherwise this is handled by MS LINK.EXE.
|
||||||
|
*/
|
||||||
|
if(!gbMSComp)
|
||||||
|
{
|
||||||
|
/* Check whether the current export is not PRIVATE, or has an ordinal */
|
||||||
|
int bIsNotPrivate = (!gbNotPrivateNoWarn && /*gbImportLib &&*/ !(exp.uFlags & FL_PRIVATE));
|
||||||
|
int bHasOrdinal = (exp.uFlags & FL_ORDINAL);
|
||||||
|
|
||||||
|
/* Check whether the current export is an OLE export, in case any of these tests pass */
|
||||||
|
if(bIsNotPrivate || bHasOrdinal)
|
||||||
|
{
|
||||||
|
for(i = 0; i < ARRAYSIZE(astrOlePrivateExports); ++i)
|
||||||
|
{
|
||||||
|
if(strlen(astrOlePrivateExports[i]) == exp.strName.len &&
|
||||||
|
strncmp(exp.strName.buf, astrOlePrivateExports[i], exp.strName.len) == 0)
|
||||||
|
{
|
||||||
|
/* The current export is an OLE export: display the corresponding warning */
|
||||||
|
if(bIsNotPrivate)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WARNING: %s line %d: Exported symbol '%.*s' should be PRIVATE\n",
|
||||||
|
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
||||||
|
}
|
||||||
|
if(bHasOrdinal)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WARNING: %s line %d: exported symbol '%.*s' should not be assigned an ordinal\n",
|
||||||
|
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pexports[*cExports] = exp;
|
pexports[*cExports] = exp;
|
||||||
(*cExports)++;
|
(*cExports)++;
|
||||||
gbDebug = 0;
|
gbDebug = 0;
|
||||||
@@ -1198,6 +1329,7 @@ void usage(void)
|
|||||||
" -n=<name> name of the dll\n"
|
" -n=<name> name of the dll\n"
|
||||||
" -a=<arch> set architecture to one of: aarch64, armv7, i686, x86_64\n"
|
" -a=<arch> set architecture to one of: aarch64, armv7, i686, x86_64\n"
|
||||||
" --implib generate a def file for an import library\n"
|
" --implib generate a def file for an import library\n"
|
||||||
|
" --msvc MSVC compatibility\n"
|
||||||
" --no-private-warnings suppress warnings about symbols that should be private\n"
|
" --no-private-warnings suppress warnings about symbols that should be private\n"
|
||||||
" --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n",
|
" --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n",
|
||||||
XTCSPECC_VERSION,
|
XTCSPECC_VERSION,
|
||||||
@@ -1261,6 +1393,10 @@ int main(int argc,
|
|||||||
{
|
{
|
||||||
gbImportLib = 1;
|
gbImportLib = 1;
|
||||||
}
|
}
|
||||||
|
else if(strcasecmp(argv[i], "--msvc") == 0)
|
||||||
|
{
|
||||||
|
gbMSComp = 1;
|
||||||
|
}
|
||||||
else if(strcasecmp(argv[i], "--no-private-warnings") == 0)
|
else if(strcasecmp(argv[i], "--no-private-warnings") == 0)
|
||||||
{
|
{
|
||||||
gbNotPrivateNoWarn = 1;
|
gbNotPrivateNoWarn = 1;
|
||||||
@@ -1380,6 +1516,15 @@ int main(int argc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!gbMSComp)
|
||||||
|
{
|
||||||
|
if(ApplyOrdinals(pexports, cExports) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "error: could not apply ordinals!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(pszDefFileName)
|
if(pszDefFileName)
|
||||||
{
|
{
|
||||||
/* Open output file */
|
/* Open output file */
|
||||||
|
|||||||
-3416
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user