tcc android-enabled (armeabi-v7a)

On an armeabi-v7a device (phone) in the termux app with
clang & make installed this passes all the tests.

Can be used as a cross compiler to create "native apps" as well.
Example 'config-extra.mak' for the cross arm-eabi-tcc:

  SYSROOT = <path_to_android_ndk...>/sysroot/usr
  TRIPLET = arm-linux-androideabi
  ANDRVER = 32

  ROOT-arm-eabi = $(SYSROOT)

  CRT-arm-eabi = {R}/lib/$(TRIPLET)/$(ANDRVER)
  LIB-arm-eabi = {B};{R}/lib/$(TRIPLET)/$(ANDRVER);{R}/lib/$(TRIPLET)
  INC-arm-eabi = {B}/lib/include;{R}/include/$(TRIPLET);{R}/include

  DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
  DEF-arm-eabi += -DTARGETOS_ANDROID -DCONFIG_TCC_PIE -DCONFIG_NEW_DTAGS
  DEF-arm-eabi += -DCONFIG_TCC_ELFINTERP=\"/system/bin/linker\"

  # on unix replace ';' by ':'.
  $ ./configure && make cross-arm-eabi && make install
This commit is contained in:
grischka 2022-05-17 22:28:32 +02:00
parent 8e860702e4
commit 09808f327f
14 changed files with 109 additions and 49 deletions

View file

@ -90,8 +90,10 @@ NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64
NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS)
NATIVE_DEFINES_$(CONFIG_Android) += -DTARGETOS_ANDROID
NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE
NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC
NATIVE_DEFINES_$(CONFIG_new-dtags) += -DCONFIG_NEW_DTAGS
NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0
NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0
NATIVE_DEFINES += $(NATIVE_DEFINES_yes) $(NATIVE_DEFINES_no_no)

41
configure vendored
View file

@ -27,8 +27,7 @@ mandir=""
infodir=""
sysroot=""
cross_prefix=""
test -z "$CC" && CC="gcc"
test -z "$cc" && cc="$CC"
cc="gcc"
ar="ar"
bigendian="no"
mingw32="no"
@ -46,16 +45,20 @@ confvars=
suggest="yes"
gcc_major=0
gcc_minor=0
cc_name="$cc"
cc_name="gcc"
ar_set=
darwin=
cpu=
cpuver=
dwarf=
# use CC from environment when set
test -n "$CC" && cc="$CC"
# OS specific
cpu_sys=`uname -m`
cpu=`uname -m`
cpu_sys="$cpu"
targetos=`uname`
test "$(uname -o)" = "Android" && targetos=Android
case $targetos in
Darwin)
@ -73,6 +76,20 @@ case $targetos in
DragonFly|OpenBSD|FreeBSD|NetBSD)
confvars="$confvars BSD ldl=no"
;;
Android)
confvars="$confvars Android pie new-dtags"
if test -n "$TERMUX_VERSION"; then
prefix="$PREFIX" # "/data/data/com.termux/files/usr"
sysroot="$PREFIX"
test "$cpu" = "aarch64" -o "$cpu" = "x86_64" && S="64" || S=""
tcc_sysincludepaths="{B}/include:{R}/include/\\\"CONFIG_TRIPLET\\\":{R}/include"
tcc_libpaths="{B}:{R}/lib:/system/lib${S}"
tcc_crtprefix="{R}/lib"
tcc_elfinterp="/system/bin/linker${S}"
use_triplet="yes"
tcc_switches="-Wl,-rpath=$sysroot/lib,-section-alignment=0x1000"
fi
;;
*)
;;
esac
@ -153,6 +170,8 @@ for opt do
;;
--with-selinux) confvars="$confvars selinux"
;;
--tcc-switches=*) tcc_switches=`echo $opt | cut -d '=' -f 2-`
;;
--config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
;;
--config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
@ -176,9 +195,6 @@ if test "$darwin" = "yes" -a "$cpu" = "x86_64" -a "$cpu_sys" = "arm64"; then
LDFLAGS="$LDFLAGS -arch $cpu"
fi
# checking for cpu
test -z "$cpu" && cpu="$cpu_sys"
case "$cpu" in
x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
cpu="i386"
@ -325,6 +341,7 @@ Advanced options (experts only):
--crtprefix=... specify locations of crt?.o, colon separated
--elfinterp=... specify elf interpreter
--triplet=... specify system library/include directory triplet
--tcc-switches=... specify implicit switches passed to tcc
--config-uClibc,-musl enable system specific configurations
--config-mingw32 build on windows using msys, busybox, etc.
@ -349,8 +366,8 @@ if test -z "$cross_prefix" ; then
fi
if test "$mingw32" = "no" ; then
if test -z "$triplet"; then
if test -n "$_triplet" -a -f "/usr/lib/$_triplet/crti.o" ; then
if test -z "$triplet" -a -n "$_triplet"; then
if test -f "/usr/lib/$_triplet/crti.o" -o -n "$use_triplet" ; then
triplet="$_triplet"
fi
fi
@ -372,8 +389,7 @@ if test -z "$cross_prefix" ; then
confvars="$confvars arm_eabihf arm_vfp"
elif test "${_triplet%eabi}" != "$_triplet" ; then
confvars="$confvars arm_eabi arm_vfp"
fi
if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
elif grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
confvars="$confvars arm_vfp"
fi
fi
@ -496,6 +512,7 @@ print_mak CONFIG_TCC_SYSINCLUDEPATHS "$tcc_sysincludepaths"
print_mak CONFIG_TCC_LIBPATHS "$tcc_libpaths"
print_mak CONFIG_TCC_CRTPREFIX "$tcc_crtprefix"
print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp"
print_mak CONFIG_TCC_SWITCHES "$tcc_switches"
print_mak CONFIG_LDDIR "$tcc_lddir"
print_mak CONFIG_TRIPLET "$triplet"
print_mak TCC_CPU_VERSION "$cpuver" num

View file

@ -21,6 +21,8 @@ const char *platform_macros[] = {
"__OpenBSD__", "TARGETOS_OpenBSD",
"__NetBSD__", "TARGETOS_NetBSD",
"__linux__", "TARGETOS_Linux",
"__ANDROID__", "TARGETOS_ANDROID",
"__SIZEOF_POINTER__", "PTR_SIZE",
"__SIZEOF_LONG__", "LONG_SIZE",
0
@ -206,15 +208,21 @@ int main(int argc, char **argv)
# define TRIPLET_OS "unknown"
#endif
#if defined __ANDROID__
# define ABI_PREFIX "android"
#else
# define ABI_PREFIX "gnu"
#endif
/* Define calling convention and ABI */
#if defined (__ARM_EABI__)
# if defined (__ARM_PCS_VFP)
# define TRIPLET_ABI "gnueabihf"
# define TRIPLET_ABI ABI_PREFIX"eabihf"
# else
# define TRIPLET_ABI "gnueabi"
# define TRIPLET_ABI ABI_PREFIX"eabi"
# endif
#else
# define TRIPLET_ABI "gnu"
# define TRIPLET_ABI ABI_PREFIX
#endif
#if defined _WIN32

View file

@ -125,6 +125,13 @@
#define __FINITE_MATH_ONLY__ 1
#define _FORTIFY_SOURCE 0
#elif defined __ANDROID__
#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD
#define __PRETTY_FUNCTION__ __FUNCTION__
#define __has_builtin(x) 0
#define _Nonnull
#define _Nullable
#else
/* Linux */

View file

@ -161,7 +161,7 @@ static pthread_spinlock_t bounds_spin;
#define HAVE_TLS_FUNC (1)
#define HAVE_TLS_VAR (0)
#endif
#ifdef TCC_MUSL
#if defined TCC_MUSL || defined __ANDROID__
# undef HAVE_CTYPE
#endif
#endif
@ -1174,7 +1174,8 @@ void __attribute__((destructor)) __bound_exit(void)
if (inited) {
#if !defined(_WIN32) && !defined(__APPLE__) && !defined TCC_MUSL && \
!defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
!defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
!defined(__ANDROID__)
if (print_heap) {
extern void __libc_freeres (void);
__libc_freeres ();

View file

@ -496,6 +496,8 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
c = p[1], p += 2;
if (c == 'B')
cstr_cat(&str, s->tcc_lib_path, -1);
if (c == 'R')
cstr_cat(&str, CONFIG_SYSROOT, -1);
if (c == 'f' && file) {
/* substitute current file's dir */
const char *f = file->true_filename;
@ -810,7 +812,9 @@ LIBTCCAPI TCCState *tcc_new(void)
#ifdef TCC_TARGET_ARM
s->float_abi = ARM_FLOAT_ABI;
#endif
#ifdef CONFIG_NEW_DTAGS
s->enable_new_dtags = 1;
#endif
s->ppfp = stdout;
/* might be used in error() before preprocess_start() */
s->include_stack_ptr = s->include_stack;
@ -943,6 +947,11 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
tcc_add_crt(s, "crtbeginS.o");
else
tcc_add_crt(s, "crtbegin.o");
#elif defined TARGETOS_ANDROID
if (output_type != TCC_OUTPUT_DLL)
tcc_add_crt(s, "crtbegin_dynamic.o");
else
tcc_add_crt(s, "crtbegin_so.o");
#else
if (output_type != TCC_OUTPUT_DLL)
tcc_add_crt(s, "crt1.o");

3
tcc.c
View file

@ -281,6 +281,9 @@ int main(int argc0, char **argv0)
redo:
argc = argc0, argv = argv0;
s = s1 = tcc_new();
#ifdef CONFIG_TCC_SWITCHES
tcc_set_options(s, CONFIG_TCC_SWITCHES);
#endif
opt = tcc_parse_args(s, &argc, &argv, 1);
if (n == 0) {

View file

@ -857,7 +857,7 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
/* dlsym() needs the undecorated name. */
void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
if (addr == NULL) {
int i;
for (i = 0; i < s1->nb_loaded_dlls; i++)
@ -1526,6 +1526,11 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
# if !TARGETOS_OpenBSD
tcc_add_crt(s1, "crtn.o");
# endif
#elif TARGETOS_ANDROID
if (s1->output_type == TCC_OUTPUT_DLL)
tcc_add_crt(s1, "crtend_so.o");
else
tcc_add_crt(s1, "crtend_android.o");
#else
tcc_add_crt(s1, "crtn.o");
#endif
@ -2272,22 +2277,15 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
ehdr.e_ident[4] = ELFCLASSW;
ehdr.e_ident[5] = ELFDATA2LSB;
ehdr.e_ident[6] = EV_CURRENT;
#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
#endif
#ifdef TCC_TARGET_ARM
#ifdef TCC_ARM_EABI
ehdr.e_ident[EI_OSABI] = 0;
ehdr.e_flags = EF_ARM_EABI_VER4;
if (file_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL))
ehdr.e_flags |= EF_ARM_HASENTRY;
if (s1->float_abi == ARM_HARD_FLOAT)
ehdr.e_flags |= EF_ARM_VFP_FLOAT;
else
ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
#else
#elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
ehdr.e_flags = EF_ARM_EABI_VER5;
ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
#elif defined TCC_TARGET_ARM
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
#endif
#elif defined TCC_TARGET_RISCV64
ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
#endif

View file

@ -8266,7 +8266,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
sym = type.ref;
if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
decl0(VT_CMP, 0, sym);
#ifdef TCC_TARGET_MACHO
#if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID
if (sym->f.func_alwinl
&& ((type.t & (VT_EXTERN | VT_INLINE))
== (VT_EXTERN | VT_INLINE))) {

18
tccpp.c
View file

@ -3713,6 +3713,9 @@ static const char * const target_os_defs =
# else
"__linux__\0"
"__linux\0"
# if TARGETOS_ANDROID
"__ANDROID__\0"
# endif
# endif
"__unix__\0"
"__unix\0"
@ -3724,17 +3727,22 @@ static void putdef(CString *cs, const char *p)
cstr_printf(cs, "#define %s%s\n", p, &" 1"[!!strchr(p, ' ')*2]);
}
static void putdefs(CString *cs, const char *p)
{
while (*p)
putdef(cs, p), p = strchr(p, 0) + 1;
}
static void tcc_predefs(TCCState *s1, CString *cs, int is_asm)
{
int a, b, c;
const char *defs[] = { target_machine_defs, target_os_defs, NULL };
const char *p;
sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
cstr_printf(cs, "#define __TINYC__ %d\n", a*10000 + b*100 + c);
for (a = 0; defs[a]; ++a)
for (p = defs[a]; *p; p = strchr(p, 0) + 1)
putdef(cs, p);
putdefs(cs, target_machine_defs);
putdefs(cs, target_os_defs);
#ifdef TCC_TARGET_ARM
if (s1->float_abi == ARM_HARD_FLOAT)
putdef(cs, "__ARM_PCS_VFP");

View file

@ -390,7 +390,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
/* XXX: BSD sometimes dump core with bad system call */
# if (TCC_TARGET_ARM && !TARGETOS_BSD) || TCC_TARGET_ARM64
# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64
if (mode == 0 || mode == 3) {
void __clear_cache(void *beginning, void *end);
__clear_cache(ptr, (char *)ptr + length);

View file

@ -35,8 +35,8 @@ endif
ifeq (,$(filter arm64 i386 x86_64,$(ARCH)))
TESTS := $(filter-out vla_test-run,$(TESTS))
endif
ifeq ($(CONFIG_arm_eabi),yes)
TESTS := $(filter-out test3,$(TESTS))
ifeq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--)
TESTS := $(filter-out test3 test1b,$(TESTS))
endif
ifeq (,$(filter i386 x86_64,$(ARCH)))
TESTS := $(filter-out asm-c-connect-test,$(TESTS))
@ -250,7 +250,7 @@ abitest-% : abitest-%.exe
./$< $(TCCFLAGS)
abitest: abitest-cc
ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
ifneq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--)
abitest: abitest-tcc
endif
@ -261,6 +261,8 @@ vla_test-run: vla_test$(EXESUF)
@echo ------------ $@ ------------
./vla_test$(EXESUF)
.PHONY: abitest vla_test
asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
$(TCC) -o $@ $^

View file

@ -21,14 +21,19 @@
typedef __SIZE_TYPE__ uintptr_t;
#endif
#if defined(_WIN32) || \
(defined(__arm__) && \
(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)))
#if defined(_WIN32) \
|| (defined(__arm__) \
&& (defined(__FreeBSD__) \
|| defined(__OpenBSD__) \
|| defined(__NetBSD__) \
|| defined __ANDROID__))
#define LONG_LONG_FORMAT "%lld"
#define ULONG_LONG_FORMAT "%llu"
#define XLONG_LONG_FORMAT "%llx"
#else
#define LONG_LONG_FORMAT "%Ld"
#define ULONG_LONG_FORMAT "%Lu"
#define XLONG_LONG_FORMAT "%Lx"
#endif
// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
@ -2265,7 +2270,7 @@ double ftab1[3] = { 1.2, 3.4, -5.6 };
void float_test(void)
{
#if !defined(__arm__) || defined(__ARM_PCS_VFP)
#if !defined(__arm__) || defined(__ARM_PCS_VFP) || defined __ANDROID__
volatile float fa, fb;
volatile double da, db;
int a;
@ -2531,7 +2536,7 @@ void longlong_test(void)
b = 0x12345678;
a = -1;
c = a + b;
printf("%Lx\n", c);
printf(XLONG_LONG_FORMAT"\n", c);
#endif
/* long long reg spill test */

View file

@ -9,7 +9,7 @@ TESTS = $(patsubst %.c,%.test,\
# some tests do not pass on all platforms, remove them for now
SKIP = 34_array_assignment.test # array assignment is not in C standard
ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
ifeq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--)
SKIP += 22_floating_point.test
endif
ifdef CONFIG_OSX
@ -27,12 +27,12 @@ ifeq (,$(filter i386 x86_64,$(ARCH)))
SKIP += 125_atomic_misc.test # currently only x86 supported
endif
ifeq ($(CONFIG_backtrace),no)
SKIP += 112_backtrace.test
SKIP += 113_btdll.test
CONFIG_bcheck = no
# no bcheck without backtrace
endif
ifeq ($(CONFIG_bcheck),no)
SKIP += 112_backtrace.test
SKIP += 114_bound_signal.test
SKIP += 115_bound_setjmp.test
SKIP += 116_bound_setjmp2.test