mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Upgrade mono repo to cosmocc 3.2
The toolchain will now be downloaded going forward from multiple pinned URLs which have shasums. Either wget or curl must be installed. This change unblocks #1053
This commit is contained in:
parent
a334f9cc33
commit
0de6a08988
75 changed files with 183 additions and 19489 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
# -*- conf -*-
|
||||
|
||||
/o
|
||||
/cosmocc
|
||||
/.prompt.jtlp
|
||||
|
||||
# TODO: Find some way to have Python write to o/
|
||||
|
|
78
Makefile
78
Makefile
|
@ -73,10 +73,13 @@ MODE := $(m)
|
|||
endif
|
||||
endif
|
||||
|
||||
COMMA := ,
|
||||
PWD := $(shell pwd)
|
||||
|
||||
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
||||
# - user ran build/bootstrap/make.com, in which case make's working directory is in wsl
|
||||
# - user ran make, in which case cocmd.com's working directory is in wsl
|
||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(shell pwd)),)
|
||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
||||
$(warning wsl2 interop is enabled)
|
||||
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
|
||||
endif
|
||||
|
@ -89,13 +92,70 @@ ifeq ($(MAKE_VERSION), 3.81)
|
|||
$(error please use build/bootstrap/make.com)
|
||||
endif
|
||||
|
||||
# provide instructions to non-linux users on unbundling gcc
|
||||
ifeq ($(TOOLCHAIN),) # if TOOLCHAIN isn't defined
|
||||
ifeq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","") # if our gcc isn't unbundled
|
||||
ifneq ($(UNAME_M)-$(UNAME_S), x86_64-Linux) # if this is not amd64 linux
|
||||
$(error please run tool/cosmocc/fetch.sh)
|
||||
endif
|
||||
LC_ALL = C
|
||||
SOURCE_DATE_EPOCH = 0
|
||||
|
||||
ARFLAGS = rcsD
|
||||
ZFLAGS ?=
|
||||
XARGS ?= xargs -P4 -rs8000
|
||||
DOT ?= dot
|
||||
CLANG = clang
|
||||
TMPDIR = o/tmp
|
||||
|
||||
AR = build/bootstrap/ar.com
|
||||
CP = build/bootstrap/cp.com
|
||||
RM = build/bootstrap/rm.com -f
|
||||
GZIP = build/bootstrap/gzip.com
|
||||
ECHO = build/bootstrap/echo.com
|
||||
CHMOD = build/bootstrap/chmod.com
|
||||
TOUCH = build/bootstrap/touch.com
|
||||
PKG = build/bootstrap/package.com
|
||||
MKDEPS = build/bootstrap/mkdeps.com
|
||||
ZIPOBJ = build/bootstrap/zipobj.com
|
||||
ZIPCOPY = build/bootstrap/zipcopy.com
|
||||
PECHECK = build/bootstrap/pecheck.com
|
||||
FIXUPOBJ = build/bootstrap/fixupobj.com
|
||||
MKDIR = build/bootstrap/mkdir.com -p
|
||||
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
|
||||
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
ifneq ($(findstring aarch64,$(MODE)),)
|
||||
ARCH = aarch64
|
||||
HOSTS ?= pi studio freebsdarm
|
||||
else
|
||||
ARCH = x86_64
|
||||
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
|
||||
endif
|
||||
|
||||
ZIPOBJ_FLAGS += -a$(ARCH)
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
export ADDR2LINE
|
||||
export LC_ALL
|
||||
export MKDIR
|
||||
export MODE
|
||||
export SOURCE_DATE_EPOCH
|
||||
export TMPDIR
|
||||
|
||||
COSMOCC = cosmocc/3.2
|
||||
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
|
||||
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e)
|
||||
|
||||
AS = $(TOOLCHAIN)as
|
||||
CC = $(TOOLCHAIN)gcc
|
||||
CXX = $(TOOLCHAIN)g++
|
||||
CXXFILT = $(TOOLCHAIN)c++filt
|
||||
LD = $(TOOLCHAIN)ld.bfd
|
||||
NM = $(TOOLCHAIN)nm
|
||||
GCC = $(TOOLCHAIN)gcc
|
||||
STRIP = $(TOOLCHAIN)strip
|
||||
OBJCOPY = $(TOOLCHAIN)objcopy
|
||||
OBJDUMP = $(TOOLCHAIN)objdump
|
||||
ifneq ($(wildcard $(PWD)/$(TOOLCHAIN)addr2line),)
|
||||
ADDR2LINE = $(PWD)/$(TOOLCHAIN)addr2line
|
||||
else
|
||||
ADDR2LINE = $(TOOLCHAIN)addr2line
|
||||
endif
|
||||
|
||||
# the default build modes is empty string
|
||||
|
@ -138,7 +198,7 @@ $(warning please run ape/apeinstall.sh if you intend to use landlock make)
|
|||
$(shell sleep .5)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
|
||||
ifneq ($(TOOLCHAIN),)
|
||||
.STRICT = 1
|
||||
endif
|
||||
endif
|
||||
|
@ -149,8 +209,8 @@ endif
|
|||
libc/stdbool.h \
|
||||
libc/disclaimer.inc \
|
||||
rwc:/dev/shm \
|
||||
rx:cosmocc \
|
||||
rx:build/bootstrap \
|
||||
rx:o/third_party/gcc \
|
||||
r:build/portcosmo.h \
|
||||
/proc/stat \
|
||||
rw:/dev/null \
|
||||
|
|
23
README.md
23
README.md
|
@ -76,18 +76,7 @@ make install
|
|||
## Cosmopolitan Source Builds
|
||||
|
||||
Cosmopolitan can be compiled from source on any of our supported
|
||||
platforms. First, you need to download or clone the repository. If
|
||||
you're not using x86-64 Linux then you'll need cosmocc too.
|
||||
|
||||
```sh
|
||||
git clone https://github.com/jart/cosmopolitan cosmo
|
||||
cd cosmo
|
||||
mkdir -p o/third_party/gcc
|
||||
pushd o/third_party/gcc
|
||||
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip
|
||||
unzip cosmocc.zip
|
||||
popd
|
||||
```
|
||||
platforms. The Makefile will download cosmocc automatically.
|
||||
|
||||
It's recommended that you install a systemwide APE Loader. This command
|
||||
requires `sudo` access to copy the `ape` command to a system folder and
|
||||
|
@ -103,7 +92,7 @@ guaranteed to be compatible and furthermore includes our extensions for
|
|||
doing build system sandboxing.
|
||||
|
||||
```sh
|
||||
o//third_party/gcc/bin/make -j8
|
||||
build/bootstrap/make.com -j8
|
||||
o//examples/hello.com
|
||||
```
|
||||
|
||||
|
@ -114,7 +103,7 @@ depends on core LIBC packages.
|
|||
|
||||
```sh
|
||||
rm -rf o//libc o//test
|
||||
o//third_party/gcc/bin/make o//test/posix/signal_test.com
|
||||
build/bootstrap/make.com o//test/posix/signal_test.com
|
||||
o//test/posix/signal_test.com
|
||||
```
|
||||
|
||||
|
@ -123,21 +112,21 @@ list out each individual one. For example if you wanted to build and run
|
|||
all the unit tests in the `TEST_POSIX` package, you could say:
|
||||
|
||||
```sh
|
||||
o//third_party/gcc/bin/make o//test/posix
|
||||
build/bootstrap/make.com o//test/posix
|
||||
```
|
||||
|
||||
Cosmopolitan provides a variety of build modes. For example, if you want
|
||||
really tiny binaries (as small as 12kb in size) then you'd say:
|
||||
|
||||
```sh
|
||||
o//third_party/gcc/bin/make m=tiny
|
||||
build/bootstrap/make.com m=tiny
|
||||
```
|
||||
|
||||
You can furthermore cut out the bloat of other operating systems, and
|
||||
have Cosmopolitan become much more similar to Musl Libc.
|
||||
|
||||
```sh
|
||||
o//third_party/gcc/bin/make m=tinylinux
|
||||
build/bootstrap/make.com m=tinylinux
|
||||
```
|
||||
|
||||
For further details, see [//build/config.mk](build/config.mk).
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -53,91 +53,6 @@
|
|||
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
|
||||
#
|
||||
|
||||
LC_ALL = C
|
||||
SOURCE_DATE_EPOCH = 0
|
||||
|
||||
ARFLAGS = rcsD
|
||||
ZFLAGS ?=
|
||||
XARGS ?= xargs -P4 -rs8000
|
||||
DOT ?= dot
|
||||
CLANG = clang
|
||||
TMPDIR = o/tmp
|
||||
|
||||
AR = build/bootstrap/ar.com
|
||||
CP = build/bootstrap/cp.com
|
||||
RM = build/bootstrap/rm.com -f
|
||||
GZIP = build/bootstrap/gzip.com
|
||||
ECHO = build/bootstrap/echo.com
|
||||
CHMOD = build/bootstrap/chmod.com
|
||||
TOUCH = build/bootstrap/touch.com
|
||||
PKG = build/bootstrap/package.com
|
||||
MKDEPS = build/bootstrap/mkdeps.com
|
||||
ZIPOBJ = build/bootstrap/zipobj.com
|
||||
ZIPCOPY = build/bootstrap/zipcopy.com
|
||||
PECHECK = build/bootstrap/pecheck.com
|
||||
FIXUPOBJ = build/bootstrap/fixupobj.com
|
||||
MKDIR = build/bootstrap/mkdir.com -p
|
||||
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
|
||||
|
||||
COMMA := ,
|
||||
PWD := $(shell build/bootstrap/pwd.com)
|
||||
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
ifneq ($(findstring aarch64,$(MODE)),)
|
||||
ARCH = aarch64
|
||||
HOSTS ?= pi studio freebsdarm
|
||||
else
|
||||
ARCH = x86_64
|
||||
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
|
||||
endif
|
||||
|
||||
ZIPOBJ_FLAGS += -a$(ARCH)
|
||||
|
||||
ifeq ($(PREFIX),)
|
||||
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ifneq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","")
|
||||
PREFIX = o/third_party/gcc/bin/x86_64-linux-cosmo-
|
||||
else
|
||||
IGNORE := $(shell build/bootstrap/unbundle.com)
|
||||
PREFIX = o/third_party/gcc/bin/x86_64-linux-musl-
|
||||
endif
|
||||
endif # ($(ARCH),x86_64))
|
||||
ifeq ($(ARCH),aarch64)
|
||||
ifneq ("$(wildcard o/third_party/gcc/bin/aarch64-linux-cosmo-*)","")
|
||||
PREFIX = o/third_party/gcc/bin/aarch64-linux-cosmo-
|
||||
else
|
||||
IGNORE := $(shell build/bootstrap/unbundle.com)
|
||||
PREFIX = o/third_party/gcc/bin/aarch64-linux-musl-
|
||||
endif
|
||||
endif # ($(ARCH),aarch64)
|
||||
endif # ($(USE_SYSTEM_TOOLCHAIN),)
|
||||
endif # ($(PREFIX),)
|
||||
|
||||
AS = $(PREFIX)as
|
||||
CC = $(PREFIX)gcc
|
||||
CXX = $(PREFIX)g++
|
||||
CXXFILT = $(PREFIX)c++filt
|
||||
LD = $(PREFIX)ld.bfd
|
||||
NM = $(PREFIX)nm
|
||||
GCC = $(PREFIX)gcc
|
||||
STRIP = $(PREFIX)strip
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
OBJDUMP = $(PREFIX)objdump
|
||||
ifneq ($(wildcard $(PWD)/$(PREFIX)addr2line),)
|
||||
ADDR2LINE = $(PWD)/$(PREFIX)addr2line
|
||||
else
|
||||
ADDR2LINE = $(PREFIX)addr2line
|
||||
endif
|
||||
|
||||
export ADDR2LINE
|
||||
export LC_ALL
|
||||
export MKDIR
|
||||
export MODE
|
||||
export SOURCE_DATE_EPOCH
|
||||
export TMPDIR
|
||||
|
||||
ifeq ($(LANDLOCKMAKE_VERSION),)
|
||||
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
|
||||
else
|
||||
|
|
91
build/download-cosmocc.sh
Executable file
91
build/download-cosmocc.sh
Executable file
|
@ -0,0 +1,91 @@
|
|||
#!/bin/sh
|
||||
# cosmocc downloader script
|
||||
# https://justine.lol/cosmo3/#install
|
||||
# https://github.com/jart/cosmopolitan/blob/master/tool/cosmocc/README.md
|
||||
|
||||
# collect arguments
|
||||
OUTPUT_DIR=${1:?OUTPUT_DIR}
|
||||
COSMOCC_VERSION=${2:?COSMOCC_VERSION}
|
||||
COSMOCC_SHA256SUM=${3:?COSMOCC_SHA256SUM}
|
||||
URL1="https://github.com/jart/cosmopolitan/releases/download/${COSMOCC_VERSION}/cosmocc-${COSMOCC_VERSION}.zip"
|
||||
URL2="https://cosmo.zip/pub/cosmocc/cosmocc-${COSMOCC_VERSION}.zip"
|
||||
|
||||
# helper function
|
||||
abort() {
|
||||
printf '%s\n' "download terminated." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# exit if already downloaded
|
||||
# we need it because directory timestamps work wierdly
|
||||
OUTPUT_DIR=${OUTPUT_DIR%/}
|
||||
if [ -d "${OUTPUT_DIR}" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# find commands we need to securely download cosmocc
|
||||
if ! UNZIP=$(command -v unzip 2>/dev/null); then
|
||||
printf '%s\n' "$0: fatal error: you need the unzip command" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/unzip and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
if ! SHA256SUM=$(command -v sha256sum 2>/dev/null); then
|
||||
if [ ! -f build/sha256sum.c ]; then
|
||||
printf '%s\n' "$0: fatal error: you need to install sha256sum" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
if ! SHA256SUM=$(command -v "$PWD/o/build/sha256sum" 2>/dev/null); then
|
||||
if ! CC=$(command -v "$CC" 2>/dev/null); then
|
||||
if ! CC=$(command -v cc 2>/dev/null); then
|
||||
if ! CC=$(command -v cosmocc 2>/dev/null); then
|
||||
printf '%s\n' "$0: fatal error: you need to install either sha256sum, cc, or cosmocc" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
mkdir -p o/build || abort
|
||||
SHA256SUM="$PWD/o/build/sha256sum"
|
||||
printf '%s\n' "${CC} -w -O2 -o ${SHA256SUM} build/sha256sum.c" >&2
|
||||
"${CC}" -w -O2 -o "${SHA256SUM}.$$" build/sha256sum.c || abort
|
||||
mv -f "${SHA256SUM}.$$" "${SHA256SUM}" || abort
|
||||
fi
|
||||
fi
|
||||
if WGET=$(command -v wget 2>/dev/null); then
|
||||
DOWNLOAD=$WGET
|
||||
DOWNLOAD_ARGS=-O
|
||||
elif CURL=$(command -v curl 2>/dev/null); then
|
||||
DOWNLOAD=$CURL
|
||||
DOWNLOAD_ARGS=-fLo
|
||||
else
|
||||
printf '%s\n' "$0: fatal error: you need to install either wget or curl" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/wget and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
|
||||
# create temporary output directory
|
||||
OLDPWD=$PWD
|
||||
OUTPUT_TMP="${OUTPUT_DIR}.tmp.$$/"
|
||||
mkdir -p "${OUTPUT_TMP}" || abort
|
||||
cd "${OUTPUT_TMP}"
|
||||
die() {
|
||||
cd "${OLDPWD}"
|
||||
rm -rf "${OUTPUT_TMP}"
|
||||
abort
|
||||
}
|
||||
|
||||
# download cosmocc toolchain
|
||||
# multiple urls avoids outages and national firewalls
|
||||
if ! "${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL1}"; then
|
||||
rm -f cosmocc.zip
|
||||
"${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL2}" || die
|
||||
fi
|
||||
printf '%s\n' "${COSMOCC_SHA256SUM} *cosmocc.zip" >cosmocc.zip.sha256sum
|
||||
"${SHA256SUM}" -c cosmocc.zip.sha256sum || die
|
||||
"${UNZIP}" cosmocc.zip || die
|
||||
rm -f cosmocc.zip cosmocc.zip.sha256sum
|
||||
|
||||
# commit output directory
|
||||
cd "${OLDPWD}" || die
|
||||
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
|
|
@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
|
|||
fi
|
||||
|
||||
find_objdump() {
|
||||
if [ -x o/third_party/gcc/bin/$1-linux-cosmo-objdump ]; then
|
||||
OBJDUMP=o/third_party/gcc/bin/$1-linux-cosmo-objdump
|
||||
elif [ -x o/third_party/gcc/bin/$1-linux-musl-objdump ]; then
|
||||
OBJDUMP=o/third_party/gcc/bin/$1-linux-musl-objdump
|
||||
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump" ]; then
|
||||
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump"
|
||||
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump" ]; then
|
||||
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump"
|
||||
if [ -x cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then
|
||||
OBJDUMP=cosmocc/3.2/bin/$1-linux-cosmo-objdump
|
||||
elif [ -x cosmocc/3.2/bin/$1-linux-musl-objdump ]; then
|
||||
OBJDUMP=cosmocc/3.2/bin/$1-linux-musl-objdump
|
||||
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then
|
||||
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump"
|
||||
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then
|
||||
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump"
|
||||
else
|
||||
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
|
||||
exit 1
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include "libc/str/str.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define ADDR2LINE "o/third_party/gcc/bin/x86_64-linux-musl-addr2line"
|
||||
#define ADDR2LINE "cosmocc/3.2/bin/x86_64-linux-musl-addr2line"
|
||||
#elif defined(__aarch64__)
|
||||
#define ADDR2LINE "o/third_party/gcc/bin/aarch64-linux-musl-addr2line"
|
||||
#define ADDR2LINE "cosmocc/3.2/bin/aarch64-linux-musl-addr2line"
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
|
|
17107
third_party/gcc/LICENSE.txt
vendored
17107
third_party/gcc/LICENSE.txt
vendored
File diff suppressed because it is too large
Load diff
27
third_party/gcc/README.cosmo
vendored
27
third_party/gcc/README.cosmo
vendored
|
@ -1,27 +0,0 @@
|
|||
DESCRIPTION
|
||||
|
||||
Cosmopolitan GCC
|
||||
Prebuilt x86_64-linux binaries
|
||||
An APE-friendly C/C++ compiler
|
||||
|
||||
LICENSE
|
||||
|
||||
GPLv3 and other licenses (see LICENSE.txt)
|
||||
|
||||
ORIGIN
|
||||
|
||||
@ahgamut's musl-cross-make fork
|
||||
https://github.com/ahgamut/musl-cross-make/
|
||||
e58abc1110b335a3341e8ad5821ad8e3880d9bb2
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
ahgamut's musl-cross-make fork includes a 2kLOC patch that modifies
|
||||
GCC so it'll compile C code like `switch(errno){case EINVAL: etc.}`
|
||||
see third_party/gcc/portcosmo.patch for GCC 11.2.0 for our changes
|
||||
|
||||
NOTES
|
||||
|
||||
These binaries were compiled by Justine Tunney. You have the freedom
|
||||
to obtain the original source source code, apply our patch, and enjoy
|
||||
all the freedoms promised to you by the GNU General Public License.
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-ar
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-as
|
BIN
third_party/gcc/aarch64-linux-musl/bin/ld.bfd.gz
vendored
BIN
third_party/gcc/aarch64-linux-musl/bin/ld.bfd.gz
vendored
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
ld.bfd
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-nm
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-objcopy
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-objdump
|
|
@ -1 +0,0 @@
|
|||
../../bin/aarch64-linux-musl-strip
|
BIN
third_party/gcc/bin/aarch64-linux-musl-addr2line.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-addr2line.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-ar.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-ar.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-as.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-as.gz
vendored
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
aarch64-linux-musl-g++
|
BIN
third_party/gcc/bin/aarch64-linux-musl-c++filt.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-c++filt.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-g++.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-g++.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-gcc-nm.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-gcc-nm.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-gcc.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-gcc.gz
vendored
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
../aarch64-linux-musl/bin/ld.bfd
|
|
@ -1 +0,0 @@
|
|||
../aarch64-linux-musl/bin/ld.bfd
|
BIN
third_party/gcc/bin/aarch64-linux-musl-nm.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-nm.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-objcopy.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-objcopy.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-objdump.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-objdump.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/aarch64-linux-musl-strip.gz
vendored
BIN
third_party/gcc/bin/aarch64-linux-musl-strip.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-addr2line.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-addr2line.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-ar.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-ar.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-as.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-as.gz
vendored
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
x86_64-linux-musl-g++
|
BIN
third_party/gcc/bin/x86_64-linux-musl-c++filt.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-c++filt.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-g++.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-g++.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-gcc-nm.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-gcc-nm.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-gcc.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-gcc.gz
vendored
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
../x86_64-linux-musl/bin/ld.bfd
|
1
third_party/gcc/bin/x86_64-linux-musl-ld.sym
vendored
1
third_party/gcc/bin/x86_64-linux-musl-ld.sym
vendored
|
@ -1 +0,0 @@
|
|||
../x86_64-linux-musl/bin/ld.bfd
|
BIN
third_party/gcc/bin/x86_64-linux-musl-nm.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-nm.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-objcopy.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-objcopy.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-objdump.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-objdump.gz
vendored
Binary file not shown.
BIN
third_party/gcc/bin/x86_64-linux-musl-strip.gz
vendored
BIN
third_party/gcc/bin/x86_64-linux-musl-strip.gz
vendored
Binary file not shown.
97
third_party/gcc/config.mak
vendored
97
third_party/gcc/config.mak
vendored
|
@ -1,97 +0,0 @@
|
|||
#
|
||||
# config.mak.dist - sample musl-cross-make configuration
|
||||
#
|
||||
# Copy to config.mak and edit as desired.
|
||||
#
|
||||
|
||||
# There is no default TARGET; you must select one here or on the make
|
||||
# command line. Some examples:
|
||||
|
||||
# TARGET = i486-linux-musl
|
||||
TARGET = aarch64-linux-musl
|
||||
# TARGET = arm-linux-musleabi
|
||||
# TARGET = arm-linux-musleabihf
|
||||
# TARGET = sh2eb-linux-muslfdpic
|
||||
# TARGET = powerpc64le-linux-musl
|
||||
# TARGET = aarch64-linux-musl
|
||||
|
||||
# By default, cross compilers are installed to ./output under the top-level
|
||||
# musl-cross-make directory and can later be moved wherever you want them.
|
||||
# To install directly to a specific location, set it here. Multiple targets
|
||||
# can safely be installed in the same location. Some examples:
|
||||
|
||||
OUTPUT = /opt/cross11portcosmo
|
||||
# OUTPUT = /usr/local
|
||||
|
||||
# By default, latest supported release versions of musl and the toolchain
|
||||
# components are used. You can override those here, but the version selected
|
||||
# must be supported (under hashes/ and patches/) to work. For musl, you
|
||||
# can use "git-refname" (e.g. git-master) instead of a release. Setting a
|
||||
# blank version for gmp, mpc, mpfr and isl will suppress download and
|
||||
# in-tree build of these libraries and instead depend on pre-installed
|
||||
# libraries when available (isl is optional and not set by default).
|
||||
# Setting a blank version for linux will suppress installation of kernel
|
||||
# headers, which are not needed unless compiling programs that use them.
|
||||
|
||||
BINUTILS_VER = 2.35.2
|
||||
GCC_VER = 11.2.0
|
||||
# MUSL_VER = git-master
|
||||
# GMP_VER =
|
||||
# MPC_VER =
|
||||
# MPFR_VER =
|
||||
# ISL_VER =
|
||||
# LINUX_VER =
|
||||
|
||||
# By default source archives are downloaded with wget. curl is also an option.
|
||||
|
||||
# DL_CMD = wget -c -O
|
||||
# DL_CMD = curl -C - -L -o
|
||||
|
||||
# Check sha-1 hashes of downloaded source archives. On gnu systems this is
|
||||
# usually done with sha1sum.
|
||||
|
||||
# SHA1_CMD = sha1sum -c
|
||||
# SHA1_CMD = sha1 -c
|
||||
# SHA1_CMD = shasum -a 1 -c
|
||||
|
||||
# Something like the following can be used to produce a static-linked
|
||||
# toolchain that's deployable to any system with matching arch, using
|
||||
# an existing musl-targeted cross compiler. This only works if the
|
||||
# system you build on can natively (or via binfmt_misc and qemu) run
|
||||
# binaries produced by the existing toolchain (in this example, i486).
|
||||
|
||||
# MUSL_CONFIG += --enable-debug
|
||||
# MUSL_CONFIG += CFLAGS="-Os -fno-omit-frame-pointer -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
|
||||
MUSL_CONFIG += CFLAGS="-Os"
|
||||
|
||||
COMMON_CONFIG += CC="/opt/cross/bin/x86_64-linux-musl-gcc -static --static"
|
||||
COMMON_CONFIG += CXX="/opt/cross/bin/x86_64-linux-musl-g++ -static --static"
|
||||
# COMMON_CONFIG += CC="gcc -static --static"
|
||||
# COMMON_CONFIG += CXX="g++ -static --static"
|
||||
|
||||
# Recommended options for smaller build for deploying binaries:
|
||||
|
||||
COMMON_CONFIG += CFLAGS="-Os -g0"
|
||||
COMMON_CONFIG += CXXFLAGS="-Os -g0"
|
||||
COMMON_CONFIG += LDFLAGS="-s"
|
||||
|
||||
# Options you can add for faster/simpler build at the expense of features:
|
||||
|
||||
COMMON_CONFIG += --disable-nls
|
||||
GCC_CONFIG += --disable-libquadmath --disable-decimal-float
|
||||
GCC_CONFIG += --disable-libitm
|
||||
GCC_CONFIG += --disable-fixed-point
|
||||
GCC_CONFIG += --disable-lto
|
||||
|
||||
# By default C and C++ are the only languages enabled, and these are
|
||||
# the only ones tested and known to be supported. You can uncomment the
|
||||
# following and add other languages if you want to try getting them to
|
||||
# work too.
|
||||
|
||||
GCC_CONFIG += --enable-languages=c,c++ #--enable-plugin
|
||||
|
||||
# You can keep the local build path out of your toolchain binaries and
|
||||
# target libraries with the following, but then gdb needs to be told
|
||||
# where to look for source files.
|
||||
|
||||
# COMMON_CONFIG += --with-debug-prefix-map=$(CURDIR)=
|
|
@ -1 +0,0 @@
|
|||
../../../../bin/aarch64-linux-musl-as
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
../../../../x86_64-linux-musl/bin/ld.bfd
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
../../../../bin/aarch64-linux-musl-ld.bfd
|
|
@ -1 +0,0 @@
|
|||
../../../../bin/aarch64-linux-musl-ld.bfd
|
|
@ -1 +0,0 @@
|
|||
../../../../bin/x86_64-linux-musl-as
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
1910
third_party/gcc/portcosmo.patch
vendored
1910
third_party/gcc/portcosmo.patch
vendored
File diff suppressed because it is too large
Load diff
37
third_party/gcc/upgrade-cosmo-gcc.sh
vendored
37
third_party/gcc/upgrade-cosmo-gcc.sh
vendored
|
@ -1,37 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
ARCH=${1:-x86_64}
|
||||
IMPORT=${2:-/opt/cross11portcosmo}
|
||||
PREFIX=third_party/gcc
|
||||
OLDVERSION=11.2.0
|
||||
NEWVERSION=11.2.0
|
||||
|
||||
rm -rf o/third_party/gcc
|
||||
if [ $OLDVERSION != $NEWVERSION ]; then
|
||||
mv $PREFIX/libexec/gcc/$ARCH-linux-musl/$OLDVERSION $PREFIX/libexec/gcc/$ARCH-linux-musl/$NEWVERSION
|
||||
mv $PREFIX/lib/gcc/$ARCH-linux-musl/$OLDVERSION $PREFIX/lib/gcc/$ARCH-linux-musl/$NEWVERSION
|
||||
sed -i -e "s/$OLDVERSION/$NEWVERSION/g" $(find $PREFIX -name \*.sym | grep $ARCH)
|
||||
fi
|
||||
|
||||
FILES="
|
||||
$ARCH-linux-musl/bin/ld.bfd
|
||||
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/collect2
|
||||
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1
|
||||
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1plus
|
||||
bin/$ARCH-linux-musl-as
|
||||
bin/$ARCH-linux-musl-ar
|
||||
bin/$ARCH-linux-musl-gcc
|
||||
bin/$ARCH-linux-musl-g++
|
||||
bin/$ARCH-linux-musl-nm
|
||||
bin/$ARCH-linux-musl-objcopy
|
||||
bin/$ARCH-linux-musl-c++filt
|
||||
bin/$ARCH-linux-musl-addr2line
|
||||
bin/$ARCH-linux-musl-objdump
|
||||
bin/$ARCH-linux-musl-gcc-nm
|
||||
bin/$ARCH-linux-musl-strip
|
||||
"
|
||||
|
||||
for f in $FILES; do
|
||||
cp -f $IMPORT/$f $PREFIX/$f || exit
|
||||
gzip -f9 $PREFIX/$f || exit
|
||||
done
|
1
third_party/gcc/x86_64-linux-musl/bin/ar.sym
vendored
1
third_party/gcc/x86_64-linux-musl/bin/ar.sym
vendored
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-ar
|
1
third_party/gcc/x86_64-linux-musl/bin/as.sym
vendored
1
third_party/gcc/x86_64-linux-musl/bin/as.sym
vendored
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-as
|
BIN
third_party/gcc/x86_64-linux-musl/bin/ld.bfd.gz
vendored
BIN
third_party/gcc/x86_64-linux-musl/bin/ld.bfd.gz
vendored
Binary file not shown.
1
third_party/gcc/x86_64-linux-musl/bin/ld.sym
vendored
1
third_party/gcc/x86_64-linux-musl/bin/ld.sym
vendored
|
@ -1 +0,0 @@
|
|||
ld.bfd
|
1
third_party/gcc/x86_64-linux-musl/bin/nm.sym
vendored
1
third_party/gcc/x86_64-linux-musl/bin/nm.sym
vendored
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-nm
|
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-objcopy
|
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-objdump
|
|
@ -1 +0,0 @@
|
|||
../../bin/x86_64-linux-musl-strip
|
|
@ -1,93 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
const char *prog;
|
||||
char tmpdir[PATH_MAX];
|
||||
char binpath[PATH_MAX];
|
||||
|
||||
bool IsDirectory(const char *path) {
|
||||
int e;
|
||||
bool res;
|
||||
struct stat st;
|
||||
e = errno;
|
||||
res = stat(path, &st) != -1 && S_ISDIR(st.st_mode);
|
||||
errno = e;
|
||||
return res;
|
||||
}
|
||||
|
||||
void Execute(char *argv[]) {
|
||||
int ws;
|
||||
if (!vfork()) {
|
||||
execv(argv[0], argv);
|
||||
_Exit(127);
|
||||
}
|
||||
wait(&ws);
|
||||
if (!WIFEXITED(ws) || WEXITSTATUS(ws)) {
|
||||
fputs(argv[0], stderr);
|
||||
fputs(": command failed\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int Visit(const char *fpath, const struct stat *sb, int tflag,
|
||||
struct FTW *ftwbuf) {
|
||||
if (tflag == FTW_F && endswith(fpath, ".gz")) {
|
||||
Execute((char *[]){"build/bootstrap/gzip.com", "-d", (char *)fpath, 0});
|
||||
strcpy(binpath, fpath);
|
||||
binpath[strlen(binpath) - 3] = 0;
|
||||
chmod(binpath, 0755);
|
||||
} else if (tflag == FTW_F && endswith(fpath, ".sym")) {
|
||||
strcpy(binpath, fpath);
|
||||
binpath[strlen(binpath) - 4] = 0;
|
||||
symlink(xslurp(fpath, 0), binpath);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!IsLinux()) return 0;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "unbundle";
|
||||
if (IsDirectory("o/third_party/gcc")) return 0;
|
||||
makedirs("o/third_party", 0755);
|
||||
FormatInt32(stpcpy(tmpdir, "o/third_party/gcc."), getpid());
|
||||
Execute(
|
||||
(char *[]){"build/bootstrap/cp.com", "-r", "third_party/gcc", tmpdir, 0});
|
||||
if (nftw(tmpdir, Visit, 20, 0) == -1) {
|
||||
fputs(prog, stderr);
|
||||
fputs(": nftw failed: ", stderr);
|
||||
fputs(_strerdoc(errno), stderr);
|
||||
fputs("\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
rename(tmpdir, "o/third_party/gcc");
|
||||
}
|
|
@ -20,9 +20,8 @@ Cosmopolitan comes with absolutely NO WARRANTY of any kind.
|
|||
For more information, see the Cosmopolitan LICENSE files.
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
This launches GNU GCC/Binutils subprocesses, which is free software; see
|
||||
Cosmopolitan's third_party/gcc/ for source code and copying conditions.
|
||||
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
cosmocc's LICENSE files for source code and copying conditions. There is
|
||||
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
EOF
|
||||
exit
|
||||
fi
|
||||
|
|
|
@ -18,9 +18,8 @@ Cosmopolitan comes with absolutely NO WARRANTY of any kind.
|
|||
For more information, see the Cosmopolitan LICENSE files.
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
This launches GNU GCC/Binutils subprocesses, which is free software; see
|
||||
Cosmopolitan's third_party/gcc/ for source code and copying conditions.
|
||||
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
cosmocc's LICENSE files for source code and copying conditions. There is
|
||||
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
EOF
|
||||
exit
|
||||
fi
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
#!/bin/sh
|
||||
# tool/cosmocc/fetch.sh
|
||||
# sets up mono repo to use latest cosmocc toolchain
|
||||
|
||||
URL=https://cosmo.zip/pub/cosmocc/cosmocc.zip
|
||||
|
||||
echo creating o/third_party/gcc... >&2
|
||||
rm -rf o/third_party/gcc || exit
|
||||
mkdir -p o/third_party/gcc || exit
|
||||
cd o/third_party/gcc
|
||||
|
||||
echo downloading $URL... >&2
|
||||
if command -v wget >/dev/null; then
|
||||
wget $URL || exit
|
||||
else
|
||||
curl -Lo cosmocc.zip $URL || exit
|
||||
fi
|
||||
|
||||
echo extracting cosmocc.zip... >&2
|
||||
unzip cosmocc.zip || exit
|
||||
rm -f cosmocc.zip
|
||||
|
||||
# report success and give tips
|
||||
cat <<'EOF' >&2
|
||||
|
||||
SUCCESS
|
||||
|
||||
the cosmo mono repo will now build using cosmocc
|
||||
|
||||
WARNING
|
||||
|
||||
if you run `make clean` then you'll have to download it again
|
||||
|
||||
CONSIDER
|
||||
|
||||
you can install the cosmocc toolchain you just downloaded as follows
|
||||
|
||||
sudo chmod 01777 /opt
|
||||
rm -rf /opt/cosmocc
|
||||
mv o/third_party/gcc /opt/cosmocc
|
||||
ln -sf /opt/cosmocc o/third_party/gcc
|
||||
echo 'export PATH="/opt/cosmocc/bin:$PATH"' >>~/.profile
|
||||
|
||||
then just recreate the symlink after cleaning. please note that you
|
||||
should NEVER need to use make clean with the cosmo mono repo, since
|
||||
our Makefile is flawless. if make clean actually helps, file a bug.
|
||||
|
||||
EOF
|
||||
|
||||
# give tip to linux users
|
||||
if [ x"$(uname -s)" = x"Linux" ]; then
|
||||
cat <<'EOF' >&2
|
||||
PROTIP
|
||||
|
||||
running these commands
|
||||
|
||||
rm -rf o
|
||||
sudo mount -t tmpfs -o size=10G,noatime,nodiratime /dev/shm o
|
||||
ln -sf /opt/cosmocc o/third_party/gcc
|
||||
|
||||
makes the mono repo build faster
|
||||
|
||||
EOF
|
||||
fi
|
|
@ -2,7 +2,7 @@
|
|||
# cosmopolitan toolchain packager
|
||||
#
|
||||
# tool/cosmocc/package.sh
|
||||
# cd cosmocc
|
||||
# cd cosmocc/latest
|
||||
# zip -ry9 ../cosmocc.zip .
|
||||
#
|
||||
|
||||
|
@ -15,7 +15,7 @@ mode() {
|
|||
esac
|
||||
}
|
||||
|
||||
OUTDIR=${1:-cosmocc}
|
||||
OUTDIR=${1:-cosmocc/latest}
|
||||
APELINK=o/$(mode)/tool/build/apelink.com
|
||||
AMD64=${2:-x86_64}
|
||||
ARM64=${3:-aarch64}
|
||||
|
|
Loading…
Reference in a new issue