diff --git a/build-tool-osx.sh b/build-tool-osx.sh new file mode 100755 index 000000000..2a2ac9248 --- /dev/null +++ b/build-tool-osx.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# +# This script installs the required build-time dependencies +# and builds AppImageTool on OSX +# + +small_FLAGS="-Os -ffunction-sections -fdata-sections" +small_LDFLAGS="-s -Wl,--gc-sections" +CC="cc -O2 -Wall -Wno-deprecated-declarations -Wno-unused-result" + +STRIP="strip" +JOBS=${JOBS:-1} + +echo $KEY | md5sum + +set -e +set -x + +HERE="$(dirname "$(readlink -f "${0}")")" +cd "$HERE" + +# Fetch git submodules +git submodule init +git submodule update + +# Clean up from previous run +rm -rf build/ || true + +# Build lzma always static because the runtime gets distributed with +# the generated .AppImage file. +if [ ! -e "./xz-5.2.3/build/lib/liblzma.a" ] ; then + wget -c http://tukaani.org/xz/xz-5.2.3.tar.gz + tar xf xz-5.2.3.tar.gz + cd xz-5.2.3 + mkdir -p build/lib + CFLAGS="-Wall $small_FLAGS" ./configure --prefix=$(pwd)/build --libdir=$(pwd)/build/lib --enable-static --disable-shared + make -j$JOBS && make install + cd - +fi + +# Patch squashfuse_ll to be a library rather than an executable + +cd squashfuse +if [ ! -e ./ll.c.orig ]; then + patch -p1 --backup < ../squashfuse.patch + patch -p1 --backup < ../squashfuse_dlopen.patch +fi +if [ ! -e ./squashfuse_dlopen.c ]; then + cp ../squashfuse_dlopen.c . +fi +if [ ! -e ./squashfuse_dlopen.h ]; then + cp ../squashfuse_dlopen.h . +fi + +# Build libsquashfuse_ll library + +if [ ! -e ./Makefile ] ; then + export ACLOCAL_FLAGS="-I /usr/share/aclocal" + glibtoolize --force + aclocal + autoheader + automake --force-missing --add-missing + autoreconf -fi || true # Errors out, but the following succeeds then? + autoconf + sed -i "" '/PKG_CHECK_MODULES.*/,/,:./d' configure # https://github.com/vasi/squashfuse/issues/12 + CFLAGS="-Wall $small_FLAGS" ./configure --disable-demo --disable-high-level --without-lzo --without-lz4 --with-xz=$(pwd)/../xz-5.2.3/build + + # Patch Makefile to use static lzma + sed -i "" "s|XZ_LIBS = -llzma -L$(pwd)/../xz-5.2.3/build/lib|XZ_LIBS = -Bstatic -llzma -L$(pwd)/../xz-5.2.3/build/lib|g" Makefile +fi + +bash --version + +make -j$JOBS + +cd .. + +# Build mksquashfs with -offset option to skip n bytes +# https://github.com/plougher/squashfs-tools/pull/13 +cd squashfs-tools +patch -p1 --backup < ../squashfs_osx.patch +cd squashfs-tools + +# Patch squashfuse-tools Makefile to link against static llzma +sed -i "" "s|CFLAGS += -DXZ_SUPPORT|CFLAGS += -DXZ_SUPPORT -I../../xz-5.2.3/build/include|g" Makefile +sed -i "" "s|LIBS += -llzma|LIBS += -Bstatic -llzma -L../../xz-5.2.3/build/lib|g" Makefile + +#make -j$JOBS XZ_SUPPORT=1 mksquashfs # LZ4_SUPPORT=1 did not build yet on CentOS 6 +#$STRIP mksquashfs + +cd ../../ + +pwd + +mkdir build +cd build + +cp ../squashfs-tools/squashfs-tools/mksquashfs . + + +# Compile appimagetool but do not link - glib version + +$CC -DVERSION_NUMBER=\"$(git describe --tags --always --abbrev=7)\" -D_FILE_OFFSET_BITS=64 -I../squashfuse/ \ + $(pkg-config --cflags glib-2.0) -g -Os ../getsection.c -c ../appimagetool.c + +# Now statically link against libsquashfuse - glib version + + # statically link against liblzma + $CC -o appimagetool appimagetool.o ../elf.c ../getsection.c -DENABLE_BINRELOC ../binreloc.c \ + ../squashfuse/.libs/libsquashfuse.a ../squashfuse/.libs/libfuseprivate.a \ + -L../xz-5.2.3/build/lib \ + -ldl -lpthread \ + $(pkg-config --cflags --libs glib-2.0) -lz -llzma + + diff --git a/squashfs_osx.patch b/squashfs_osx.patch new file mode 100644 index 000000000..e0654e2ba --- /dev/null +++ b/squashfs_osx.patch @@ -0,0 +1,425 @@ +diff --git a/squashfs-tools/action.c b/squashfs-tools/action.c +index 359daa7..8575fba 100644 +--- a/squashfs-tools/action.c ++++ b/squashfs-tools/action.c +@@ -39,6 +39,10 @@ + #include + #include + ++#ifndef FNM_EXTMATCH /* glibc extension */ ++ #define FNM_EXTMATCH 0 ++#endif ++ + #include "squashfs_fs.h" + #include "mksquashfs.h" + #include "action.h" +@@ -1953,9 +1957,12 @@ static char *get_start(char *s, int n) + + static int subpathname_fn(struct atom *atom, struct action_data *action_data) + { +- return fnmatch(atom->argv[0], get_start(strdupa(action_data->subpath), ++ char *path = strdup(action_data->subpath); ++ int is_match = fnmatch(atom->argv[0], get_start(path, + count_components(atom->argv[0])), + FNM_PATHNAME|FNM_PERIOD|FNM_EXTMATCH) == 0; ++ free(path); ++ return is_match; + } + + TEST_VAR_FN(filesize, ACTION_REG, action_data->buf->st_size) +diff --git a/squashfs-tools/info.c b/squashfs-tools/info.c +index 7968c77..c8e4c52 100644 +--- a/squashfs-tools/info.c ++++ b/squashfs-tools/info.c +@@ -134,31 +134,22 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; +- int sig, waiting = 0; ++ int sig, err, waiting = 0; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGHUP); ++ sigaddset(&sigmask, SIGALRM); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); ++ err = sigwait(&sigmask, &sig); + +- if(sig == -1) { ++ if(err == -1) { + switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ + case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ + continue; + default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " ++ BAD_ERROR("sigwaitfailed " + "because %s\n", strerror(errno)); + } + } +@@ -169,8 +160,12 @@ void *info_thrd(void *arg) + /* set one second interval period, if ^\ received + within then, dump queue and cache status */ + waiting = 1; +- } else ++ alarm(1); ++ } else if (sig == SIGQUIT) { + dump_state(); ++ } else if (sig == SIGALRM) { ++ waiting = 0; ++ } + } + } + +diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c +index 86f82bb..77e48b2 100644 +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -51,6 +51,10 @@ + #include + #include + ++#ifndef FNM_EXTMATCH /* glibc extension */ ++ #define FNM_EXTMATCH 0 ++#endif ++ + #ifndef linux + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN +@@ -824,13 +828,13 @@ char *subpathname(struct dir_ent *dir_ent) + } + + +-inline unsigned int get_inode_no(struct inode_info *inode) ++static inline unsigned int get_inode_no(struct inode_info *inode) + { + return inode->inode_number; + } + + +-inline unsigned int get_parent_no(struct dir_info *dir) ++static inline unsigned int get_parent_no(struct dir_info *dir) + { + return dir->depth ? get_inode_no(dir->dir_ent->inode) : inode_no; + } +@@ -2053,7 +2057,7 @@ struct file_info *duplicate(long long file_size, long long bytes, + } + + +-inline int is_fragment(struct inode_info *inode) ++static inline int is_fragment(struct inode_info *inode) + { + int file_size = inode->buf.st_size; + +@@ -3016,20 +3020,20 @@ struct inode_info *lookup_inode2(struct stat *buf, int pseudo, int id) + } + + +-inline struct inode_info *lookup_inode(struct stat *buf) ++static inline struct inode_info *lookup_inode(struct stat *buf) + { + return lookup_inode2(buf, 0, 0); + } + + +-inline void alloc_inode_no(struct inode_info *inode, unsigned int use_this) ++static inline void alloc_inode_no(struct inode_info *inode, unsigned int use_this) + { + if (inode->inode_number == 0) + inode->inode_number = use_this ? : inode_no ++; + } + + +-inline struct dir_ent *create_dir_entry(char *name, char *source_name, ++static inline struct dir_ent *create_dir_entry(char *name, char *source_name, + char *nonstandard_pathname, struct dir_info *dir) + { + struct dir_ent *dir_ent = malloc(sizeof(struct dir_ent)); +@@ -3046,7 +3050,7 @@ inline struct dir_ent *create_dir_entry(char *name, char *source_name, + } + + +-inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, ++static inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, + struct inode_info *inode_info) + { + struct dir_info *dir = dir_ent->our_dir; +@@ -3062,7 +3066,7 @@ inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, + } + + +-inline void add_dir_entry2(char *name, char *source_name, ++static inline void add_dir_entry2(char *name, char *source_name, + char *nonstandard_pathname, struct dir_info *sub_dir, + struct inode_info *inode_info, struct dir_info *dir) + { +@@ -3074,7 +3078,7 @@ inline void add_dir_entry2(char *name, char *source_name, + } + + +-inline void free_dir_entry(struct dir_ent *dir_ent) ++static inline void free_dir_entry(struct dir_ent *dir_ent) + { + if(dir_ent->name) + free(dir_ent->name); +@@ -3086,7 +3090,7 @@ inline void free_dir_entry(struct dir_ent *dir_ent) + } + + +-inline void add_excluded(struct dir_info *dir) ++static inline void add_excluded(struct dir_info *dir) + { + dir->excluded ++; + } +@@ -4090,6 +4094,7 @@ void initialise_threads(int readq, int fragq, int bwriteq, int fwriteq, + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGHUP); ++ sigaddset(&sigmask, SIGALRM); + if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1) + BAD_ERROR("Failed to set signal mask in intialise_threads\n"); + +@@ -4864,12 +4869,43 @@ int parse_num(char *arg, int *res) + + int get_physical_memory() + { ++ int phys_mem; ++#ifndef linux ++ #ifdef HW_MEMSIZE ++ #define SYSCTL_PHYSMEM HW_MEMSIZE ++ #elif defined(HW_PHYSMEM64) ++ #define SYSCTL_PHYSMEM HW_PHYSMEM64 ++ #else ++ #define SYSCTL_PHYSMEM HW_PHYSMEM ++ #endif ++ ++ int mib[2]; ++ uint64_t sysctl_physmem = 0; ++ size_t sysctl_len = sizeof(sysctl_physmem); ++ ++ mib[0] = CTL_HW; ++ mib[1] = SYSCTL_PHYSMEM; ++ ++ if(sysctl(mib, 2, &sysctl_physmem, &sysctl_len, NULL, 0) == 0) { ++ /* some systems use 32-bit values, work with what we're given */ ++ if (sysctl_len == 4) ++ sysctl_physmem = *(uint32_t*)&sysctl_physmem; ++ phys_mem = sysctl_physmem >> 20; ++ } else { ++ ERROR_START("Failed to get amount of available " ++ "memory."); ++ ERROR_EXIT(" Defaulting to least viable amount\n"); ++ phys_mem = SQUASHFS_LOWMEM; ++ } ++ #undef SYSCTL_PHYSMEM ++#else + /* Long longs are used here because with PAE, a 32-bit + machine can have more than 4GB of physical memory */ + + long long num_pages = sysconf(_SC_PHYS_PAGES); + long long page_size = sysconf(_SC_PAGESIZE); +- int phys_mem = num_pages * page_size >> 20; ++ phys_mem = num_pages * page_size >> 20; ++#endif + + if(phys_mem < SQUASHFS_LOWMEM) + BAD_ERROR("Mksquashfs requires more physical memory than is " +diff --git a/squashfs-tools/mksquashfs.h b/squashfs-tools/mksquashfs.h +index 397e17c..8b8a510 100644 +--- a/squashfs-tools/mksquashfs.h ++++ b/squashfs-tools/mksquashfs.h +@@ -24,6 +24,7 @@ + * mksquashfs.h + * + */ ++#include + + struct dir_info { + char *pathname; +diff --git a/squashfs-tools/pseudo.c b/squashfs-tools/pseudo.c +index f85fe60..ab4106b 100644 +--- a/squashfs-tools/pseudo.c ++++ b/squashfs-tools/pseudo.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/squashfs-tools/read_xattrs.c b/squashfs-tools/read_xattrs.c +index 42106f5..837d3fb 100644 +--- a/squashfs-tools/read_xattrs.c ++++ b/squashfs-tools/read_xattrs.c +@@ -39,13 +39,13 @@ + #include + #endif + ++#include ++ + #include "squashfs_fs.h" + #include "squashfs_swap.h" + #include "xattr.h" + #include "error.h" + +-#include +- + extern int read_fs_bytes(int, long long, int, void *); + extern int read_block(int, long long, long long *, int, void *); + +diff --git a/squashfs-tools/unsquashfs.c b/squashfs-tools/unsquashfs.c +index 1323dd6..7f46968 100644 +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -31,7 +31,12 @@ + #include "unsquashfs_info.h" + #include "stdarg.h" + ++#ifndef linux ++#include ++#else + #include ++#endif ++ + #include + #include + #include +@@ -2174,6 +2179,7 @@ void initialise_threads(int fragment_buffer_size, int data_buffer_size) + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGHUP); ++ sigaddset(&sigmask, SIGALRM); + if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1) + EXIT_UNSQUASH("Failed to set signal mask in initialise_threads" + "\n"); +diff --git a/squashfs-tools/unsquashfs.h b/squashfs-tools/unsquashfs.h +index ecd0bb4..4836b8d 100644 +--- a/squashfs-tools/unsquashfs.h ++++ b/squashfs-tools/unsquashfs.h +@@ -47,6 +47,10 @@ + #include + #include + ++#ifndef FNM_EXTMATCH /* glibc extension */ ++ #define FNM_EXTMATCH 0 ++#endif ++ + #ifndef linux + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN +diff --git a/squashfs-tools/unsquashfs_info.c b/squashfs-tools/unsquashfs_info.c +index c8e2b9b..7d4f7af 100644 +--- a/squashfs-tools/unsquashfs_info.c ++++ b/squashfs-tools/unsquashfs_info.c +@@ -97,31 +97,22 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; +- int sig, waiting = 0; ++ int sig, err, waiting = 0; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGHUP); ++ sigaddset(&sigmask, SIGALRM); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); ++ err = sigwait(&sigmask, &sig); + +- if(sig == -1) { ++ if(err == -1) { + switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ + case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ + continue; + default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " ++ BAD_ERROR("sigwait failed " + "because %s\n", strerror(errno)); + } + } +@@ -133,8 +124,12 @@ void *info_thrd(void *arg) + /* set one second interval period, if ^\ received + within then, dump queue and cache status */ + waiting = 1; +- } else ++ alarm(1); ++ } else if (sig == SIGQUIT) { + dump_state(); ++ } else if (sig == SIGALRM) { ++ waiting = 0; ++ } + } + } + +diff --git a/squashfs-tools/unsquashfs_xattr.c b/squashfs-tools/unsquashfs_xattr.c +index 59f4aae..13f0e35 100644 +--- a/squashfs-tools/unsquashfs_xattr.c ++++ b/squashfs-tools/unsquashfs_xattr.c +@@ -27,6 +27,11 @@ + + #include + ++#ifdef XATTR_NOFOLLOW /* Apple's xattrs */ ++ #define lsetxattr(path_, name_, val_, sz_, flags_) \ ++ setxattr(path_, name_, val_, sz_, 0, flags_ | XATTR_NOFOLLOW) ++#endif ++ + #define NOSPACE_MAX 10 + + extern int root_process; +diff --git a/squashfs-tools/xattr.c b/squashfs-tools/xattr.c +index b46550c..5b32eca 100644 +--- a/squashfs-tools/xattr.c ++++ b/squashfs-tools/xattr.c +@@ -22,6 +22,14 @@ + * xattr.c + */ + ++#ifndef linux ++#define __BYTE_ORDER BYTE_ORDER ++#define __BIG_ENDIAN BIG_ENDIAN ++#define __LITTLE_ENDIAN LITTLE_ENDIAN ++#else ++#include ++#endif ++ + #define TRUE 1 + #define FALSE 0 + +@@ -36,6 +44,13 @@ + #include + #include + ++#ifdef XATTR_NOFOLLOW /* Apple's xattrs */ ++ #define llistxattr(path_, buf_, sz_) \ ++ listxattr(path_, buf_, sz_, XATTR_NOFOLLOW) ++ #define lgetxattr(path_, name_, val_, sz_) \ ++ getxattr(path_, name_, val_, sz_, 0, XATTR_NOFOLLOW) ++#endif ++ + #include "squashfs_fs.h" + #include "squashfs_swap.h" + #include "mksquashfs.h"