diff options
43 files changed, 3004 insertions, 0 deletions
diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..bd47dfe --- /dev/null +++ b/Makefile.in @@ -0,0 +1,311 @@ +PACKAGE = @package@ +PROJECT_DIR = @project_dir@ + +BUILD = @build@ +HOST = @host@ +TARGET = @target@ +ARCH = @arch@ +COMPILER = @compiler@ +TOOLCHAIN = @toolchain@ +SYSROOT = @sysroot@ +CROSS_COMPILE = @cross_compile@ +SHELL = @shell@ + +CFLAGS_DEBUG = @cflags_debug@ +CFLAGS_COMMON = @cflags_common@ +CFLAGS_CMDLINE = @cflags_cmdline@ +CFLAGS_CONFIG = @cflags_config@ +CFLAGS_SYSROOT = @cflags_sysroot@ +CFLAGS_OS = @cflags_os@ +CFLAGS_SITE = @cflags_site@ +CFLAGS_PATH = @cflags_path@ + +LDFLAGS_DEBUG = @ldflags_debug@ +LDFLAGS_COMMON = @ldflags_common@ +LDFLAGS_CMDLINE = @ldflags_cmdline@ +LDFLAGS_CONFIG = @ldflags_config@ +LDFLAGS_SYSROOT = @ldflags_sysroot@ +LDFLAGS_PATH = @ldflags_path@ + +PE_SUBSYSTEM = @pe_subsystem@ +PE_IMAGE_BASE = @pe_image_base@ +PE_CONFIG_DEFS = @pe_config_defs@ + +ELF_EH_FRAME = @elf_eh_frame@ +ELF_HASH_STYLE = @elf_hash_style@ +ELF_CONFIG_DEFS = @elf_config_defs@ + +PREFIX = @prefix@ +BINDIR = @bindir@ +LIBDIR = @libdir@ +INCLUDEDIR = @includedir@ +SYSLIBDIR = @syslibdir@ +MANDIR = @mandir@ +DOCDIR = @docdir@ +LIBEXECDIR = @libexecdir@ + +NATIVE_CC = @native_cc@ +NATIVE_OS = @native_os@ +NATIVE_OS_BITS = @native_os_bits@ +NATIVE_OS_UNDERSCORE = @native_os_underscore@ + +USER_CC = @user_cc@ +USER_CPP = @user_cpp@ +USER_CXX = @user_cxx@ + + +all: +install: +shared: +static: + + + +include $(PROJECT_DIR)/sysinfo/host/$(HOST).mk +include $(PROJECT_DIR)/sysinfo/compiler/$(COMPILER).mk +include $(PROJECT_DIR)/sysinfo/toolchain/$(TOOLCHAIN).mk + +include $(PROJECT_DIR)/project/defs.mk +include $(PROJECT_DIR)/project/tree.mk +include $(PROJECT_DIR)/project/depends.mk +include $(PROJECT_DIR)/project/headers.mk +include $(PROJECT_DIR)/project/common.mk +include $(PROJECT_DIR)/project/arch.mk +include $(PROJECT_DIR)/project/extras.mk +include $(PROJECT_DIR)/project/overrides.mk + + + +$(APP_SRCS:%.c=%.o): version.tag +$(APP_SRCS:%.c=%.o): CFLAGS_STATIC = $(CFLAGS_APP) + +src/%.lo: $(PROJECT_DIR)/src/%.c $(ALL_HEADERS) host.tag tree.tag + $(CC) -c -o $@ $< $(CFLAGS_SHARED) + +src/%.o: $(PROJECT_DIR)/src/%.c $(ALL_HEADERS) host.tag tree.tag + $(CC) -c -o $@ $< $(CFLAGS_STATIC) + +$(LIBDIR)/%$(OS_LIB_SUFFIX): + $(CC) -shared -o $@ $^ $(LDFLAGS_SHARED) + +$(LIBDIR)/%$(OS_ARCHIVE_EXT): + rm -f $@ + $(AR) rcs $@ $^ + + + +all: shared static app + +install: install-libs install-headers install-app + +app: default-app + + +install-libs: install-shared install-static install-implib + +install-headers:shared static + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(INCLUDEDIR)/$(PACKAGE) + cp $(API_HEADERS) $(DESTDIR)///./$(PREFIX)/./$(INCLUDEDIR)/$(PACKAGE) + +install-shared: shared install-implib + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + cp $(SHARED_LIB) $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + +install-static: static + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + cp $(STATIC_LIB) $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + +install-app: app + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(BINDIR) + cp $(APP) $(DESTDIR)///./$(PREFIX)/./$(BINDIR) + + + +shared: shared-lib shared-implib + +static: static-lib + +shared-lib: shared-objs $(SHARED_LIB) + +static-lib: static-objs $(STATIC_LIB) + +shared-implib: shared-lib + + + +default-app: version.tag static $(DEFAULT_APP) $(APP) + +shared-app: version.tag shared $(SHARED_APP) + +static-app: version.tag static $(STATIC_APP) + + + +shared-objs: dirs $(SHARED_OBJS) + +static-objs: dirs $(STATIC_OBJS) + +app-objs: dirs $(APP_OBJS) + + + +$(SHARED_LIB): $(SHARED_OBJS) + +$(STATIC_LIB): $(STATIC_OBJS) + +$(APP): $(DEFAULT_APP) + cp $^ $@ + +$(DEFAULT_APP): $(STATIC_OBJS) $(APP_OBJS) + $(CC) -o $@ $^ $(LDFLAGS_APP) + +$(SHARED_APP): $(SHARED_LIB) $(APP_OBJS) + $(CC) -o $@ $(APP_OBJS) -l$(PACKAGE) $(LDFLAGS_SHARED) + +$(STATIC_APP): $(STATIC_OBJS) $(APP_OBJS) + $(CC) -static -o $@ $^ -l$(PACKAGE) $(LDFLAGS_STATIC) + + +dirs: dirs.tag tree.tag + +dirs.tag: + mkdir -p $(BINDIR) + mkdir -p $(LIBDIR) + touch dirs.tag + +host.tag: Makefile + $(PROJECT_DIR)/sysinfo/host/host.sh --compiler="$(CC)" --cflags="$(CFLAGS)" + touch host.tag + +version.tag: + $(PROJECT_DIR)/sysinfo/version.sh \ + -s $(PROJECT_DIR) \ + -o build/$(PACKAGE)_version.h \ + -p $(PACKAGE) + touch version.tag + +distclean: clean + rm -f Makefile + +clean: + rm -f tree.tag + rm -f dirs.tag + rm -f host.tag + rm -f version.tag + rm -f $(SHARED_OBJS) + rm -f $(STATIC_OBJS) + rm -f $(APP_OBJS) + rm -f $(SHARED_LIB) + rm -f $(STATIC_LIB) + rm -f $(SHARED_IMPLIB) + rm -f $(APP) + rm -f $(DEFAULT_APP) + rm -f $(SHARED_APP) + rm -f $(STATIC_APP) + + +.display: .display-project .display-env .display-tools .display-flags \ + .display-pe .display-elf .display-dirs .display-build + +.display-project: + @echo PROJECT_DIR:' '$(PROJECT_DIR) + @echo BUILD_DIR:' '$(CURDIR) + @echo + +.display-env: + @echo BUILD:' '$(BUILD) + @echo HOST:' '$(HOST) + @echo TARGET:' '$(TARGET) + @echo ARCH:' '$(ARCH) + @echo COMPILER:' '$(COMPILER) + @echo TOOLCHAIN:' '$(TOOLCHAIN) + @echo SYSROOT:' '$(SYSROOT) + @echo CROSS_COMPILE:' '$(CROSS_COMPILE) + @echo SHELL:' '$(SHELL) + @echo + +.display-tools: + @echo CC:' '$(CC) + @echo CPP:' '$(CPP) + @echo CXX:' '$(CXX) + @echo + @echo AS:' '$(AS) + @echo AR:' '$(AR) + @echo LD:' '$(LD) + @echo NM:' '$(NM) + @echo OBJDUMP:' '$(OBJDUMP) + @echo RANLIB:' '$(RANLIB) + @echo SIZE:' '$(SIZE) + @echo STRIP:' '$(STRIP) + @echo STRINGS:' '$(STRINGS) + @echo + @echo ADDR2LINE:' '$(ADDR2LINE) + @echo COV:' '$(COV) + @echo CXXFILT' '$(CXXFILT) + @echo ELFEDIT:' '$(ELFEDIT) + @echo OBJCOPY:' '$(OBJCOPY) + @echo READELF:' '$(READELF) + @echo + +.display-flags: + @echo CFLAGS_DEBUG:' '$(CFLAGS_DEBUG) + @echo CFLAGS_COMMON:' '$(CFLAGS_COMMON) + @echo CFLAGS_CMDLINE:' '$(CFLAGS_CMDLINE) + @echo CFLAGS_CONFIG:' '$(CFLAGS_CONFIG) + @echo CFLAGS_SYSROOT:' '$(CFLAGS_SYSROOT) + @echo CFLAGS_OS:' '$(CFLAGS_OS) + @echo CFLAGS_SITE:' '$(CFLAGS_SITE) + @echo CFLAGS_PATH:' '$(CFLAGS_PATH) + @echo + @echo LDFLAGS_DEBUG:' '$(LDFLAGS_DEBUG) + @echo LDFLAGS_COMMON:' '$(LDFLAGS_COMMON) + @echo LDFLAGS_CMDLINE:' '$(LDFLAGS_CMDLINE) + @echo LDFLAGS_CONFIG:' '$(LDFLAGS_CONFIG) + @echo LDFLAGS_SYSROOT:' '$(LDFLAGS_SYSROOT) + @echo LDFLAGS_PATH:' '$(LDFLAGS_PATH) + @echo + +.display-pe: + @echo PE_SUBSYSTEM:' '$(PE_SUBSYSTEM) + @echo PE_IMAGE_BASE:' '$(PE_IMAGE_BASE) + @echo PE_CONFIG_DEFS:' '$(PE_CONFIG_DEFS) + @echo + +.display-elf: + @echo ELF_EH_FRAME:' '$(ELF_EH_FRAME) + @echo ELF_HASH_STYLE:' '$(ELF_HASH_STYLE) + @echo ELF_CONFIG_DEFS:' '$(ELF_CONFIG_DEFS) + @echo + +.display-dirs: + @echo PREFIX:' '$(PREFIX) + @echo BINDIR:' '$(BINDIR) + @echo LIBDIR:' '$(LIBDIR) + @echo INCLUDEDIR:' '$(INCLUDEDIR) + @echo SYSLIBDIR:' '$(SYSLIBDIR) + @echo MANDIR:' '$(MANDIR) + @echo DOCDIR:' '$(DOCDIR) + @echo LIBEXECDIR:' '$(LIBEXECDIR) + @echo + +.display-build: + @echo NATIVE_CC:' '$(NATIVE_CC) + @echo NATIVE_OS:' '$(NATIVE_OS) + @echo NATIVE_OS_BITS:' '$(NATIVE_OS_BITS) + @echo NATIVE_OS_UNDERSCORE:' '$(NATIVE_OS_UNDERSCORE) + @echo + @echo USER_CC:' '$(USER_CC) + @echo USER_CPP:' '$(USER_CPP) + @echo USER_CXX:' '$(USER_CXX) + @echo + + +.PHONY: all install shared static app .display \ + shared-objs shared-lib shared-implib \ + static-objs static-lib \ + default-app shared-app static-app \ + install-shared install-static install-implib \ + install-headers install-app \ + clean distclean version \ + .display-project .display-env .display-tools .display-flags \ + .display-pe .display-elf .display-dirs .display-build diff --git a/config.project b/config.project new file mode 100644 index 0000000..bb734a7 --- /dev/null +++ b/config.project @@ -0,0 +1,50 @@ +# project +mb_package=slibtool +mb_require_out_of_tree=no + + +# dirs +mb_default_prefix= +mb_default_bindir=bin +mb_default_libdir=lib +mb_default_includedir=include +mb_default_syslibdir=lib +mb_default_mandir=man +mb_default_docdir=doc +mb_default_libexecdir=libexec + + +# build +mb_default_build= +mb_default_host= +mb_default_target= +mb_default_arch= +mb_default_compiler= +mb_default_toolchain= +mb_default_sysroot= +mb_default_cross_compile= +mb_default_shell=sh + + +# switches +mb_default_cflags_debug= +mb_default_cflags_common="-std=c99 -D_XOPEN_SOURCE=700 -I\$(PROJECT_DIR)/src/internal -I\$(PROJECT_DIR)/include -Ibuild" +mb_default_cflags_cmdline= +mb_default_cflags_config= +mb_default_cflags_sysroot= +mb_default_cflags_path= + +mb_default_ldflags_debug= +mb_default_ldflags_common="-Llib" +mb_default_ldflags_cmdline= +mb_default_ldflags_config= +mb_default_ldflags_sysroot= +mb_default_ldflags_path= + +mb_default_pe_subsystem=windows +mb_default_pe_image_base= +mb_default_pe_config_defs= + +mb_default_elf_eh_frame= +mb_default_elf_hash_style= +mb_default_elf_config_defs= diff --git a/config.usage b/config.usage new file mode 100644 index 0000000..fda5882 --- /dev/null +++ b/config.usage @@ -0,0 +1,79 @@ +configure: a skinny configuration script. + +supported switches: +------------------- + --help + + --prefix + --bindir + --libdir + --includedir + --syslibdir + --mandir + --libexecdir + + --build + --host + --target + --arch + --compiler + --toolchain + --sysroot + --cross-compile + --shell + --debug + + +supported variables: +-------------------- + PREFIX + BINDIR + LIBDIR + INCLUDEDIR + LIBDIR + MANDIR + DOCDIR + LIBEXECDIR + + CC + CPP + CXX + + BUILD + HOST + TARGET + ARCH + COMPILER + TOOLCHAIN + SYSROOT + CROSS_COMPILE + SHELL + + CFLAGS + CFLAGS_DEBUG + CFLAGS_COMMON + CFLAGS_CMDLINE + CFLAGS_CONFIG + CFLAGS_SYSROOT + CFLAGS_PATH + + LDFLAGS + LDFLAGS_DEBUG + LDFLAGS_COMMON + LDFLAGS_CMDLINE + LDFLAGS_CONFIG + LDFLAGS_SYSROOT + LDFLAGS_PATH + + PE_SUBSYSTEM + PE_IMAGE_BASE + PE_CONFIG_DEFS + + ELF_EH_FRAME + ELF_HASH_STYLE + ELF_CONFIG_DEFS + + NATIVE_CC + NATIVE_OS + NATIVE_OS_BITS + NATIVE_OS_UNDERSCORE diff --git a/configure b/configure new file mode 100755 index 0000000..fc22842 --- /dev/null +++ b/configure @@ -0,0 +1,467 @@ +#!/bin/sh +# we are no longer lazy. + +# this script respects both CFLAGS and CFLAGS_CMDLINE, +# as well as both LDFLAGS and LDFLAGS_CMDLINE, however +# the latter variable of each pair should be preferred. + +usage() +{ + cat "$mb_project_dir"/config.usage + exit $? +} + +error_msg() +{ + echo $@ >&2 +} + + +init_vars() +{ + mb_project_dir=$(cd `dirname $0` ; pwd) + mb_pwd=`pwd` + + if [ -z "$mb_config" ]; then + . $mb_project_dir/config.project || exit 2 + else + . "$mb_config" || exit 2 + fi + + # dirs + mb_prefix=$PREFIX + mb_bindir=$BINDIR + mb_libdir=$LIBDIR + mb_includedir=$INCLUDEDIR + mb_syslibdir=$LIBDIR + mb_mandir=$MANDIR + mb_docdir=$DOCDIR + mb_libexecdir=$LIBEXECDIR + + + # build + mb_build=$BUILD + mb_host=$HOST + mb_target=$TARGET + mb_arch=$ARCH + mb_compiler=$COMPILER + mb_toolchain=$TOOLCHAIN + mb_sysroot=$SYSROOT + mb_cross_compile=$CROSS_COMPILE + mb_shell=$SHELL + + # switches + mb_cflags=$CFLAGS + mb_cflags_debug=$CFLAGS_DEBUG + mb_cflags_common=$CFLAGS_COMMON + mb_cflags_cmdline=$CFLAGS_CMDLINE + mb_cflags_config=$CFLAGS_CONFIG + mb_cflags_sysroot=$CFLAGS_SYSROOT + mb_cflags_os=$CFLAGS_OS + mb_cflags_site=$CFLAGS_SITE + mb_cflags_path=$CFLAGS_PATH + + mb_ldflags=$LDFLAGS + mb_ldflags_debug=$LDFLAGS_DEBUG + mb_ldflags_common=$LDFLAGS_COMMON + mb_ldflags_cmdline=$LDFLAGS_CMDLINE + mb_ldflags_config=$LDFLAGS_CONFIG + mb_ldflags_sysroot=$LDFLAGS_SYSROOT + mb_ldflags_path=$LDFLAGS_PATH + + mb_pe_subsystem=$PE_SUBSYSTEM + mb_pe_image_base=$PE_IMAGE_BASE + mb_pe_config_defs=$PE_CONFIG_DEFS + + mb_elf_eh_frame=$ELF_EH_FRAME + mb_elf_hash_style=$ELF_HASH_STYLE + mb_elf_config_defs=$ELF_CONFIG_DEFS + + # overrides + mb_native_cc=$NATIVE_CC + mb_native_os=$NATIVE_OS + mb_native_os_bits=$NATIVE_OS_BITS + mb_native_os_underscore=$NATIVE_OS_UNDERSCORE + + mb_user_cc=$CC + mb_user_cpp=$CPP + mb_user_cxx=$CXX +} + + +verify_build_directory() +{ + if [ "$mb_project_dir" = "$mb_pwd" ]; then + if [ "$mb_require_out_of_tree" = yes ]; then + error_msg "$mb_package: out-of-tree builds are required." + error_msg "please invoke configure again from a clean build directory." + exit 2 + else + mb_project_dir='.' + fi + fi +} + + +common_defaults() +{ + # dirs + [ -z "$mb_prefix" ] && mb_prefix=$mb_default_prefix + [ -z "$mb_bindir" ] && mb_bindir=$mb_default_bindir + [ -z "$mb_libdir" ] && mb_libdir=$mb_default_libdir + [ -z "$mb_includedir" ] && mb_includedir=$mb_default_includedir + [ -z "$mb_syslibdir" ] && mb_syslibdir=$mb_default_syslibdir + [ -z "$mb_mandir" ] && mb_mandir=$mb_default_mandir + [ -z "$mb_docdir" ] && mb_docdir=$mb_default_docdir + [ -z "$mb_libexecdir" ] && mb_libexecdir=$mb_default_libexecdir + + # build + [ -z "$mb_build" ] && mb_build=$mb_default_build + [ -z "$mb_host" ] && mb_host=$mb_default_host + [ -z "$mb_target" ] && mb_target=$mb_default_target + [ -z "$mb_arch" ] && mb_arch=$mb_default_arch + [ -z "$mb_compiler" ] && mb_compiler=$mb_default_compiler + [ -z "$mb_toolchain" ] && mb_toolchain=$mb_default_toolchain + [ -z "$mb_sysroot" ] && mb_sysroot=$mb_default_sysroot + [ -z "$mb_cross_compile" ] && mb_cross_compile=$mb_default_cross_compile + [ -z "$mb_shell" ] && mb_shell=$mb_default_shell + + # switches + [ -z "$mb_cflags_debug" ] && mb_cflags_debug=$mb_default_cflags_debug + [ -z "$mb_cflags_common" ] && mb_cflags_common=$mb_default_cflags_common + [ -z "$mb_cflags_cmdline" ] && mb_cflags_cmdline=$mb_default_cflags_cmdline + [ -z "$mb_cflags_config" ] && mb_cflags_config=$mb_default_cflags_config + [ -z "$mb_cflags_sysroot" ] && mb_cflags_sysroot=$mb_default_cflags_sysroot + [ -z "$mb_cflags_os" ] && mb_cflags_os=$mb_default_cflags_os + [ -z "$mb_cflags_site" ] && mb_cflags_site=$mb_default_cflags_site + [ -z "$mb_cflags_path" ] && mb_cflags_path=$mb_default_cflags_path + + [ -z "$mb_ldflags_debug" ] && mb_ldflags_debug=$mb_default_ldflags_debug + [ -z "$mb_ldflags_common" ] && mb_ldflags_common=$mb_default_ldflags_common + [ -z "$mb_ldflags_cmdline" ] && mb_ldflags_cmdline=$mb_default_ldflags_cmdline + [ -z "$mb_ldflags_config" ] && mb_ldflags_config=$mb_default_ldflags_config + [ -z "$mb_ldflags_sysroot" ] && mb_ldflags_sysroot=$mb_default_ldflags_sysroot + [ -z "$mb_ldflags_path" ] && mb_ldflags_path=$mb_default_ldflags_path + + [ -z "$mb_pe_subsystem" ] && mb_pe_subsystem=$mb_default_pe_subsystem + [ -z "$mb_pe_image_base" ] && mb_pe_image_base=$mb_default_pe_image_base + [ -z "$mb_pe_config_defs" ] && mb_pe_config_defs=$mb_default_pe_config_defs + + [ -z "$mb_elf_eh_frame" ] && mb_elf_eh_frame=$mb_default_elf_eh_frame + [ -z "$mb_elf_hash_style" ] && mb_elf_hash_style=$mb_default_elf_hash_style + [ -z "$mb_elf_config_defs" ] && mb_elf_config_defs=$mb_default_elf_config_defs + + # host/target + [ -z "$mb_host" ] && mb_host=$mb_target + [ -z "$mb_target" ] && mb_target=$mb_host + + # sysroot + if [ -n "$mb_sysroot" ]; then + if [ -z "$mb_cflags_sysroot" ]; then + mb_cflags_sysroot="--sysroot=$mb_sysroot" + fi + + if [ -z "$mb_ldflags_sysroot" ]; then + mb_ldflags_sysroot="-Wl,--sysroot,$mb_sysroot" + fi + fi + + # debug + if [ "$mb_debug" = yes ]; then + if [ -z "$mb_cflags_debug" ]; then + mb_cflags_debug='-g3 -O0' + fi + fi + + # compiler + if [ -n "$mb_compiler" ]; then + if [ -z "$mb_native_cc" ]; then + mb_native_cc=$mb_compiler + fi + fi + + # toolchain + if [ -z "$mb_toolchain" ]; then + mb_toolchain='binutils' + fi + + # fallback host recipe + if [ -n "$mb_host" ]; then + if ! [ -f $mb_project_dir/sysinfo/host/$mb_host.mk ]; then + if [ -z "$mb_cross_compile" ]; then + mb_cross_compile=$mb_host- + fi + + mb_host='any-host'; + fi + fi + + # fallback compiler recipe + if [ -n "$mb_compiler" ]; then + if ! [ -f $mb_project_dir/sysinfo/compiler/$mb_compiler.mk ]; then + mb_compiler='any-compiler' + fi + fi +} + + +native_defaults() +{ + # CC (when set, must be valid) + if [ -n "$CC" ]; then + $CC -dM -E - < /dev/null > /dev/null || exit 2 + fi + + # compiler + [ -z "$mb_native_cc" ] && mb_native_cc=$CC + [ -z "$mb_native_cc" ] && mb_native_cc='cc' + $mb_native_cc -dM -E - < /dev/null > /dev/null 2>/dev/null || mb_native_cc= + + [ -z "$mb_native_cc" ] && mb_native_cc='gcc' + $mb_native_cc -dM -E - < /dev/null > /dev/null 2>/dev/null || mb_native_cc= + + [ -z "$mb_native_cc" ] && mb_native_cc='clang' + $mb_native_cc -dM -E - < /dev/null > /dev/null 2>/dev/null || mb_native_cc= + + [ -z "$mb_native_cc" ] && mb_native_cc='cparser' + $mb_native_cc -dM -E - < /dev/null > /dev/null 2>/dev/null || mb_native_cc= + + if [ -z "$mb_native_cc" ]; then + echo "configure: info: could not find a working native compiler." + mb_native_cc='false' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep '__clang__' > /dev/null && mb_compiler='clang' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep '__GCC' > /dev/null && mb_compiler='gcc' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep '__CPARSER__' > /dev/null && mb_compiler='cparser' + fi + + if [ -z "$mb_compiler" ]; then + echo "configure: info: could not identify the native compiler." + mb_compiler='any-compiler' + fi + + + # host + if [ -z "$mb_host" ]; then + mb_host='native' + fi + + + # target + if [ -z "$mb_target" ]; then + mb_target='native' + fi + + + # os + mb_native_os=`uname | tr '[:upper:]' '[:lower:]'` + + mb_native_os_sizeof_pointer=`$mb_native_cc -dM -E - < /dev/null \ + | grep __SIZEOF_POINTER__ \ + | cut -d ' ' -f3` + + mb_native_os_bits=`expr '8' '*' '0'"$mb_native_os_sizeof_pointer"` + + if [ $mb_native_os_bits = 32 ]; then + mb_native_os_underscore='_' + else + mb_native_os_underscore='' + fi + + if [ -z "$mb_native_os_sizeof_pointer" ]; then + error_msg "config error: could not determine size of pointer on native system." + exit 2 + fi + + [ -z "$mb_native_os" ] && mb_native_os=$mb_native_os + [ -z "$mb_native_os_bits" ] && mb_native_os_bits=$mb_native_os_bits + [ -z "$mb_native_os_underscore" ] && mb_native_os_underscore=$mb_native_os_underscore +} + + +cross_defaults() +{ + if [ -z "$mb_cross_compile" ] && [ "$mb_host" != native ]; then + mb_cross_compile=$mb_host'-' + fi +} + + +config_copy() +{ + sed -e 's^@package@^'"$mb_package"'^g' \ + -e 's^@project_dir@^'"$mb_project_dir"'^g' \ + \ + -e 's^@build@^'"$mb_build"'^g' \ + -e 's^@host@^'"$mb_host"'^g' \ + -e 's^@target@^'"$mb_target"'^g' \ + -e 's^@arch@^'"$mb_arch"'^g' \ + -e 's^@compiler@^'"$mb_compiler"'^g' \ + -e 's^@toolchain@^'"$mb_toolchain"'^g' \ + -e 's^@sysroot@^'"$mb_sysroot"'^g' \ + -e 's^@cross_compile@^'"$mb_cross_compile"'^g' \ + -e 's^@shell@^'"$mb_shell"'^g' \ + \ + -e 's^@cflags@^'"$mb_cflags"'^g' \ + -e 's^@cflags_debug@^'"$mb_cflags_debug"'^g' \ + -e 's^@cflags_common@^'"$mb_cflags_common"'^g' \ + -e 's^@cflags_cmdline@^'"$mb_cflags $mb_cflags_cmdline"'^g' \ + -e 's^@cflags_config@^'"$mb_cflags_config"'^g' \ + -e 's^@cflags_sysroot@^'"$mb_cflags_sysroot"'^g' \ + -e 's^@cflags_os@^'"$mb_cflags_os"'^g' \ + -e 's^@cflags_site@^'"$mb_cflags_site"'^g' \ + -e 's^@cflags_path@^'"$mb_cflags_path"'^g' \ + \ + -e 's^@ldflags@^'"$mb_ldflags"'^g' \ + -e 's^@ldflags_debug@^'"$mb_ldflags_debug"'^g' \ + -e 's^@ldflags_common@^'"$mb_ldflags_common"'^g' \ + -e 's^@ldflags_cmdline@^'"$mb_ldflags $mb_ldflags_cmdline"'^g' \ + -e 's^@ldflags_config@^'"$mb_ldflags_config"'^g' \ + -e 's^@ldflags_sysroot@^'"$mb_ldflags_sysroot"'^g' \ + -e 's^@ldflags_path@^'"$mb_ldflags_path"'^g' \ + \ + -e 's^@pe_subsystem@^'"$mb_pe_subsystem"'^g' \ + -e 's^@pe_image\_base@^'"$mb_pe_image_base"'^g' \ + -e 's^@pe_config\_defs@^'"$mb_pe_config_defs"'^g' \ + \ + -e 's^@elf_eh\_frame@^'"$mb_elf_eh_frame"'^g' \ + -e 's^@elf_hash\_style@^'"$mb_elf_hash_style"'^g' \ + -e 's^@elf_config\_defs@^'"$mb_elf_config_defs"'^g' \ + \ + -e 's^@prefix@^'"$mb_prefix"'^g' \ + -e 's^@bindir@^'"$mb_bindir"'^g' \ + -e 's^@libdir@^'"$mb_libdir"'^g' \ + -e 's^@includedir@^'"$mb_includedir"'^g' \ + -e 's^@syslibdir@^'"$mb_syslibdir"'^g' \ + -e 's^@mandir@^'"$mb_mandir"'^g' \ + -e 's^@docdir@^'"$mb_docdir"'^g' \ + -e 's^@libexecdir@^'"$mb_libexecdir"'^g' \ + \ + -e 's^@native_cc@^'"$mb_native_cc"'^g' \ + -e 's^@native_os@^'"$mb_native_os"'^g' \ + -e 's^@native_os_bits@^'"$mb_native_os_bits"'^g' \ + -e 's^@native_os_underscore@^'"$mb_native_os_underscore"'^g' \ + \ + -e 's^@user_cc@^'"$mb_user_cc"'^g' \ + -e 's^@user_cpp@^'"$mb_user_cpp"'^g' \ + -e 's^@user_cxx@^'"$mb_user_cxx"'^g' \ + $mb_project_dir/Makefile.in > $mb_pwd/Makefile +} + + +config_host() +{ + make -s host.tag && return 0 + + error_msg "configure was able to generate a Makefile for the selected host," + error_msg "however the host-targeting compiler was found to be missing" + error_msg "at least one of the required headers or features." + exit 2 +} + + +config_status() +{ + printf "\n\n" + make .display + printf "\nconfiguration completed successfully.\n\n" +} + +# one: init +init_vars +verify_build_directory + + +# two: args +for arg ; do + case "$arg" in + --help) usage + ;; + + # dirs + --prefix=*) + mb_prefix=${arg#*=} + ;; + --bindir=*) + mb_bindir=${arg#*=} + ;; + --libdir=*) + mb_libdir=${arg#*=} + ;; + --includedir=*) + mb_includedir=${arg#*=} + ;; + --syslibdir=*) + mb_syslibdir=${arg#*=} + ;; + --mandir=*) + mb_mandir=${arg#*=} + ;; + --libexecdir=*) + mb_libexecdir=${arg#*=} + ;; + + + # build + --build=*) + mb_build=${arg#*=} + ;; + --host=*) + mb_host=${arg#*=} + ;; + --target=*) + mb_target=${arg#*=} + ;; + --arch=*) + mb_arch=${arg#*=} + ;; + --compiler=*) + mb_compiler=${arg#*=} + ;; + --toolchain=*) + mb_toolchain=${arg#*=} + ;; + --sysroot=*) + mb_sysroot=${arg#*=} + ;; + --cross-compile=*) + mb_cross_compile=${arg#*=} + ;; + --shell=*) + mb_shell=${arg#*=} + ;; + --debug) + mb_debug='yes' + ;; + *) + error_msg ${arg#}: "unsupported config argument." + exit 2 + ;; + esac +done + + + +# three: defaults +common_defaults +native_defaults +cross_defaults + + + +# four: config +config_copy +config_host +config_status + + +# all done +exit 0 diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h new file mode 100644 index 0000000..4aec0cc --- /dev/null +++ b/include/slibtool/slibtool.h @@ -0,0 +1,88 @@ +#ifndef SOFORT_H +#define SOFORT_H + +#include <stdint.h> +#include <stdio.h> + +#include "slibtool_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* pre-alpha */ +#ifndef SLBT_APP +#ifndef SLBT_PRE_ALPHA +#error libslibtool: pre-alpha: ABI is not final! +#error to use the library, please pass -DSLBT_PRE_ALPHA to the compiler. +#endif +#endif + +/* status codes */ +#define SLBT_OK 0x00 +#define SLBT_USAGE 0x01 +#define SLBT_BAD_OPT 0x02 +#define SLBT_BAD_OPT_VAL 0x03 +#define SLBT_IO_ERROR 0xA0 +#define SLBT_MAP_ERROR 0xA1 + +/* driver flags */ +#define SLBT_DRIVER_VERBOSITY_NONE 0x0000 +#define SLBT_DRIVER_VERBOSITY_ERRORS 0x0001 +#define SLBT_DRIVER_VERBOSITY_STATUS 0x0002 +#define SLBT_DRIVER_VERBOSITY_USAGE 0x0004 +#define SLBT_DRIVER_CLONE_VECTOR 0x0008 + +#define SLBT_DRIVER_VERSION 0x0010 +#define SLBT_DRIVER_DRY_RUN 0x0020 + +/* unit action flags */ + +struct slbt_input { + void * addr; + size_t size; +}; + +struct slbt_common_ctx { + uint64_t drvflags; + uint64_t actflags; + uint64_t fmtflags; +}; + +struct slbt_driver_ctx { + const char ** units; + const char * program; + const char * module; + const struct slbt_common_ctx * cctx; + void * any; + int status; + int nerrors; +}; + +struct slbt_unit_ctx { + const char * const * path; + const struct slbt_input * map; + const struct slbt_common_ctx * cctx; + void * any; + int status; + int nerrors; +}; + +/* driver api */ +slbt_api int slbt_get_driver_ctx (char ** argv, char ** envp, uint32_t flags, struct slbt_driver_ctx **); +slbt_api int slbt_create_driver_ctx (const struct slbt_common_ctx *, struct slbt_driver_ctx **); +slbt_api void slbt_free_driver_ctx (struct slbt_driver_ctx *); + +slbt_api int slbt_get_unit_ctx (const struct slbt_driver_ctx *, const char * path, struct slbt_unit_ctx **); +slbt_api void slbt_free_unit_ctx (struct slbt_unit_ctx *); + +slbt_api int slbt_map_input (int fd, const char * path, int prot, struct slbt_input *); +slbt_api int slbt_unmap_input (struct slbt_input *); + +/* utility api */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/slibtool/slibtool_api.h b/include/slibtool/slibtool_api.h new file mode 100644 index 0000000..2be0a47 --- /dev/null +++ b/include/slibtool/slibtool_api.h @@ -0,0 +1,35 @@ +#ifndef SOFORT_API_H +#define SOFORT_API_H + +#include <limits.h> + +/* slbt_export */ +#if defined(__dllexport) +#define slbt_export __dllexport +#else +#define slbt_export +#endif + +/* slbt_import */ +#if defined(__dllimport) +#define slbt_import __dllimport +#else +#define slbt_import +#endif + +/* slbt_api */ +#ifndef SLBT_APP +#if defined (SLBT_BUILD) +#define slbt_api slbt_export +#elif defined (SLBT_SHARED) +#define slbt_api slbt_import +#elif defined (SLBT_STATIC) +#define slbt_api +#else +#define slbt_api +#endif +#else +#define slbt_api +#endif + +#endif diff --git a/project/arch.mk b/project/arch.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/project/arch.mk diff --git a/project/common.mk b/project/common.mk new file mode 100644 index 0000000..45a3d8f --- /dev/null +++ b/project/common.mk @@ -0,0 +1,8 @@ +COMMON_SRCS = \ + src/driver/slbt_driver_ctx.c \ + src/driver/slbt_unit_ctx.c \ + src/logic/slbt_map_input.c \ + src/skin/slbt_skin_default.c \ + +APP_SRCS = \ + src/slibtool.c diff --git a/project/defs.mk b/project/defs.mk new file mode 100644 index 0000000..9c36756 --- /dev/null +++ b/project/defs.mk @@ -0,0 +1,44 @@ +SHARED_LIB_DEPS = +SHARED_APP_DEPS = +STATIC_APP_DEPS = + +COMMON_LOBJS = $(COMMON_SRCS:.c=.lo) +COMMON_OBJS = $(COMMON_SRCS:.c=.o) + +ARCH_LOBJS = $(ARCH_SRCS:.c=.lo) +ARCH_OBJS = $(ARCH_SRCS:.c=.o) + +APP_LOBJS = $(APP_SRCS:.c=.lo) +APP_OBJS = $(APP_SRCS:.c=.o) + +SHARED_OBJS = $(COMMON_LOBJS) $(ARCH_LOBJS) +STATIC_OBJS = $(COMMON_OBJS) $(ARCH_OBJS) + +SHARED_LIB = $(LIBDIR)/$(OS_LIB_PREFIX)$(PACKAGE)$(OS_LIB_SUFFIX) +STATIC_LIB = $(LIBDIR)/$(OS_LIB_PREFIX)$(PACKAGE)$(OS_ARCHIVE_EXT) +SHARED_IMPLIB = $(LIBDIR)/$(OS_LIB_PREFIX)$(PACKAGE)$(OS_IMPLIB_EXT) + +APP = $(BINDIR)/$(OS_APP_PREFIX)$(PACKAGE)$(OS_APP_SUFFIX) +DEFAULT_APP = $(BINDIR)/$(OS_APP_PREFIX)$(PACKAGE)-default$(OS_APP_SUFFIX) +SHARED_APP = $(BINDIR)/$(OS_APP_PREFIX)$(PACKAGE)-shared$(OS_APP_SUFFIX) +STATIC_APP = $(BINDIR)/$(OS_APP_PREFIX)$(PACKAGE)-static$(OS_APP_SUFFIX) + +CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_CONFIG) $(CFLAGS_SYSROOT) \ + $(CFLAGS_COMMON) $(CFLAGS_CMDLINE) $(CFLAGS_HOST) \ + $(CFLAGS_PATH) $(CFLAGS_OS) $(CFLAGS_SITE) + +CFLAGS_SHARED = $(CFLAGS) $(CFLAGS_PIC) $(CFLAGS_SHARED_ATTR) +CFLAGS_STATIC = $(CFLAGS) $(CFLAGS_OBJ) $(CFLAGS_STATIC_ATTR) +CFLAGS_APP = $(CFLAGS) $(CFLAGS_OBJ) $(CFLAGS_APP_ATTR) + +LDFLAGS_SHARED = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(SHARED_LIB_DEPS) $(LDFLAGS_LAST) + +LDFLAGS_APP = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(SHARED_APP_DEPS) $(LDFLAGS_LAST) + +LDFLAGS_STATIC = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(STATIC_APP_DEPS) $(LDFLAGS_LAST) diff --git a/project/depends.mk b/project/depends.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/project/depends.mk diff --git a/project/extras.mk b/project/extras.mk new file mode 100644 index 0000000..8e2cb61 --- /dev/null +++ b/project/extras.mk @@ -0,0 +1,3 @@ +CFLAGS_SHARED_ATTR += -DSLBT_PRE_ALPHA -DSLBT_BUILD +CFLAGS_STATIC_ATTR += -DSLBT_PRE_ALPHA -DSLBT_STATIC +CFLAGS_APP_ATTR += -DSLBT_APP diff --git a/project/headers.mk b/project/headers.mk new file mode 100644 index 0000000..1a210ff --- /dev/null +++ b/project/headers.mk @@ -0,0 +1,9 @@ +API_HEADERS = \ + $(PROJECT_DIR)/include/$(PACKAGE)/slibtool.h \ + $(PROJECT_DIR)/include/$(PACKAGE)/slibtool_api.h \ + +INTERNAL_HEADERS = \ + $(PROJECT_DIR)/src/internal/argv/argv.h \ + $(PROJECT_DIR)/src/internal/$(PACKAGE)_driver_impl.h \ + +ALL_HEADERS = $(API_HEADERS) $(INTERNAL_HEADERS) diff --git a/project/overrides.mk b/project/overrides.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/project/overrides.mk diff --git a/project/tree.mk b/project/tree.mk new file mode 100644 index 0000000..d91f6a2 --- /dev/null +++ b/project/tree.mk @@ -0,0 +1,8 @@ +tree.tag: + mkdir -p src + mkdir -p src/driver + mkdir -p src/internal + mkdir -p src/logic + mkdir -p src/output + mkdir -p src/skin + touch tree.tag diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c new file mode 100644 index 0000000..9888e46 --- /dev/null +++ b/src/driver/slbt_driver_ctx.c @@ -0,0 +1,181 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdint.h> +#include <unistd.h> +#include <fcntl.h> + +#define ARGV_DRIVER + +#include <slibtool/slibtool.h> +#include "slibtool_driver_impl.h" +#include "argv/argv.h" + +struct slbt_driver_ctx_alloc { + struct argv_meta * meta; + struct slbt_driver_ctx_impl ctx; + uint64_t guard; + const char * units[]; +}; + +static uint32_t slbt_argv_flags(uint32_t flags) +{ + uint32_t ret = 0; + + if (flags & SLBT_DRIVER_VERBOSITY_NONE) + ret |= ARGV_VERBOSITY_NONE; + + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + ret |= ARGV_VERBOSITY_ERRORS; + + if (flags & SLBT_DRIVER_VERBOSITY_STATUS) + ret |= ARGV_VERBOSITY_STATUS; + + return ret; +} + +static int slbt_driver_usage( + const char * program, + const char * arg, + const struct argv_option * options, + struct argv_meta * meta) +{ + char header[512]; + + snprintf(header,sizeof(header), + "Usage: %s [options] <file>...\n" "Options:\n", + program); + + argv_usage(stdout,header,options,arg); + argv_free(meta); + + return SLBT_USAGE; +} + +static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc( + struct argv_meta * meta, + const struct slbt_common_ctx * cctx, + size_t nunits) +{ + struct slbt_driver_ctx_alloc * ictx; + size_t size; + struct argv_entry * entry; + const char ** units; + + size = sizeof(struct slbt_driver_ctx_alloc); + size += (nunits+1)*sizeof(const char *); + + if (!(ictx = calloc(1,size))) + return 0; + + if (cctx) + memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx)); + + for (entry=meta->entries,units=ictx->units; entry->fopt || entry->arg; entry++) + if (!entry->fopt) + *units++ = entry->arg; + + ictx->meta = meta; + ictx->ctx.ctx.units = ictx->units; + return &ictx->ctx; +} + +static int slbt_get_driver_ctx_fail(struct argv_meta * meta) +{ + argv_free(meta); + return -1; +} + +int slbt_get_driver_ctx( + char ** argv, + char ** envp, + uint32_t flags, + struct slbt_driver_ctx ** pctx) +{ + struct slbt_driver_ctx_impl * ctx; + struct slbt_common_ctx cctx; + const struct argv_option * options; + struct argv_meta * meta; + struct argv_entry * entry; + size_t nunits; + const char * program; + + options = slbt_default_options; + + if (!(meta = argv_get(argv,options,slbt_argv_flags(flags)))) + return -1; + + nunits = 0; + program = argv_program_name(argv[0]); + memset(&cctx,0,sizeof(cctx)); + + if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE)) + return slbt_driver_usage(program,0,options,meta); + + /* get options, count units */ + for (entry=meta->entries; entry->fopt || entry->arg; entry++) { + if (entry->fopt) { + switch (entry->tag) { + case TAG_HELP: + if (flags & SLBT_DRIVER_VERBOSITY_USAGE) + return slbt_driver_usage(program,entry->arg,options,meta); + + case TAG_VERSION: + cctx.drvflags |= SLBT_DRIVER_VERSION; + break; + } + } else + nunits++; + } + + if (!(ctx = slbt_driver_ctx_alloc(meta,&cctx,nunits))) + return slbt_get_driver_ctx_fail(meta); + + ctx->ctx.program = program; + ctx->ctx.cctx = &ctx->cctx; + + *pctx = &ctx->ctx; + return SLBT_OK; +} + +int slbt_create_driver_ctx( + const struct slbt_common_ctx * cctx, + struct slbt_driver_ctx ** pctx) +{ + struct argv_meta * meta; + struct slbt_driver_ctx_impl * ctx; + char * argv[] = {"slibtool_driver",0}; + + if (!(meta = argv_get(argv,slbt_default_options,0))) + return -1; + + if (!(ctx = slbt_driver_ctx_alloc(meta,cctx,0))) + return slbt_get_driver_ctx_fail(0); + + ctx->ctx.cctx = &ctx->cctx; + memcpy(&ctx->cctx,cctx,sizeof(*cctx)); + *pctx = &ctx->ctx; + return SLBT_OK; +} + +static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx) +{ + argv_free(ictx->meta); + free(ictx); +} + +void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx) +{ + struct slbt_driver_ctx_alloc * ictx; + uintptr_t addr; + + if (ctx) { + addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx); + addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx); + ictx = (struct slbt_driver_ctx_alloc *)addr; + slbt_free_driver_ctx_impl(ictx); + } +} diff --git a/src/driver/slbt_unit_ctx.c b/src/driver/slbt_unit_ctx.c new file mode 100644 index 0000000..3fab392 --- /dev/null +++ b/src/driver/slbt_unit_ctx.c @@ -0,0 +1,62 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> + +#include <slibtool/slibtool.h> +#include "slibtool_driver_impl.h" + +static int slbt_free_unit_ctx_impl(struct slbt_unit_ctx_impl * ctx, int status) +{ + if (ctx) { + slbt_unmap_input(&ctx->map); + free(ctx); + } + + return status; +} + +int slbt_get_unit_ctx( + const struct slbt_driver_ctx * dctx, + const char * path, + struct slbt_unit_ctx ** pctx) +{ + struct slbt_unit_ctx_impl * ctx; + + if (!dctx || !(ctx = calloc(1,sizeof(*ctx)))) + return -1; + + if (slbt_map_input(-1,path,PROT_READ,&ctx->map)) + return slbt_free_unit_ctx_impl(ctx,-1); + + memcpy(&ctx->cctx,dctx->cctx, + sizeof(ctx->cctx)); + + ctx->path = path; + + ctx->uctx.path = &ctx->path; + ctx->uctx.map = &ctx->map; + ctx->uctx.cctx = &ctx->cctx; + + *pctx = &ctx->uctx; + return 0; +} + +void slbt_free_unit_ctx(struct slbt_unit_ctx * ctx) +{ + struct slbt_unit_ctx_impl * ictx; + uintptr_t addr; + + if (ctx) { + addr = (uintptr_t)ctx - offsetof(struct slbt_unit_ctx_impl,uctx); + ictx = (struct slbt_unit_ctx_impl *)addr; + slbt_free_unit_ctx_impl(ictx,0); + } +} diff --git a/src/internal/argv/argv.h b/src/internal/argv/argv.h new file mode 100644 index 0000000..4f037fb --- /dev/null +++ b/src/internal/argv/argv.h @@ -0,0 +1,1053 @@ +/****************************************************************************/ +/* argv.h: a thread-safe argument vector parser and usage screen generator */ +/* Copyright (C) 2015--2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SOFORT. */ +/* This file is (also) part of sofort: portable software project template. */ +/****************************************************************************/ + +#ifndef ARGV_H +#define ARGV_H + +#include <stdbool.h> +#include <stdint.h> +#include <stddef.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#define ARGV_VERBOSITY_NONE 0x00 +#define ARGV_VERBOSITY_ERRORS 0x01 +#define ARGV_VERBOSITY_STATUS 0x02 +#define ARGV_CLONE_VECTOR 0x80 + +#ifndef ARGV_TAB_WIDTH +#define ARGV_TAB_WIDTH 8 +#endif + +/*******************************************/ +/* */ +/* support of hybrid options */ +/* ------------------------- */ +/* hybrid options are very similar to */ +/* long options, yet are prefixed by */ +/* a single dash rather than two */ +/* (i.e. -std, -isystem). */ +/* hybrid options are supported by this */ +/* driver for compatibility with legacy */ +/* tools; note, however, that the use */ +/* of hybrid options should be strongly */ +/* discouraged due to the limitations */ +/* they impose on short options (for */ +/* example, a driver implementing -std */ +/* may not provide -s as a short option */ +/* that takes an arbitrary value). */ +/* */ +/* SPACE: -hybrid VALUE (i.e. -MF file) */ +/* EQUAL: -hybrid=VALUE (i.e. -std=c99) */ +/* COMMA: -hybrid,VALUE (i.e. -Wl,<arg>) */ +/* ONLY: -opt accepted, --opt rejected */ +/* JOINED: -optVALUE */ +/* */ +/*******************************************/ + + +#define ARGV_OPTION_HYBRID_NONE 0x00 +#define ARGV_OPTION_HYBRID_ONLY 0x01 +#define ARGV_OPTION_HYBRID_SPACE 0x02 +#define ARGV_OPTION_HYBRID_EQUAL 0x04 +#define ARGV_OPTION_HYBRID_COMMA 0x08 +#define ARGV_OPTION_HYBRID_JOINED 0x10 +#define ARGV_OPTION_HYBRID_CIRCUS (ARGV_OPTION_HYBRID_SPACE \ + | ARGV_OPTION_HYBRID_JOINED) +#define ARGV_OPTION_HYBRID_DUAL (ARGV_OPTION_HYBRID_SPACE \ + | ARGV_OPTION_HYBRID_EQUAL) +#define ARGV_OPTION_HYBRID_SWITCH (ARGV_OPTION_HYBRID_SPACE \ + | ARGV_OPTION_HYBRID_EQUAL \ + | ARGV_OPTION_HYBRID_COMMA \ + | ARGV_OPTION_HYBRID_JOINED) + +enum argv_optarg { + ARGV_OPTARG_NONE, + ARGV_OPTARG_REQUIRED, + ARGV_OPTARG_OPTIONAL, +}; + +enum argv_mode { + ARGV_MODE_SCAN, + ARGV_MODE_COPY, +}; + +enum argv_error { + ARGV_ERROR_OK, + ARGV_ERROR_INTERNAL, + ARGV_ERROR_SHORT_OPTION, + ARGV_ERROR_LONG_OPTION, + ARGV_ERROR_OPTARG_NONE, + ARGV_ERROR_OPTARG_REQUIRED, + ARGV_ERROR_OPTARG_PARADIGM, + ARGV_ERROR_HYBRID_NONE, + ARGV_ERROR_HYBRID_ONLY, + ARGV_ERROR_HYBRID_SPACE, + ARGV_ERROR_HYBRID_EQUAL, + ARGV_ERROR_HYBRID_COMMA, +}; + +struct argv_option { + const char * long_name; + const char short_name; + int tag; + enum argv_optarg optarg; + int flags; + const char * paradigm; + const char * argname; + const char * description; +}; + +struct argv_entry { + const char * arg; + int tag; + bool fopt; + bool fval; + bool fnoscan; + enum argv_error errcode; +}; + +struct argv_meta { + char ** argv; + struct argv_entry * entries; +}; + +struct argv_meta_impl { + char ** argv; + char * strbuf; + struct argv_meta meta; +}; + +struct argv_ctx { + int flags; + int mode; + int nentries; + int unitidx; + int erridx; + enum argv_error errcode; + const char * errch; + const struct argv_option * erropt; + const char * program; +}; + +#ifdef ARGV_DRIVER + +static const char * argv_program_name(const char *); + +static void argv_usage( + FILE *, + const char * header, + const struct argv_option[], + const char * mode); + +static struct argv_meta * argv_get( + char **, + const struct argv_option[], + int flags); + +static void argv_free(struct argv_meta *); + + + + +/*------------------------------------*/ +/* implementation of static functions */ +/*------------------------------------*/ + +static const struct argv_option * argv_short_option( + const char * ch, + const struct argv_option options[], + struct argv_entry * entry) +{ + const struct argv_option * option; + + for (option=options; option->long_name || option->short_name; option++) { + if (option->short_name == *ch) { + entry->tag = option->tag; + entry->fopt = true; + return option; + } + } + + return 0; +} + +static const struct argv_option * argv_long_option( + const char * ch, + const struct argv_option options[], + struct argv_entry * entry) +{ + const struct argv_option * option; + const char * arg; + size_t len; + + for (option=options; option->long_name || option->short_name; option++) { + len = option->long_name ? strlen(option->long_name) : 0; + + if (len && !(strncmp(option->long_name,ch,len))) { + arg = ch + len; + + if (!*arg + || (*arg == '=') + || (option->flags & ARGV_OPTION_HYBRID_JOINED) + || ((option->flags & ARGV_OPTION_HYBRID_COMMA) + && (*arg == ','))) { + entry->tag = option->tag; + entry->fopt = true; + return option; + } + } + } + + return 0; +} + +static inline bool is_short_option(const char * arg) +{ + return (arg[0]=='-') && arg[1] && (arg[1]!='-'); +} + +static inline bool is_long_option(const char * arg) +{ + return (arg[0]=='-') && (arg[1]=='-') && arg[2]; +} + +static inline bool is_last_option(const char * arg) +{ + return (arg[0]=='-') && (arg[1]=='-') && !arg[2]; +} + +static inline bool is_hybrid_option( + const char * arg, + const struct argv_option options[]) +{ + const struct argv_option * option; + struct argv_entry entry; + + if (!is_short_option(arg)) + return false; + + if (!(option = argv_long_option(++arg,options,&entry))) + return false; + + if (!(option->flags & ARGV_OPTION_HYBRID_SWITCH)) + if (argv_short_option(arg,options,&entry)) + return false; + + return true; +} + +static inline bool is_arg_in_paradigm(const char * arg, const char * paradigm) +{ + size_t len; + const char * ch; + + for (ch=paradigm,len=strlen(arg); ch; ) { + if (!strncmp(arg,ch,len)) { + if (!*(ch += len)) + return true; + else if (*ch == '|') + return true; + } + + if ((ch = strchr(ch,'|'))) + ch++; + } + + return false; +} + +static inline const struct argv_option * option_from_tag( + const struct argv_option options[], + int tag) +{ + const struct argv_option * option; + + for (option=options; option->short_name || option->long_name; option++) + if (option->tag == tag) + return option; + return 0; +} + +static void argv_scan( + char ** argv, + const struct argv_option options[], + struct argv_ctx * ctx, + struct argv_meta * meta) +{ + char ** parg; + const char * ch; + const char * val; + const struct argv_option * option; + struct argv_entry entry; + struct argv_entry * mentry; + enum argv_error ferr; + bool fval; + bool fnext; + bool fshort; + bool fhybrid; + bool fnoscan; + + parg = &argv[1]; + ch = *parg; + ferr = ARGV_ERROR_OK; + fshort = false; + fnoscan = false; + fval = false; + mentry = meta ? meta->entries : 0; + + ctx->unitidx = 0; + ctx->erridx = 0; + + while (ch && (ferr == ARGV_ERROR_OK)) { + option = 0; + fhybrid = false; + + if (fnoscan) + fval = true; + + else if (is_last_option(ch)) + fnoscan = true; + + else if (!fshort && is_hybrid_option(ch,options)) + fhybrid = true; + + if (!fnoscan && !fhybrid && (fshort || is_short_option(ch))) { + if (!fshort) + ch++; + + if ((option = argv_short_option(ch,options,&entry))) { + if (ch[1]) { + ch++; + fnext = false; + fshort = (option->optarg == ARGV_OPTARG_NONE); + } else { + parg++; + ch = *parg; + fnext = true; + fshort = false; + } + + if (option->optarg == ARGV_OPTARG_NONE) { + if (!fnext && ch && (*ch == '-')) + ferr = ARGV_ERROR_OPTARG_NONE; + else + fval = false; + } else if (!fnext) + fval = true; + else if (option->optarg == ARGV_OPTARG_REQUIRED) { + if (ch && is_short_option(ch)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (ch && is_long_option(ch)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (ch && is_last_option(ch)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (ch) + fval = true; + else + ferr = ARGV_ERROR_OPTARG_REQUIRED; + } else { + /* ARGV_OPTARG_OPTIONAL */ + if (ch && is_short_option(ch)) + fval = false; + else if (ch && is_long_option(ch)) + fval = false; + else if (ch && is_last_option(ch)) + fval = false; + else + fval = ch; + } + } else + ferr = ARGV_ERROR_SHORT_OPTION; + + } else if (!fnoscan && (fhybrid || is_long_option(ch))) { + ch += (fhybrid ? 1 : 2); + + if ((option = argv_long_option(ch,options,&entry))) { + val = ch + strlen(option->long_name); + + /* val[0] is either '=' (or ',') or '\0' */ + if (!val[0]) { + parg++; + ch = *parg; + } + + if (fhybrid && !(option->flags & ARGV_OPTION_HYBRID_SWITCH)) + ferr = ARGV_ERROR_HYBRID_NONE; + else if (option->optarg == ARGV_OPTARG_NONE) { + if (val[0]) { + ferr = ARGV_ERROR_OPTARG_NONE; + ctx->errch = val + 1; + } else + fval = false; + } else if (!fhybrid && (option->flags & ARGV_OPTION_HYBRID_ONLY)) + ferr = ARGV_ERROR_HYBRID_ONLY; + else if (val[0] && (option->flags & ARGV_OPTION_HYBRID_JOINED)) { + fval = true; + ch = val; + } else if (fhybrid && !val[0] && !(option->flags & ARGV_OPTION_HYBRID_SPACE)) + ferr = ARGV_ERROR_HYBRID_SPACE; + else if (fhybrid && (val[0]=='=') && !(option->flags & ARGV_OPTION_HYBRID_EQUAL)) + ferr = ARGV_ERROR_HYBRID_EQUAL; + else if (fhybrid && (val[0]==',') && !(option->flags & ARGV_OPTION_HYBRID_COMMA)) + ferr = ARGV_ERROR_HYBRID_COMMA; + else if (!fhybrid && (val[0]==',')) + ferr = ARGV_ERROR_HYBRID_COMMA; + else if (val[0] && !val[1]) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (val[0] && val[1]) { + fval = true; + ch = ++val; + } else if (option->optarg == ARGV_OPTARG_REQUIRED) { + if (!val[0] && !*parg) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (*parg && is_short_option(*parg)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (*parg && is_long_option(*parg)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else if (*parg && is_last_option(*parg)) + ferr = ARGV_ERROR_OPTARG_REQUIRED; + else + fval = true; + } else { + /* ARGV_OPTARG_OPTIONAL */ + fval = val[0]; + } + } else + ferr = ARGV_ERROR_LONG_OPTION; + } + + if (ferr == ARGV_ERROR_OK) + if (option && fval && option->paradigm) + if (!is_arg_in_paradigm(ch,option->paradigm)) + ferr = ARGV_ERROR_OPTARG_PARADIGM; + + if (ferr == ARGV_ERROR_OK) + if (!option && !ctx->unitidx) + ctx->unitidx = parg - argv; + + if (ferr != ARGV_ERROR_OK) { + ctx->errcode = ferr; + ctx->errch = ctx->errch ? ctx->errch : ch; + ctx->erropt = option; + ctx->erridx = parg - argv; + return; + } else if (ctx->mode == ARGV_MODE_SCAN) { + if (!fnoscan) + ctx->nentries++; + else if (fval) + ctx->nentries++; + + if (fval || !option) { + parg++; + ch = *parg; + } + } else if (ctx->mode == ARGV_MODE_COPY) { + if (fnoscan) { + if (fval) { + mentry->arg = ch; + mentry->fnoscan = true; + mentry++; + } + + parg++; + ch = *parg; + } else if (option) { + mentry->arg = fval ? ch : 0; + mentry->tag = option->tag; + mentry->fopt = true; + mentry->fval = fval; + mentry++; + + if (fval) { + parg++; + ch = *parg; + } + } else { + mentry->arg = ch; + mentry++; + parg++; + ch = *parg; + } + } + } +} + +static const char * argv_program_name(const char * program_path) +{ + const char * ch; + + if (program_path) { + if ((ch = strrchr(program_path,'/'))) + return *(++ch) ? ch : 0; + + if ((ch = strrchr(program_path,'\\'))) + return *(++ch) ? ch : 0; + } + + return program_path; +} + +static void argv_show_error(struct argv_ctx * ctx) +{ + fprintf(stderr,"%s: error: ",ctx->program); + + switch (ctx->errcode) { + case ARGV_ERROR_SHORT_OPTION: + fprintf(stderr,"'-%c' is not a valid short option\n",*ctx->errch); + break; + + case ARGV_ERROR_LONG_OPTION: + fprintf(stderr,"'--%s' is not a valid long option\n",ctx->errch); + break; + + case ARGV_ERROR_OPTARG_NONE: + fprintf(stderr,"'%s' is not a valid option value for [%s%c%s%s%s] " + "(option values may not be specified)\n", + ctx->errch, + ctx->erropt->short_name ? "-" : "", + ctx->erropt->short_name, + ctx->erropt->short_name ? "," : "", + ctx->erropt->long_name ? "--" : "", + ctx->erropt->long_name); + break; + + case ARGV_ERROR_OPTARG_REQUIRED: + fprintf(stderr,"option [%s%c%s%s%s] requires %s %s%s%s\n", + ctx->erropt->short_name ? "-" : "", + ctx->erropt->short_name, + ctx->erropt->short_name ? "," : "", + ctx->erropt->long_name ? "--" : "", + ctx->erropt->long_name, + ctx->erropt->paradigm ? "one of the following values:" : "a value", + ctx->erropt->paradigm ? "{" : "", + ctx->erropt->paradigm ? ctx->erropt->paradigm : "", + ctx->erropt->paradigm ? "}" : ""); + break; + + case ARGV_ERROR_OPTARG_PARADIGM: + fprintf(stderr,"'%s' is not a valid option value for [%s%c%s%s%s]={%s}\n", + ctx->errch, + ctx->erropt->short_name ? "-" : "", + ctx->erropt->short_name, + ctx->erropt->short_name ? "," : "", + ctx->erropt->long_name ? "--" : "", + ctx->erropt->long_name, + ctx->erropt->paradigm); + break; + + case ARGV_ERROR_HYBRID_NONE: + fprintf(stderr,"-%s is not a synonym for --%s\n", + ctx->erropt->long_name, + ctx->erropt->long_name); + break; + + case ARGV_ERROR_HYBRID_ONLY: + fprintf(stderr,"--%s is not a synonym for -%s\n", + ctx->erropt->long_name, + ctx->erropt->long_name); + break; + + case ARGV_ERROR_HYBRID_SPACE: + case ARGV_ERROR_HYBRID_EQUAL: + case ARGV_ERROR_HYBRID_COMMA: + fprintf(stderr,"-%s: illegal value assignment; valid syntax is " + "-%s%sVAL\n", + ctx->erropt->long_name, + ctx->erropt->long_name, + (ctx->erropt->flags & ARGV_OPTION_HYBRID_SPACE) + ? " " : (ctx->erropt->flags & ARGV_OPTION_HYBRID_EQUAL) + ? "=" : (ctx->erropt->flags & ARGV_OPTION_HYBRID_COMMA) + ? "," : ""); + + break; + + case ARGV_ERROR_INTERNAL: + fputs("internal error",stderr); + break; + + default: + break; + } +} + +static void argv_show_status( + const struct argv_option options[], + struct argv_ctx * ctx, + struct argv_meta * meta) +{ + int argc; + char ** argv; + struct argv_entry * entry; + const struct argv_option * option; + char short_name[2] = {0}; + const char * space = ""; + + fputs("\n\nconcatenated command line:\n",stderr); + for (argv=meta->argv; *argv; argv++) { + fprintf(stderr,"%s%s",space,*argv); + space = " "; + } + + fputs("\n\nargument vector:\n",stderr); + for (argc=0,argv=meta->argv; *argv; argc++,argv++) + fprintf(stderr,"argv[%d]: %s\n",argc,*argv); + + fputs("\n\nparsed entries:\n",stderr); + for (entry=meta->entries; entry->arg || entry->fopt; entry++) + if (entry->fopt) { + option = option_from_tag(options,entry->tag); + short_name[0] = option->short_name; + + if (entry->fval) + fprintf(stderr,"[-%s,--%s] := %s\n", + short_name,option->long_name,entry->arg); + else + fprintf(stderr,"[-%s,--%s]\n", + short_name,option->long_name); + } else + fprintf(stderr,"<program arg> := %s\n",entry->arg); + + fputs("\n\n",stderr); +} + +static struct argv_meta * argv_free_impl(struct argv_meta_impl * imeta) +{ + if (imeta->argv) + free(imeta->argv); + + if (imeta->strbuf) + free(imeta->strbuf); + + if (imeta->meta.entries) + free(imeta->meta.entries); + + free(imeta); + return 0; +} + +static struct argv_meta * argv_alloc(char ** argv, struct argv_ctx * ctx) +{ + struct argv_meta_impl * imeta; + char ** vector; + char * dst; + size_t size; + int argc; + int i; + + if (!(imeta = calloc(1,sizeof(*imeta)))) + return 0; + + if (ctx->flags & ARGV_CLONE_VECTOR) { + for (vector=argv,argc=0,size=0; *vector; vector++) { + size += strlen(*vector) + 1; + argc++; + } + + if (!(imeta->argv = calloc(argc+1,sizeof(char *)))) + return argv_free_impl(imeta); + else if (!(imeta->strbuf = calloc(1,size+1))) + return argv_free_impl(imeta); + + for (i=0,dst=imeta->strbuf; i<argc; i++) { + strcpy(dst,argv[i]); + imeta->argv[i] = dst; + dst += strlen(dst)+1; + } + + imeta->meta.argv = imeta->argv; + } else + imeta->meta.argv = argv; + + if (!(imeta->meta.entries = calloc( + ctx->nentries+1, + sizeof(struct argv_entry)))) + return argv_free_impl(imeta); + else + return &imeta->meta; +} + +static struct argv_meta * argv_get( + char * argv[], + const struct argv_option options[], + int flags) +{ + struct argv_meta * meta; + struct argv_ctx ctx = {flags,ARGV_MODE_SCAN,0,0,0,0,0,0,0}; + + argv_scan(argv,options,&ctx,0); + + if (ctx.errcode != ARGV_ERROR_OK) { + if (!ctx.program) + ctx.program = argv_program_name(argv[0]); + + if (ctx.flags & ARGV_VERBOSITY_ERRORS) + argv_show_error(&ctx); + + return 0; + } + + if (!(meta = argv_alloc(argv,&ctx))) + return 0; + + ctx.mode = ARGV_MODE_COPY; + argv_scan(meta->argv,options,&ctx,meta); + + if (ctx.errcode != ARGV_ERROR_OK) { + if (!ctx.program) + ctx.program = argv[0]; + + ctx.errcode = ARGV_ERROR_INTERNAL; + argv_show_error(&ctx); + argv_free(meta); + + return 0; + } + + if (ctx.flags & ARGV_VERBOSITY_STATUS) + argv_show_status(options,&ctx,meta); + + return meta; +} + +static void argv_free(struct argv_meta * xmeta) +{ + struct argv_meta_impl * imeta; + uintptr_t addr; + + if (xmeta) { + addr = (uintptr_t)xmeta - offsetof(struct argv_meta_impl,meta); + imeta = (struct argv_meta_impl *)addr; + argv_free_impl(imeta); + } +} + +static void argv_usage( + FILE * file, + const char * header, + const struct argv_option options[], + const char * mode) +{ + const struct argv_option * option; + bool fshort,flong; + bool fnewline; + size_t len,optlen; + size_t paralen,rparalen,mparalen; + size_t desclen,rdesclen; + + char * para; + char * next_para; + char * desc; + char * next_desc; + char * paradigm; + char * buf; + size_t buflen; + const char * sdescription; + const char * sargname; + + const char indent[] = " "; + const int rblen = sizeof("}") - sizeof(char); + const int rbblen = sizeof("{]") - sizeof(char); + const int brcklen= sizeof("[]") - sizeof(char); + const int solen = sizeof("-") - sizeof(char); + const int lolen = sizeof("--") - sizeof(char); + const int slolen = sizeof("-X,--") - sizeof(char); + + fshort = mode ? !strcmp(mode,"short") : 0; + flong = fshort ? 0 : mode && !strcmp(mode,"long"); + + if (header) + fprintf(stdout,"%s",header); + + optlen = 0; + paralen = 0; + + for (option=options; option->short_name || option->long_name; option++) { + if (fshort) + len = option->short_name ? sizeof(char) + solen : 0; + else if (flong) + len = option->long_name ? strlen(option->long_name) + lolen : 0; + else + len = option->long_name ? strlen(option->long_name) + slolen : 0; + + if (len) { + if (len > optlen) + optlen = len; + + if (option->argname) + len = strlen(option->argname); + else if (option->paradigm) + len = strlen(option->paradigm) + strlen("{}"); + else if (option->optarg != ARGV_OPTARG_NONE) + len = strlen("<val>"); + + if (option->optarg == ARGV_OPTARG_OPTIONAL) + len += strlen("[]"); + + if (len > paralen) + paralen = len; + } + } + + optlen += ARGV_TAB_WIDTH; + optlen &= (~(ARGV_TAB_WIDTH-1)); + + paradigm = next_para = buf = 0; + fnewline = false; + rparalen = 0; + mparalen = 0; + + if (paralen) { + paralen += (ARGV_TAB_WIDTH); + paralen &= (~(ARGV_TAB_WIDTH-1)); + mparalen = paralen + 2*rbblen; + + if (optlen + paralen > 64) + paralen = 32; + } + + /* account for ' ','\t', try to fit in 80 or 96 columns */ + if (optlen+paralen+2+ARGV_TAB_WIDTH < 80-32) + desclen = 80 - (optlen+paralen+2+ARGV_TAB_WIDTH); + else if (optlen+paralen+2+ARGV_TAB_WIDTH < 96-32) + desclen = 96 - (optlen+paralen+2+ARGV_TAB_WIDTH); + else + desclen = 32; + + buflen = 0; + rdesclen = 1; + + for (option=options; option->short_name || option->long_name; option++) { + if (fshort && !option->short_name) + continue; + else if (flong && !option->long_name) + continue; + + if (option->paradigm) { + if (option->optarg == ARGV_OPTARG_OPTIONAL) + rparalen = strlen(option->paradigm) - 2*rbblen; + else + rparalen = strlen(option->paradigm) - 2*rblen; + } + + sdescription = option->description ? option->description : ""; + sargname = option->argname ? option->argname : ""; + + if (option->paradigm) + rdesclen = snprintf(buf,buflen,sdescription,option->paradigm); + else + rdesclen = snprintf(buf,buflen,sdescription,sargname); + + if (fnewline) + (void)0; + + if ((rparalen > paralen) || (rdesclen > desclen)) { + if (!fnewline) { + (void)0; + fnewline = true; + } + } else + fnewline = false; + + if (fshort) + fprintf(file,"%s-%-*c",indent,(int)(optlen-solen),option->short_name); + else if (flong) + fprintf(file, + (option->flags & ARGV_OPTION_HYBRID_ONLY) + ? "%s -%-*s" + : "%s--%-*s", + indent,(int)(optlen-lolen),option->long_name); + else { + if (option->short_name && option->long_name) + fprintf(file, + (option->flags & ARGV_OPTION_HYBRID_ONLY) + ? "%s-%c, -%-*s" + : "%s-%c,--%-*s", + indent,option->short_name, + (int)(optlen-slolen),option->long_name); + else if (option->short_name) + fprintf(file,"%s-%-*c", + indent,(int)(optlen-solen),option->short_name); + else + fprintf(file, + (option->flags & ARGV_OPTION_HYBRID_ONLY) + ? "%s%3s -%-*s" + : "%s%3s--%-*s", + indent,"", + (int)(optlen-slolen),option->long_name); + } + + if (rdesclen > buflen) { + if (buf) { + free(buf); + buf = 0; + } + + len = rdesclen + 512; + len &= (~511); + + if ((buf = calloc(1,len))) { + buflen = len; + + if (option->paradigm) + rdesclen = snprintf(buf,buflen, + option->description, + option->paradigm); + else + rdesclen = snprintf(buf,buflen, + option->description, + option->argname); + } else { + buflen = 0; + continue; + } + } + + if (option->argname) { + if (option->optarg == ARGV_OPTARG_OPTIONAL) + fprintf(file,"[%s]%-*c", + option->argname, + (int)(paralen-strlen(option->argname)-brcklen),' '); + else + fprintf(file,"%s%-*c", + option->argname, + (int)(paralen-strlen(option->argname)),' '); + para = (char *)0; + } else if (option->paradigm && (rparalen <= paralen)) { + if (option->optarg == ARGV_OPTARG_OPTIONAL) + fprintf(file,"[{%s}]%-*c", + option->paradigm, + (int)(paralen-strlen(option->paradigm)-2*rbblen),' '); + else + fprintf(file,"{%s}%-*c", + option->paradigm, + (int)(paralen-strlen(option->paradigm)-rbblen),' '); + para = (char *)0; + } else if (option->paradigm) { + if (!paradigm && !(paradigm = calloc(1,mparalen))) { + fputc('\n',file); + continue; + } else + para = strcpy(paradigm,option->paradigm); + + if (option->optarg == ARGV_OPTARG_OPTIONAL) { + fputs("[{",file); + rparalen = paralen - rbblen; + } else { + fputc('{',file); + rparalen = paralen - rblen; + } + } else { + fprintf(file,"%-*c",(int)paralen,' '); + para = (char *)0; + } + + + if (!para && option->description && rdesclen <= desclen) { + fputc('\t',file); + fputs(buf,file); + desc = (char *)0; + } else if (option->description) + desc = buf; + else + desc = (char *)0; + + while (para || desc) { + if (para) { + next_para = para+rparalen-1; + + for (; (next_para>para) && (*next_para!='|'); ) + next_para--; + + if (para > paradigm) { + if (option->optarg == ARGV_OPTARG_OPTIONAL) + fputs(" ",file); + else + fputc(' ',file); + } + + if (*next_para != '|') { + fprintf(file,"%s",para); + para = (char *)0; + } else if (next_para > para) { + *next_para = '\0'; + fprintf(file,"%-*s",(int)rparalen,para); + *next_para = '|'; + para = next_para; + rparalen = strlen(para); + + /* 2*rbblen,2*rblen, etc.: account for indentation */ + if (option->optarg == ARGV_OPTARG_OPTIONAL) + rparalen = (rparalen+2*rbblen > paralen) + ? paralen-rbblen + : rparalen; + else + rparalen = (rparalen+2*rblen > paralen) + ? paralen-rblen + : rparalen; + } else { + if (option->optarg == ARGV_OPTARG_OPTIONAL) + fprintf(file,"%s}]%-*c",para, + (int)(paralen-strlen(para)-rbblen),' '); + else + fprintf(file,"%s}%-*c",para, + (int)(paralen-strlen(para)-rblen),' '); + para = (char *)0; + } + } else if (desc > buf) + fprintf(file,"%-*c",(int)paralen,' '); + + if (desc) { + if (desc > buf) + fputs("\t ",file); + else + fputc('\t',file); + + if ((rdesclen = strlen(desc)+(desc>buf)) <= desclen) { + fputs(desc,file); + desc = (char *)0; + } else { + next_desc = desc + desclen - 1; + + for (; (next_desc > desc) + && (*next_desc != ' ') + && (*next_desc != '\n'); ) + next_desc--; + + if ((*next_desc != ' ') && (*next_desc!='\n')) { + fputs(desc,file); + desc = (char *)0; + } else if (next_desc > desc) { + *next_desc = '\0'; + fputs(desc,file); + desc = ++next_desc; + } else { + fputs(desc,file); + desc = (char *)0; + } + } + } + + if (para || desc) + fprintf(file,"\n%s%-*c",indent,(int)optlen,' '); + } + + fputc('\n',file); + } + + if (paradigm) + free(paradigm); + + if (buf) + free(buf); +} + +#endif + +#endif diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h new file mode 100644 index 0000000..d8e3111 --- /dev/null +++ b/src/internal/slibtool_driver_impl.h @@ -0,0 +1,31 @@ +#ifndef SOFORT_DRIVER_IMPL_H +#define SOFORT_DRIVER_IMPL_H + +#include <stdint.h> +#include <stdio.h> +#include <sys/types.h> + +#include <slibtool/slibtool.h> +#include "argv/argv.h" + +extern int slibtool_main(int, char **, char **); +extern const struct argv_option slbt_default_options[]; + +enum app_tags { + TAG_HELP, + TAG_VERSION, +}; + +struct slbt_driver_ctx_impl { + struct slbt_common_ctx cctx; + struct slbt_driver_ctx ctx; +}; + +struct slbt_unit_ctx_impl { + const char * path; + struct slbt_input map; + struct slbt_common_ctx cctx; + struct slbt_unit_ctx uctx; +}; + +#endif diff --git a/src/logic/slbt_map_input.c b/src/logic/slbt_map_input.c new file mode 100644 index 0000000..2da2429 --- /dev/null +++ b/src/logic/slbt_map_input.c @@ -0,0 +1,51 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdint.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <slibtool/slibtool.h> + +int slbt_map_input( + int fd, + const char * path, + int prot, + struct slbt_input * map) +{ + struct stat st; + bool fnew; + int ret; + + if ((fnew = (fd < 0))) + fd = open(path,O_RDONLY | O_CLOEXEC); + + if (fd < 0) + return -1; + + if ((ret = fstat(fd,&st) < 0) && fnew) + close(fd); + + if (ret < 0) + return -1; + + map->size = st.st_size; + map->addr = mmap(0,map->size,prot,MAP_PRIVATE,fd,0); + + if (fnew) + close(fd); + + return (map->addr == MAP_FAILED) ? -1 : 0; +} + +int slbt_unmap_input(struct slbt_input * map) +{ + return munmap(map->addr,map->size); +} diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c new file mode 100644 index 0000000..644b6b9 --- /dev/null +++ b/src/skin/slbt_skin_default.c @@ -0,0 +1,12 @@ +#include "slibtool_driver_impl.h" +#include "argv/argv.h" + +const struct argv_option slbt_default_options[] = { + {"version", 'v',TAG_VERSION,ARGV_OPTARG_NONE,0,0,0, + "show version information"}, + + {"help", 'h',TAG_HELP,ARGV_OPTARG_OPTIONAL,0,"short|long",0, + "show usage information [listing %s options only]"}, + + {0,0,0,0,0,0,0,0} +}; diff --git a/src/slibtool.c b/src/slibtool.c new file mode 100644 index 0000000..6fb3422 --- /dev/null +++ b/src/slibtool.c @@ -0,0 +1,67 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdio.h> +#include <unistd.h> +#include <slibtool/slibtool.h> +#include "slibtool_version.h" +#include "slibtool_driver_impl.h" + +#ifndef SLBT_DRIVER_FLAGS +#define SLBT_DRIVER_FLAGS SLBT_DRIVER_VERBOSITY_ERRORS \ + | SLBT_DRIVER_VERBOSITY_USAGE +#endif + +static const char vermsg[] = "%s (git://midipix.org/slibtool): commit %s.\n"; + +static ssize_t slibtool_version(struct slbt_driver_ctx * dctx) +{ + return fprintf(stdout,vermsg,dctx->program,SLIBTOOL_GIT_VERSION); +} + +static void slibtool_perform_unit_actions(struct slbt_unit_ctx * uctx) +{ +} + +static int slibtool_exit(struct slbt_driver_ctx * dctx, int nerrors) +{ + slbt_free_driver_ctx(dctx); + return nerrors ? 2 : 0; +} + +int slibtool_main(int argc, char ** argv, char ** envp) +{ + int ret; + struct slbt_driver_ctx * dctx; + struct slbt_unit_ctx * uctx; + const char ** unit; + + if ((ret = slbt_get_driver_ctx(argv,envp,SLBT_DRIVER_FLAGS,&dctx))) + return (ret == SLBT_USAGE) ? !--argc : 2; + + if (dctx->cctx->drvflags & SLBT_DRIVER_VERSION) + if ((slibtool_version(dctx)) < 0) + return slibtool_exit(dctx,2); + + for (unit=dctx->units; *unit; unit++) { + if (!(slbt_get_unit_ctx(dctx,*unit,&uctx))) { + slibtool_perform_unit_actions(uctx); + ret += uctx->nerrors; + slbt_free_unit_ctx(uctx); + } + } + + return slibtool_exit(dctx,ret); +} + +#ifndef SLIBTOOL_IN_A_BOX + +int main(int argc, char ** argv, char ** envp) +{ + return slibtool_main(argc,argv,envp); +} + +#endif diff --git a/sysinfo/compiler/any-compiler.mk b/sysinfo/compiler/any-compiler.mk new file mode 100644 index 0000000..4c98621 --- /dev/null +++ b/sysinfo/compiler/any-compiler.mk @@ -0,0 +1,29 @@ +ifeq ($(CROSS_COMPILE)x,x) + CROSS_HOST = + CROSS_HOST_SPEC = +else + CROSS_HOST = + CROSS_HOST_SPEC = +endif + + +ifeq ($(USER_CC)x,x) + CC = $(NATIVE_CC) $(CROSS_HOST_SPEC) +else + CC = $(USER_CC) $(CROSS_HOST_SPEC) +endif + +ifeq ($(USER_CPP)x,x) + CPP = $(NATIVE_CC) $(CROSS_HOST_SPEC) -E +else + CPP = $(USER_CPP) $(CROSS_HOST_SPEC) -E +endif + +ifeq ($(USER_CXX)x,x) + CXX = $(NATIVE_CC) $(CROSS_HOST_SPEC) -std=c++ +else + CXX = $(USER_CXX) $(CROSS_HOST_SPEC) -std=c++ +endif + + +CFLAGS_PIC = -fPIC diff --git a/sysinfo/compiler/clang.mk b/sysinfo/compiler/clang.mk new file mode 100644 index 0000000..77b4b86 --- /dev/null +++ b/sysinfo/compiler/clang.mk @@ -0,0 +1,31 @@ +ifeq ($(CROSS_COMPILE)x,x) + CROSS_HOST = + CROSS_HOST_SPEC = +else ifeq ($(CROSS_HOST)x,x) + CROSS_HOST = $(HOST) + CROSS_HOST_SPEC = --target=$(HOST) +else + CROSS_HOST_SPEC = --target=$(CROSS_HOST) +endif + + +ifeq ($(USER_CC)x,x) + CC = $(NATIVE_CC) $(CROSS_HOST_SPEC) +else + CC = $(USER_CC) $(CROSS_HOST_SPEC) +endif + +ifeq ($(USER_CPP)x,x) + CPP = $(NATIVE_CC) $(CROSS_HOST_SPEC) -E +else + CPP = $(USER_CPP) $(CROSS_HOST_SPEC) -E +endif + +ifeq ($(USER_CXX)x,x) + CXX = $(NATIVE_CC)++ $(CROSS_HOST_SPEC) +else + CXX = $(USER_CXX) $(CROSS_HOST_SPEC) +endif + + +CFLAGS_PIC = -fPIC diff --git a/sysinfo/compiler/cparser.mk b/sysinfo/compiler/cparser.mk new file mode 100644 index 0000000..6c4dc8e --- /dev/null +++ b/sysinfo/compiler/cparser.mk @@ -0,0 +1,31 @@ +ifeq ($(CROSS_COMPILE)x,x) + CROSS_HOST = + CROSS_HOST_SPEC = +else ifeq ($(CROSS_HOST)x,x) + CROSS_HOST = $(HOST) + CROSS_HOST_SPEC = --target=$(HOST) +else + CROSS_HOST_SPEC = --target=$(CROSS_HOST) +endif + + +ifeq ($(USER_CC)x,x) + CC = $(NATIVE_CC) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp +else + CC = $(USER_CC) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp +endif + +ifeq ($(USER_CPP)x,x) + CPP = $(NATIVE_CC) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp -E +else + CPP = $(USER_CPP) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp -E +endif + +ifeq ($(USER_CXX)x,x) + CXX = $(NATIVE_CC) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp -std=c++ +else + CXX = $(USER_CXX) $(CROSS_HOST_SPEC) -Wno-experimental -integrated-cpp -std=c++ +endif + + +CFLAGS_PIC = -fPIC diff --git a/sysinfo/compiler/gcc.mk b/sysinfo/compiler/gcc.mk new file mode 100644 index 0000000..d14d8dc --- /dev/null +++ b/sysinfo/compiler/gcc.mk @@ -0,0 +1,24 @@ +ifeq ($(USER_CC)x,x) + ifeq ($(CROSS_COMPILE)x,x) + CC = $(CROSS_COMPILE)$(NATIVE_CC) + else + CC = $(CROSS_COMPILE)gcc + endif +else + CC = $(USER_CC) +endif + +ifeq ($(USER_CPP)x,x) + CPP = $(CROSS_COMPILE)cpp +else + CPP = $(USER_CPP) +endif + +ifeq ($(USER_CXX)x,x) + CXX = $(CROSS_COMPILE)c++ +else + CXX = $(USER_CXX) +endif + + +CFLAGS_PIC = -fPIC diff --git a/sysinfo/host/any-host.mk b/sysinfo/host/any-host.mk new file mode 100644 index 0000000..acb606a --- /dev/null +++ b/sysinfo/host/any-host.mk @@ -0,0 +1,7 @@ +include $(PROJECT_DIR)/sysinfo/os/any-os.mk + +ARCH = +HOST_BITS = +HOST_UNDERSCORE = + +CROSS_HOST = $(TARGET) diff --git a/sysinfo/host/host.sh b/sysinfo/host/host.sh new file mode 100755 index 0000000..e4079ee --- /dev/null +++ b/sysinfo/host/host.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +error_msg() +{ + echo $@ >&2 +} + +host_test() +{ + mb_hdrdir=$(pwd)/build + mkdir -p $mb_hdrdir || exit 2 + + if [ -z "$mb_compiler" ]; then + echo "config error: compiler not set." + exit 2 + fi + + $mb_compiler -dM -E - < /dev/null > /dev/null && return 0 + + error_msg "config error: invalid compiler." + exit 2 +} + +host_endian_h() +{ + mb_header='endian.h' + rm -f "$mb_hdrdir"/$mb_header + + # portable + printf "#include <$mb_header>" | $mb_compiler $mb_cflags \ + -E - > /dev/null 2>/dev/null \ + && return 0 + + # non-portable + mb_hosthdr= + + [ -z $mb_hosthdr ] && printf "#include <sys/$mb_header>" | $mb_compiler $mb_cflags \ + -E - > /dev/null 2>/dev/null \ + && mb_hosthdr='sys/'$mb_header + + [ -z $mb_hosthdr ] && printf "#include <machine/$mb_header>" | $mb_compiler $mb_cflags \ + -E - > /dev/null 2>/dev/null \ + && mb_hosthdr='machine/'$mb_header + + if [ -z "$mb_hosthdr" ]; then + error_msg "config error: could not find an alternate <$mb_header>." + exit 2 + fi + + printf "#include <%s>\\n" $mb_hosthdr > "$mb_hdrdir"/$mb_header || exit 2 +} + + +# one: args +for arg ; do + case "$arg" in + --help) usage + ;; + --compiler=*) + mb_compiler=${arg#*=} + ;; + --cflags=*) + mb_cflags=${arg#*=} + ;; + *) + error_msg ${arg#}: "unsupported config argument." + exit 2 + ;; + esac +done + + +# two: test +host_test + + +# three: headers +host_endian_h + + +# all done +exit 0 diff --git a/sysinfo/host/i686-nt32-midipix.mk b/sysinfo/host/i686-nt32-midipix.mk new file mode 100644 index 0000000..fd4b8f8 --- /dev/null +++ b/sysinfo/host/i686-nt32-midipix.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/midipix.mk + +ARCH = nt32 +HOST_BITS = 32 +HOST_UNDERSCORE = '_' diff --git a/sysinfo/host/i686-unknown-linux.mk b/sysinfo/host/i686-unknown-linux.mk new file mode 100644 index 0000000..bec437c --- /dev/null +++ b/sysinfo/host/i686-unknown-linux.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/linux.mk + +ARCH = i386 +HOST_BITS = 32 +HOST_UNDERSCORE = '_' diff --git a/sysinfo/host/i686-w64-mingw32.mk b/sysinfo/host/i686-w64-mingw32.mk new file mode 100644 index 0000000..b18e2e3 --- /dev/null +++ b/sysinfo/host/i686-w64-mingw32.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/mingw.mk + +ARCH = w32 +HOST_BITS = 32 +HOST_UNDERSCORE = '_' diff --git a/sysinfo/host/native.mk b/sysinfo/host/native.mk new file mode 100644 index 0000000..f0cf720 --- /dev/null +++ b/sysinfo/host/native.mk @@ -0,0 +1,45 @@ +include $(PROJECT_DIR)/sysinfo/os/$(NATIVE_OS).mk + +OS = $(NATIVE_OS) +HOST_BITS = $(NATIVE_OS_BITS) +HOST_UNDERSCORE = $(NATIVE_OS_UNDERSCORE) + +ifeq ($(OS),linux) + ifeq ($(HOST_BITS),32) + ARCH = i386 + else ifeq ($(HOST_BITS),64) + ARCH = x86_64 + endif +endif + +ifeq ($(OS),midipix) + ifeq ($(HOST_BITS),32) + ARCH = nt32 + else ifeq ($(HOST_BITS),64) + ARCH = nt64 + endif +endif + +ifeq ($(OS),mingw) + ifeq ($(HOST_BITS),32) + ARCH = w32 + else ifeq ($(HOST_BITS),64) + ARCH = w64 + endif +endif + +ifeq ($(OS),bsd) + ifeq ($(HOST_BITS),32) + ARCH = bsd32 + else ifeq ($(HOST_BITS),64) + ARCH = bsd64 + endif +endif + +ifeq ($(OS),darwin) + ifeq ($(HOST_BITS),32) + ARCH = dw32 + else ifeq ($(HOST_BITS),64) + ARCH = dw64 + endif +endif diff --git a/sysinfo/host/x86_64-nt64-midipix.mk b/sysinfo/host/x86_64-nt64-midipix.mk new file mode 100644 index 0000000..d0e1d52 --- /dev/null +++ b/sysinfo/host/x86_64-nt64-midipix.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/midipix.mk + +ARCH = nt64 +HOST_BITS = 64 +HOST_UNDERSCORE = '' diff --git a/sysinfo/host/x86_64-unknown-linux.mk b/sysinfo/host/x86_64-unknown-linux.mk new file mode 100644 index 0000000..4bd1bff --- /dev/null +++ b/sysinfo/host/x86_64-unknown-linux.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/linux.mk + +ARCH = x86_64 +HOST_BITS = 64 +HOST_UNDERSCORE = '' diff --git a/sysinfo/host/x86_64-w64-mingw32.mk b/sysinfo/host/x86_64-w64-mingw32.mk new file mode 100644 index 0000000..a86f9b0 --- /dev/null +++ b/sysinfo/host/x86_64-w64-mingw32.mk @@ -0,0 +1,5 @@ +include $(PROJECT_DIR)/sysinfo/os/mingw.mk + +ARCH = w64 +HOST_BITS = 64 +HOST_UNDERSCORE = '' diff --git a/sysinfo/os/any-os.mk b/sysinfo/os/any-os.mk new file mode 100644 index 0000000..0aa0a75 --- /dev/null +++ b/sysinfo/os/any-os.mk @@ -0,0 +1,10 @@ +OS = any-os +OS_APP_PREFIX = +OS_APP_SUFFIX = +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .so +OS_IMPLIB_EXT = .invalid +OS_LIBDEF_EXT = .invalid +OS_ARCHIVE_EXT = .a + +.PHONY: $(SHARED_IMPLIB) diff --git a/sysinfo/os/bsd.mk b/sysinfo/os/bsd.mk new file mode 100644 index 0000000..1b29c90 --- /dev/null +++ b/sysinfo/os/bsd.mk @@ -0,0 +1,10 @@ +OS = bsd +OS_APP_PREFIX = +OS_APP_SUFFIX = +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .so +OS_IMPLIB_EXT = .invalid +OS_LIBDEF_EXT = .invalid +OS_ARCHIVE_EXT = .a + +.PHONY: $(SHARED_IMPLIB) diff --git a/sysinfo/os/darwin.mk b/sysinfo/os/darwin.mk new file mode 100644 index 0000000..f16b1f1 --- /dev/null +++ b/sysinfo/os/darwin.mk @@ -0,0 +1,12 @@ +OS = darwin +OS_APP_PREFIX = +OS_APP_SUFFIX = +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .dylib +OS_IMPLIB_EXT = .invalid +OS_LIBDEF_EXT = .invalid +OS_ARCHIVE_EXT = .a + +CFLAGS_OS += -D_DARWIN_C_SOURCE + +.PHONY: $(SHARED_IMPLIB) diff --git a/sysinfo/os/linux.mk b/sysinfo/os/linux.mk new file mode 100644 index 0000000..2bd6329 --- /dev/null +++ b/sysinfo/os/linux.mk @@ -0,0 +1,10 @@ +OS = linux +OS_APP_PREFIX = +OS_APP_SUFFIX = +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .so +OS_IMPLIB_EXT = .invalid +OS_LIBDEF_EXT = .invalid +OS_ARCHIVE_EXT = .a + +.PHONY: $(SHARED_IMPLIB) diff --git a/sysinfo/os/midipix.mk b/sysinfo/os/midipix.mk new file mode 100644 index 0000000..715dbcd --- /dev/null +++ b/sysinfo/os/midipix.mk @@ -0,0 +1,14 @@ +OS = midipix +OS_APP_PREFIX = +OS_APP_SUFFIX = +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .so +OS_IMPLIB_EXT = .lib.a +OS_LIBDEF_EXT = .so.def +OS_ARCHIVE_EXT = .a + +LDFLAGS_CONFIG += -mout-implib + +install-implib: shared-implib + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + cp $(SHARED_IMPLIB) $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) diff --git a/sysinfo/os/mingw.mk b/sysinfo/os/mingw.mk new file mode 100644 index 0000000..6fbc76d --- /dev/null +++ b/sysinfo/os/mingw.mk @@ -0,0 +1,15 @@ +OS = mingw +OS_APP_PREFIX = +OS_APP_SUFFIX = .exe +OS_LIB_PREFIX = lib +OS_LIB_SUFFIX = .dll +OS_IMPLIB_EXT = .dll.a +OS_LIBDEF_EXT = .def +OS_ARCHIVE_EXT = .a + +CFLAGS_PIC = +LDFLAGS_CONFIG += -Wl,--out-implib,$(SHARED_IMPLIB) + +install-implib: shared-implib + mkdir -p $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) + cp $(SHARED_IMPLIB) $(DESTDIR)///./$(PREFIX)/./$(LIBDIR) diff --git a/sysinfo/toolchain/binutils.mk b/sysinfo/toolchain/binutils.mk new file mode 100644 index 0000000..a29ac0c --- /dev/null +++ b/sysinfo/toolchain/binutils.mk @@ -0,0 +1,17 @@ +AS = $(CROSS_COMPILE)as +AR = $(CROSS_COMPILE)ar +LD = $(CROSS_COMPILE)ld +NM = $(CROSS_COMPILE)nm +OBJDUMP = $(CROSS_COMPILE)objdump +RANLIB = $(CROSS_COMPILE)ranlib +SIZE = $(CROSS_COMPILE)size +STRIP = $(CROSS_COMPILE)strip +STRINGS = $(CROSS_COMPILE)strings + + +ADDR2LINE = $(CROSS_COMPILE)addr2line +COV = $(CROSS_COMPILE)gcov +CXXFILT = $(CROSS_COMPILE)c++filt +ELFEDIT = $(CROSS_COMPILE)elfedit +OBJCOPY = $(CROSS_COMPILE)objcopy +READELF = $(CROSS_COMPILE)readelf diff --git a/sysinfo/toolchain/llvm.mk b/sysinfo/toolchain/llvm.mk new file mode 100644 index 0000000..3c805a8 --- /dev/null +++ b/sysinfo/toolchain/llvm.mk @@ -0,0 +1,17 @@ +AS = llvm-mc -filetype=obj +AR = llvm-ar +LD = lld +NM = llvm-nm +OBJDUMP = llvm-objdump +RANLIB = llvm-ranlib +SIZE = llvm-size +STRIP = $(CROSS_COMPILE)strip +STRINGS = $(CROSS_COMPILE)strings + + +ADDR2LINE = $(CROSS_COMPILE)addr2line +COV = $(CROSS_COMPILE)gcov +CXXFILT = $(CROSS_COMPILE)c++filt +ELFEDIT = $(CROSS_COMPILE)elfedit +OBJCOPY = $(CROSS_COMPILE)objcopy +READELF = $(CROSS_COMPILE)readelf diff --git a/sysinfo/version.sh b/sysinfo/version.sh new file mode 100755 index 0000000..8157765 --- /dev/null +++ b/sysinfo/version.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +usage() +{ +cat << EOF >&2 + +Usage: + -h show this HELP message + -s SRCDIR set source directory + -o OUTPUT set output header + -p PREFIX set macro prefix + +EOF +exit 1 +} + + +# one +workdir=$(pwd) +srcdir= +output= +prefix= + + +while getopts "hs:o:p:" opt; do + case $opt in + h) + usage + ;; + s) + srcdir="$OPTARG" + ;; + o) + output="$OPTARG" + ;; + p) + prefix="$OPTARG" + ;; + \?) + printf "Invalid option: -%s" "$OPTARG" >&2 + usage + ;; + esac +done + + +# two +if [ -z "$srcdir" ] || [ -z "$output" ] || [ -z "$prefix" ]; then + usage +fi + +cd "$srcdir" || exit 2 + +gitver=`git rev-parse --verify HEAD 2>/dev/null` || gitver="unknown" +macro=`echo "$prefix"_GIT_VERSION | tr '[:lower:]' '[:upper:]'` + +cd "$workdir" || exit 2 +printf "#define $macro\t\"$gitver\"\n" > "$output" + +# all done +exit 0 |