Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added flang compiler #28

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM ubuntu:jammy

# persistent dependencies
RUN set -eux ; \
apt-get -y update ; \
apt-get -y --no-install-recommends install ca-certificates build-essential wget libncurses5 ;

# flang
RUN wget https://github.com/flang-compiler/flang/releases/download/flang_20190329/flang-20190329-x86-70.tgz ; \
tar -xvzf *.tgz ; \
rm -f *.tgz ; \
ldconfig ;
6 changes: 6 additions & 0 deletions bin/flang.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

# shellcheck disable=SC2068
docker exec -it flang /root/host/proxy.sh "${PWD}" ${@}
cp -rf inbox/* "${PWD}" &> /dev/null
rm -rf inbox/* &> /dev/null
152 changes: 152 additions & 0 deletions bin/gfortran
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env python3

import sys
import os
import shlex
import subprocess
import string
import random
import shutil

def join_args(args):
return ' '.join(shlex.quote(x) for x in args)

if "-dumpversion" in sys.argv:
print("10.2.0")
sys.exit(0)

arguments = []
sys_args = sys.argv
del sys_args[0]

try:
for arg in os.environ["ARCHFLAGS"].split(" "):
sys_args.append(arg)
except KeyError:
pass

if "-h" in sys_args or "--help" in sys_args:
print("The running executable emulates a Fortran compiler. If '-arch arm64' is passed, the compiler will produce an arm64 object file for iOS from the passed source. If not, gfortran located in '/opt/homebrew/bin/' will be executed.")
print("Because flang runs in a Docker container, only files under '/Users/', '/var/folders' or '/Library' can be compiled.")
sys.exit(0)

all_args_are_object_files = True

for arg in sys_args:

if os.path.isfile(arg) and not arg.endswith(".o"):
all_args_are_object_files = False

if (not "-c" and not all_args_are_object_files) in sys_args or not "-arch arm64" in " ".join(sys_args):
print("The executed Fortran compiler only supports producing object files for iOS arm64, falling back to gfortran.", file=sys.stderr)
print("To compile sources for iOS arm64, make sure to add -arch arm64 and -c.", file=sys.stderr)
sys.exit(os.system(shlex.join(["/opt/homebrew/bin/gfortran"]+sys_args)))

if "-bundle" in sys_args or all_args_are_object_files:
args = ["clang", "-undefined", "dynamic_lookup", "-shared"]
try:
for arg in os.environ["LDFLAGS"].split(" "):
args.append(arg)
except KeyError:
pass
for arg in sys_args:
if arg != "-bundle":
args.append(arg)

command = shlex.join(args)
sys.exit(os.system(command))

def convert_to_docker_path(arg):
if arg.startswith("/"):
arg = "/¡"+arg
else:
arg = os.path.join(os.getcwd(), arg)

return arg

the_previous_parameter_was_dash_o = False
the_previous_parameter_was_dash_c = False
the_previous_parameter_was_dash_arch = False
output_path = None
source = None

for arg in sys_args:

if arg == "-c":
the_previous_parameter_was_dash_c = True
elif the_previous_parameter_was_dash_c:
the_previous_parameter_was_dash_c = False
source = arg

if arg == "-o":
the_previous_parameter_was_dash_o = True
continue
elif the_previous_parameter_was_dash_o:
the_previous_parameter_was_dash_o = False
output_path = arg
continue

if arg == "-arch":
the_previous_parameter_was_dash_arch = True
continue
elif the_previous_parameter_was_dash_arch:
the_previous_parameter_was_dash_arch = False
continue

if arg == "-fallow-argument-mismatch":
continue

if os.path.exists(arg):
arg = convert_to_docker_path(arg)
if arg.startswith("-I"):
path = arg.split("-I")[-1]
arg = "-I"+convert_to_docker_path(path)

if arg.startswith("/¡"):
arg = arg[2:]

arguments.append(arg)

if output_path is None and source is not None:
parts = source.split(".")
del parts[-1]
output_path = os.getcwd()+"/"+".".join(parts)+".o"

if os.path.isfile(output_path):
sys.exit(0)

print(output_path)

dir = os.path.dirname(os.path.abspath(__file__))
cwd = os.getcwd()

arguments.insert(0, os.path.abspath(os.path.join(dir, "flang.sh")))
arguments.insert(1, "--save-temps")
flang_command = join_args(arguments)

inbox = os.path.join(cwd, ".inbox"+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5)))

try:
os.mkdir(inbox)
except FileExistsError:
pass

os.chdir(inbox)

os.system(flang_command)
file_path = None

for file in os.listdir("."):
if not file.endswith(".ll"):
try:
os.remove(file)
except FileNotFoundError:
pass
else:
file_path = os.path.join(os.getcwd(), file)

os.chdir(cwd)
llc = [os.path.join(dir, "llc"), "-mtriple=arm64-apple-ios", "-filetype=obj", file_path, "-o", output_path]
subprocess.run(llc, stdout=None, stderr=None)

shutil.rmtree(inbox)
16 changes: 16 additions & 0 deletions setup-iOS.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@ export MOBILE_FORGE_IPHONEOS_ARM64=$PYTHON_APPLE_SUPPORT/install/iOS/iphoneos.ar
export MOBILE_FORGE_IPHONESIMULATOR_ARM64=$PYTHON_APPLE_SUPPORT/install/iOS/iphonesimulator.arm64/python-$PYTHON_VERSION/bin/python$PYTHON_VER
export MOBILE_FORGE_IPHONESIMULATOR_X86_64=$PYTHON_APPLE_SUPPORT/install/iOS/iphonesimulator.x86_64/python-$PYTHON_VERSION/bin/python$PYTHON_VER

# Setup docker for fortran/flang

if ! docker info &>/dev/null; then
echo "Docker daemon not running!"
exit 1
fi

export DOCKER_DEFAULT_PLATFORM=linux/amd64
# shellcheck disable=SC2048,SC2086
DOCKER_BUILDKIT=1 docker build -t flang --compress . $*
docker stop flang &>/dev/null || true
docker rm flang &>/dev/null || true
docker run -d --name flang -v "$(pwd)/share:/root/host" -v /Users:/Users -v /var/folders:/var/folders -it flang

# Print help

echo
echo "You can now build packages with forge; e.g.:"
echo
Expand Down
5 changes: 5 additions & 0 deletions share/proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

cd /root/host || exit
cd "${1}" || exit
flang "${@:2}"