Closed cavivie closed 7 months ago
Fixed by:
ios.sh
#!/usr/bin/env bash
# Adapted from cctools-port
# https://github.com/tpoechtrager/cctools-port/tree/master/usage_examples/ios_toolchain
# This code is public domain
# https://github.com/tpoechtrager/cctools-port/issues/21#issuecomment-223382676
set -x
set -eo pipefail
# shellcheck disable=SC1091
. lib.sh
if [[ "${IOS_SDK_FILE}" == "nonexistent" ]] && [[ -z "${IOS_SDK_URL}" ]]; then
echo 'Must set the environment variable `IOS_SDK_FILE` or `IOS_SDK_URL`.' 1>&2
exit 1
fi
get_sdk_version() {
local version
version=$(echo "${1}" | grep -P -o "[0-9][0-9].[0-9]+" | head -1)
if [ -z "${version}" ]; then
version=$(echo "${1}" | grep -P -o "[0-9].[0-9]+" | head -1)
fi
if [ -z "${version}" ]; then
echo "iPhoneOS Version must be in the SDK filename!" 1>&2
exit 1
fi
echo "${version}"
}
extract() {
local tarball="${1}"
local outdir="${2}"
mkdir -p "${outdir}"
case $1 in
*.tar.xz|*.txz)
tar -xJf "${tarball}" --directory "${2}"
;;
*.tar.gz|*.tgz)
tar -xzf "${tarball}" --directory "${2}"
;;
*.tar.bz2|*.tbz2)
tar -xjf "${tarball}" --directory "${2}"
;;
*)
echo "unhandled archive type" 1>&2
exit 1
;;
esac
}
main() {
local target="${1}"
local target_cpu="${2}"
local ldid_commit="4bf8f4d60384a0693dbbe2084ce62a35bfeb87ab"
local libdispatch_commit="ee39300b12a77efd3f2f020e009e42d557adbb29"
local libtapi_commit="b8c5ac40267aa5f6004dd38cc2b2cd84f2d9d555"
local cctools_commit="a98286d858210b209395624477533c0bde05556a"
local install_dir="/opt/cctools"
local sdk_dir="${install_dir}"/SDKs
install_packages curl \
gcc \
g++ \
make
apt-get update
apt-get install --assume-yes --no-install-recommends clang \
libstdc++-10-dev \
libbz2-dev \
libssl-dev \
libxml2-dev \
zlib1g-dev \
xz-utils \
llvm-dev \
uuid-dev
local td
td="$(mktemp -d)"
pushd "${td}"
# first, extract the SDK and get the version.
mkdir sdk
pushd sdk
if [[ -f /"${IOS_SDK_FILE}" ]]; then
cp /"${IOS_SDK_FILE}" .
else
curl --retry 3 -sSfL "${IOS_SDK_URL}" -O
fi
filename=$(ls -t -1 . | head -1)
sdk_version=$(get_sdk_version "${filename}")
extract "${filename}" SDKs
# now, need to get our metadata, and move the SDK to the output dir
mkdir -p "${install_dir}"
mv SDKs "${sdk_dir}"
local syslib
syslib=$(find "${sdk_dir}" -name libSystem.dylib -o -name libSystem.tbd | head -n1)
local wrapper_sdkdir
pushd "${sdk_dir}"
wrapper_sdkdir=$(echo iPhoneOS*sdk | head -n1)
popd
popd
mkdir -p ios-wrapper
pushd ios-wrapper
cp /ios-wrapper.c .
# want targets like armv7s, arm64
mkdir -p "${install_dir}/bin"
local clang="${install_dir}/bin/${target}-clang"
gcc -O2 -Wall -Wextra -pedantic ios-wrapper.c \
-DSDK_DIR="\"${wrapper_sdkdir}\"" \
-DTARGET_CPU="\"${target_cpu}"\" \
-DOS_VER_MIN="\"${sdk_version}"\" \
-o "${clang}"
popd
# build our apple dependencies
git clone https://github.com/tpoechtrager/ldid.git --depth 1
pushd ldid
git fetch --depth=1 origin "${ldid_commit}"
make INSTALLPREFIX="${install_dir}" -j install
popd
git clone https://github.com/tpoechtrager/apple-libdispatch.git --depth 1
pushd apple-libdispatch
git fetch --depth=1 origin "${libdispatch_commit}"
CC=clang CXX=clang++ cmake \
-DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=${install_dir}
make install
popd
git clone https://github.com/tpoechtrager/apple-libtapi.git --depth 1
pushd apple-libtapi
git fetch --depth=1 origin "${libtapi_commit}"
INSTALLPREFIX="${install_dir}" ./build.sh
./install.sh
popd
# valid targets include `aarch64-apple-ios`
git clone https://github.com/tpoechtrager/cctools-port.git --depth 1
pushd cctools-port/cctools
git fetch --depth=1 origin "${cctools_commit}"
./configure \
--prefix="${install_dir}" \
--with-libtapi="${install_dir}" \
--with-libdispatch="${install_dir}" \
--with-libblocksruntime="${install_dir}" \
--target="${target}"
make -j
make install
popd
# make a symlink since clang is both a c and c++ compiler
ln -sf "${clang}" "${clang}"++
# need a fake wrapper for xcrun, which is used by `cc`.
echo '#!/usr/bin/env sh
echo "${SDKROOT}"
' > "${install_dir}/bin/xcrun"
chmod +x "${install_dir}/bin/xcrun"
purge_packages
popd
rm -rf "${td}"
rm ios-wrapper.c
rm "${0}"
}
main "${@}"
ios-wrapper.c
// Adapted from cctools-port
// https://github.com/tpoechtrager/cctools-port/tree/master/usage_examples/ios_toolchain
// This code is public domain
// https://github.com/tpoechtrager/cctools-port/issues/21#issuecomment-223382676
#ifndef OS_VER_MIN
#define OS_VER_MIN "4.2"
#endif
#ifndef SDK_DIR
#define SDK_DIR ""
#endif
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <limits.h>
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#include <sys/sysctl.h>
#endif
#ifdef __OpenBSD__
#include <sys/types.h>
#include <sys/user.h>
#include <sys/stat.h>
#endif
char *get_executable_path(char *epath, size_t buflen)
{
char *p;
#ifdef __APPLE__
unsigned int l = buflen;
if (_NSGetExecutablePath(epath, &l) != 0) return NULL;
#elif defined(__FreeBSD__) || defined(__DragonFly__)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
size_t l = buflen;
if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL;
#elif defined(__OpenBSD__)
int mib[4];
char **argv;
size_t len;
size_t l;
const char *comm;
int ok = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC_ARGS;
mib[2] = getpid();
mib[3] = KERN_PROC_ARGV;
if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0)
abort();
if (!(argv = malloc(len)))
abort();
if (sysctl(mib, 4, argv, &len, NULL, 0) < 0)
abort();
comm = argv[0];
if (*comm == '/' || *comm == '.')
{
char *rpath;
if ((rpath = realpath(comm, NULL)))
{
strlcpy(epath, rpath, buflen);
free(rpath);
ok = 1;
}
}
else
{
char *sp;
char *xpath = strdup(getenv("PATH"));
char *path = strtok_r(xpath, ":", &sp);
struct stat st;
if (!xpath)
abort();
while (path)
{
snprintf(epath, buflen, "%s/%s", path, comm);
if (!stat(epath, &st) && (st.st_mode & S_IXUSR))
{
ok = 1;
break;
}
path = strtok_r(NULL, ":", &sp);
}
free(xpath);
}
free(argv);
if (!ok) return NULL;
l = strlen(epath);
#else
ssize_t l = readlink("/proc/self/exe", epath, buflen - 1);
if (l > 0) epath[l] = '\0';
#endif
if (l <= 0) return NULL;
epath[buflen - 1] = '\0';
p = strrchr(epath, '/');
if (p) *p = '\0';
return epath;
}
char *get_filename(char *str)
{
char *p = strrchr(str, '/');
return p ? &p[1] : str;
}
void target_info(char *argv[], char **triple, char **compiler)
{
char *p = get_filename(argv[0]);
char *x = strrchr(p, '-');
if (!x) abort();
*compiler = &x[1];
*x = '\0';
*triple = p;
}
void env(char **p, const char *name, char *fallback)
{
char *ev = getenv(name);
if (ev) { *p = ev; return; }
*p = fallback;
}
int main(int argc, char *argv[])
{
char **args = alloca(sizeof(char*) * (argc+50));
int i, j;
char execpath[PATH_MAX+1];
char sdkpath[PATH_MAX+1];
char osvermin[64];
char *compiler;
char *target;
char *sdk;
char *cpu;
char *osmin;
target_info(argv, &target, &compiler);
if (!get_executable_path(execpath, sizeof(execpath))) abort();
snprintf(sdkpath, sizeof(sdkpath) - 1, "%s/../SDKs/" SDK_DIR, execpath);
env(&sdk, "IOS_SDK_SYSROOT", sdkpath);
env(&cpu, "IOS_TARGET_CPU", TARGET_CPU);
env(&osmin, "IPHONEOS_DEPLOYMENT_TARGET", OS_VER_MIN);
unsetenv("IPHONEOS_DEPLOYMENT_TARGET");
snprintf(osvermin, sizeof(osvermin), "-miphoneos-version-min=%s", osmin);
for (i = 1; i < argc; ++i)
{
if (!strcmp(argv[i], "-arch"))
{
cpu = NULL;
break;
}
}
i = 0;
args[i++] = compiler;
args[i++] = "-target";
args[i++] = target;
args[i++] = "-isysroot";
args[i++] = sdk;
if (cpu)
{
args[i++] = "-arch";
args[i++] = cpu;
}
args[i++] = osvermin;
args[i++] = "-mlinker-version=907";
args[i++] = "-Wl,-adhoc_codesign";
args[i++] = "-Wno-unused-command-line-argument";
for (j = 1; j < argc; ++i, ++j)
args[i] = argv[j];
args[i] = NULL;
setenv("COMPILER_PATH", execpath, 1);
execvp(compiler, args);
fprintf(stderr, "cannot invoke compiler!\n");
return 1;
}
The error log:
Next, try to replace
libdispatch0
withlibdispatch-dev
, but still fails, and the error log will be:Next, try to install
libstdc++-10-dev
, but still fails, and the error log will be:Next, try to use latest
cctools-port
(1009.2-ld64-907 -a98286d8
), but still fails, and the error log will be: