From cb51de2192df6f1e67b399b27960113903d08b4f Mon Sep 17 00:00:00 2001 From: Arvid Norlander Date: Fri, 21 Nov 2008 15:21:10 -0500 Subject: [PATCH] If we use GCC when compiling IFFI, use -fwhole-program -combine to hide symbols that could conflict, also use __attribute__((externally_visible)) to expose the symbols we need. --- etc/IFFI/IFFI.c | 2 +- etc/IFFI/IFFI.h | 21 ++++++++++++++++----- etc/cftoec.sh | 47 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/etc/IFFI/IFFI.c b/etc/IFFI/IFFI.c index 86c8fe1..221fd17 100644 --- a/etc/IFFI/IFFI.c +++ b/etc/IFFI/IFFI.c @@ -121,7 +121,7 @@ static void finger_IFFI_create(instructionPointer * ip) // arguments: line number on TOS, signature as 0gnirts beneath it fungeCell l = stack_pop(ip->stack); unsigned char * restrict str = stack_pop_string(ip->stack); - ick_create((char*)str, l); + ick_create((const char*)str, l); } // C - In markmode COME FROM the top of stack diff --git a/etc/IFFI/IFFI.h b/etc/IFFI/IFFI.h index ffd7a9d..1c70e23 100644 --- a/etc/IFFI/IFFI.h +++ b/etc/IFFI/IFFI.h @@ -34,6 +34,17 @@ #error The C-INTERCAL/cfunge external calls interface cannot be used concurrently #endif +// We need at least GCC 4.1 for this trick. +#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) +# if (__GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# define PUBLIC __attribute__((visibility("protected"),externally_visible)) extern +# else +# define PUBLIC extern +# endif +#else +# define PUBLIC extern +#endif + struct ick_ipposdeltatype { long long ix, iy, dx, dy; }; @@ -45,10 +56,10 @@ bool finger_IFFI_load(instructionPointer * ip); // We export these for use by ecto_b98 // Please remember to update the matching extern(s) over there // if you change here. -void ick_save_ip_pos_delta(struct ick_ipposdeltatype* ippd); -void ick_restore_ip_pos_delta(const struct ick_ipposdeltatype* ippd); -void ick_interpreter_run(void); -void ick_iffi_interpreter_one_iteration(void); +PUBLIC void ick_save_ip_pos_delta(struct ick_ipposdeltatype* ippd); +PUBLIC void ick_restore_ip_pos_delta(const struct ick_ipposdeltatype* ippd); +PUBLIC void ick_interpreter_run(void); +PUBLIC void ick_iffi_interpreter_one_iteration(void); // Implemented in ecto_b98 extern void ick_interpreter_main_loop(void); @@ -71,7 +82,7 @@ extern const unsigned char * ick_iffi_befungeString; extern int ick_printflow; // Accessors and mutators for INTERCAL storage -extern void ick_create(char*, unsigned long); +extern void ick_create(const char*, unsigned long); extern uint16_t ick_getonespot(unsigned short); extern void ick_setonespot(unsigned short, uint16_t); extern uint32_t ick_gettwospot(unsigned short); diff --git a/etc/cftoec.sh b/etc/cftoec.sh index 672004c..d13e545 100644 --- a/etc/cftoec.sh +++ b/etc/cftoec.sh @@ -8,8 +8,8 @@ die() { echo "Error: $1"; exit 1; } if [ -z "$1" ] || [ -z "$2" ]; then - echo "Usage: $0 ick-source-path cfunge-path" - exit 1 + echo "Usage: $0 ick-source-path cfunge-path" + exit 1 fi # test x$1 != x || ( @@ -58,13 +58,38 @@ rm -rf temp || die "Failed to remove any old temp directory" mkdir -p temp || die "Failed to create temp directory" cd temp || die "Failed to change directory to temp directory" +# Select compiler +if [ -z "$CC" ]; then + CC=cc +fi + CFLAGS="-std=c99 -DUSE32 -DDISABLE_GC -DFUNGE_EXTERNAL_LIBRARY -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED -DFUNGE_OLD_HANDPRINT=0x43464649 '-DFUNGE_NEW_HANDPRINT=\"http://example.com/\"'" +# If GCC 4.1 or later is used add: +# -O1 -combine -fwhole-program -fvisibility=hidden. +# At least -O1 needed or -fwhole-program have no effect. Which is needed for +# this trick. +if "$CC" --version 2>&1 | grep -q GCC; then + GCC_VERSION="$("$CC" --version 2>&1 | awk '/[^ ]+ \(GCC\)/ {print $3}')" + GCC_MAJOR="$(echo "$GCC_VERSION" | cut -d. -f 1)" + GCC_MINOR="$(echo "$GCC_VERSION" | cut -d. -f 2)" + # We need GCC 4.1 or later. + if [ "$GCC_MAJOR" -eq 4 ]; then + if [ "$GCC_MINOR" -ge 1 ]; then + IS_GCC=yes + fi + elif [ "$GCC_MAJOR" -gt 4 ]; then + IS_GCC=yes + fi +fi +if [ "$IS_GCC" ]; then + CFLAGS="$CFLAGS -O1 -combine -fwhole-program -fvisibility=hidden" +fi # Allow optional -O2 or such: if [ "$CFUNGE_CFLAGS" ]; then - CFLAGS="$CFLAGS $CFUNGE_CFLAGS" + CFLAGS="$CFLAGS $CFUNGE_CFLAGS" fi # Please enable this when making changes. Requested by the cfunge author. -#CFLAGS="$CFLAGS -Wall -Wextra -pedantic -Wpointer-arith -Wimplicit -Wnested-externs -Wcast-align -Wcast-qual -Wbad-function-cast -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wparentheses -Wshadow -Wundef -Wpacked -Wredundant-decls -Wfloat-equal -Wstrict-aliasing=2 -Wformat=2 -Wdisabled-optimization -Wmissing-noreturn -Wmissing-format-attribute -Wdeclaration-after-statement -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wwrite-strings" +#CFLAGS="$CFLAGS -Wall -Wextra -pedantic -Wpointer-arith -Wimplicit -Wnested-externs -Wcast-align -Wcast-qual -Wbad-function-cast -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wparentheses -Wshadow -Wundef -Wpacked -Wfloat-equal -Wstrict-aliasing=2 -Wformat=2 -Wdisabled-optimization -Wmissing-noreturn -Wmissing-format-attribute -Wdeclaration-after-statement -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wwrite-strings" echo " " Duplicating cfunge source tree so that it can be modified... cp -r $CFUNGE_PATH/src $CFUNGE_PATH/lib . @@ -85,7 +110,19 @@ $CFUNGE_PATH/tools/gen_fprint_list.sh > /dev/null || die "Failed to regen list." # I really can't be bothered to save them from themself. Dump all the resulting # object files in this temp directory. echo " " Compiling source... -find . -name '*.c' -printf "gcc $CFLAGS -c %p -o %f.o\n" | sh +if [ "$IS_GCC" ]; then + FILES="$(find . -name '*.c' -printf "%p ")" + # Pipe needed due to messy double quoting. + # It is impossible to use -o -c and multiple files all at once. GCC errors + # if you try. However the *.o will be equal to one of the source filenames + # but placed in the current directory and with .c replaced with .o + echo "$CC $CFLAGS -c $FILES" | sh +else + find . -name '*.c' -printf "$CC $CFLAGS -c %p -o %f.o\n" | sh +fi + +# Remove any existing library or ar would just add to the existing one. +rm -f ../libick_ecto_b98.a echo " " Creating library... ar cr ../libick_ecto_b98.a *.o -- 2.43.0