diff --git a/COPYING.NTUX b/COPYING.NTUX new file mode 100644 index 0000000..d1c00a1 --- /dev/null +++ b/COPYING.NTUX @@ -0,0 +1,20 @@ +/*****************************************************************************/ +/* */ +/* ntux: native translation und extension */ +/* */ +/* Copyright (C) 2016 Z. Gilboa */ +/* */ +/* This program is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 2 of the License, or */ +/* (at your option) version 3 of the License. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program. If not, see . */ +/* */ +/*****************************************************************************/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0f7be6e --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ + ntux: native translation und extension + -------------------------------------- + + Copyright (C) 2016 Z. Gilboa + + This library is currently released under the GPLv2 and GPLv3 (see + COPYING.NTUX for the relevant text). If you wish to use this + library with a different license, please contact the author + at and briefly describe the type + of license (or license exception) that you would like to obtain. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..73fd9b4 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,399 @@ +PACKAGE = @package@ +NICKNAME = @nickname@ +PROJECT_DIR = @project_dir@ +SOURCE_DIR = @source_dir@ +GIT_REFERENCE_INDEX = @git_reference_index@ +CUSTOM_INSTALL_HEADERS = @custom_install_headers@ +AVOID_VERSION = @avoid_version@ + +BUILD = @build@ +HOST = @host@ +TARGET = @target@ +ARCH = @arch@ +COMPILER = @compiler@ +TOOLCHAIN = @toolchain@ +SYSROOT = @sysroot@ +CROSS_COMPILE = @cross_compile@ +SHELL = @shell@ + +CFLAGS_COMMON = @cflags_common@ +CFLAGS_DEBUG = @cflags_debug@ +CFLAGS_CMDLINE = @cflags_cmdline@ +CFLAGS_CONFIG = @cflags_config@ +CFLAGS_SYSROOT = @cflags_sysroot@ +CFLAGS_OS = @cflags_os@ +CFLAGS_SITE = @cflags_site@ +CFLAGS_PATH = @cflags_path@ +CFLAGS_STRICT = @cflags_strict@ +CFLAGS_UTIL = @cflags_util@ +CFLAGS_LAST = @cflags_last@ +CFLAGS_ONCE = @cflags_once@ + +LDFLAGS_COMMON = @ldflags_common@ +LDFLAGS_DEBUG = @ldflags_debug@ +LDFLAGS_CMDLINE = @ldflags_cmdline@ +LDFLAGS_CONFIG = @ldflags_config@ +LDFLAGS_SYSROOT = @ldflags_sysroot@ +LDFLAGS_PATH = @ldflags_path@ +LDFLAGS_STRICT = @ldflags_strict@ +LDFLAGS_UTIL = @ldflags_util@ +LDFLAGS_LAST = @ldflags_last@ +LDFLAGS_ONCE = @ldflags_once@ + +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@ +EXEC_PREFIX = @exec_prefix@ +BINDIR = @bindir@ +LIBDIR = @libdir@ +INCLUDEDIR = @includedir@ +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_SHARED = @all_shared@ +ALL_STATIC = @all_static@ +DISABLE_FRONTEND = @disable_frontend@ +DISABLE_SHARED = @disable_shared@ +DISABLE_STATIC = @disable_static@ + +all: +install: +shared: +static: + +install-extras: +install-app-extras: + +include $(PROJECT_DIR)/sysinfo/host/$(HOST).mk +include $(PROJECT_DIR)/sysinfo/compiler/$(COMPILER).mk +include $(PROJECT_DIR)/sysinfo/toolchain/$(TOOLCHAIN).mk +include $(PROJECT_DIR)/sysinfo/os/$(OS).mk + +include $(PROJECT_DIR)/project/osforce.mk + +include $(PROJECT_DIR)/sofort/defs.mk +include $(PROJECT_DIR)/sofort/version.mk +include $(PROJECT_DIR)/sofort/custom.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): CFLAGS_STATIC = $(CFLAGS_APP) + +src/%.lo: $(SOURCE_DIR)/src/%.c $(ALL_HEADERS) host.tag tree.tag + $(CC) -c -o $@ $< $(CFLAGS_SHARED) + +src/%.o: $(SOURCE_DIR)/src/%.c $(ALL_HEADERS) host.tag tree.tag + $(CC) -c -o $@ $< $(CFLAGS_STATIC) + +lib/%$(OS_LIB_SUFFIX)$(VER_XYZ): + $(CC) -shared -o $@ $^ $(LDFLAGS_SHARED) + +lib/%$(OS_ARCHIVE_EXT): + rm -f $@ + $(AR) rcs $@ $^ + + + +all: package-shared package-static app + +install: package-install-app +install: package-install-extras +install: install-libs + +app: app-tag + +app.tag: + cp $(PACKAGE_APP) $(APP) + touch app.tag + +install-libs: package-install-shared +install-libs: package-install-static + +install-headers-default: + mkdir -p $(DESTDIR)$(INCLUDEDIR)/$(PACKAGE) + cp $(API_HEADERS) $(DESTDIR)$(INCLUDEDIR)/$(PACKAGE) + +install-shared: shared install-lib install-implib +install-shared: package-install-soname package-install-solink +install-shared: install-headers + +install-lib: shared + mkdir -p $(DESTDIR)$(LIBDIR) + cp $(SHARED_LIB) $(DESTDIR)$(LIBDIR) + +install-static: static install-headers + mkdir -p $(DESTDIR)$(LIBDIR) + cp $(STATIC_LIB) $(DESTDIR)$(LIBDIR) + +install-app: app install-app-extras + mkdir -p $(DESTDIR)$(BINDIR) + cp $(APP) $(DESTDIR)$(BINDIR) + +install-static-app: static-app install-app-extras + mkdir -p $(DESTDIR)$(BINDIR) + cp $(STATIC_APP) $(DESTDIR)$(BINDIR)/$(NICKNAME)$(OS_APP_SUFFIX) + + + +shared: shared-lib implib +shared: package-shared-soname package-shared-solink + +static: static-lib + +shared-lib: shared-objs $(SHARED_LIB) + +shared-soname: shared-lib $(SHARED_SONAME) + +shared-solink: shared-lib $(SHARED_SOLINK) + +static-lib: static-objs $(STATIC_LIB) + + + +default-app: version.tag static-objs $(DEFAULT_APP) + +shared-app: version.tag shared $(SHARED_APP) + +static-app: version.tag static-objs $(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): $(PACKAGE_APP) + +$(DEFAULT_APP): $(STATIC_OBJS) $(APP_OBJS) + rm -f app.tag + $(CC) -o $@ $^ $(LDFLAGS_APP) + +$(SHARED_APP): $(SHARED_LIB) $(APP_OBJS) + rm -f app.tag + $(CC) -o $@ $(APP_OBJS) -l$(PACKAGE) $(LDFLAGS_SHARED) + +$(STATIC_APP): $(STATIC_OBJS) $(APP_OBJS) + rm -f app.tag + $(CC) -static -o $@ $^ $(LDFLAGS_STATIC) + + +dirs: dirs.tag + +dirs.tag: + mkdir -p bin + mkdir -p lib + touch dirs.tag + +host.tag: Makefile + $(PROJECT_DIR)/sysinfo/host/host.sh --compiler="$(CC)" --cflags="$(CFLAGS)" + touch host.tag + +version.tag: $(GIT_REFERENCE_INDEX) + $(PROJECT_DIR)/sysinfo/version.sh \ + -s $(SOURCE_DIR) \ + -o build/$(PACKAGE)_version.h \ + -p $(PACKAGE) + touch version.tag + +distclean: clean + rm -f Makefile + +clean: clean-implib + rm -f tree.tag + rm -f dirs.tag + rm -f host.tag + rm -f version.tag + rm -f app.tag + rm -f $(SHARED_OBJS) + rm -f $(STATIC_OBJS) + rm -f $(APP_OBJS) + rm -f $(SHARED_LIB) + rm -f $(SHARED_SONAME) + rm -f $(SHARED_SOLINK) + rm -f $(STATIC_LIB) + 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-config + +.conf: PAGER ?= less +.conf: + $(MAKE) .display | $(PAGER) + +.display-project: + @echo PACKAGE:' '$(PACKAGE) + @echo NICKNAME:' '$(NICKNAME) + @echo PROJECT_DIR:' '$(PROJECT_DIR) + @echo SOURCE_DIR:' '$(SOURCE_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_COMMON:' '$(CFLAGS_COMMON) + @echo CFLAGS_DEBUG:' '$(CFLAGS_DEBUG) + @echo CFLAGS_VERSION:' '$(CFLAGS_VERSION) + @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 CFLAGS_STRICT:' '$(CFLAGS_STRICT) + @echo CFLAGS_UTIL:' '$(CFLAGS_UTIL) + @echo CFLAGS_LAST:' '$(CFLAGS_LAST) + @echo CFLAGS_ONCE:' '$(CFLAGS_ONCE) + @echo + @echo LDFLAGS_COMMON:' '$(LDFLAGS_COMMON) + @echo LDFLAGS_DEBUG:' '$(LDFLAGS_DEBUG) + @echo LDFLAGS_CMDLINE:' '$(LDFLAGS_CMDLINE) + @echo LDFLAGS_CONFIG:' '$(LDFLAGS_CONFIG) + @echo LDFLAGS_SYSROOT:' '$(LDFLAGS_SYSROOT) + @echo LDFLAGS_PATH:' '$(LDFLAGS_PATH) + @echo LDFLAGS_STRICT:' '$(LDFLAGS_STRICT) + @echo LDFLAGS_UTIL:' '$(LDFLAGS_UTIL) + @echo LDFLAGS_LAST:' '$(LDFLAGS_LAST) + @echo LDFLAGS_ONCE:' '$(LDFLAGS_ONCE) + @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 EXEC_PREFIX:' '$(EXEC_PREFIX) + @echo BINDIR:' '$(BINDIR) + @echo LIBDIR:' '$(LIBDIR) + @echo INCLUDEDIR:' '$(INCLUDEDIR) + @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 + +.display-config: + @echo ALL_SHARED:' '$(ALL_SHARED) + @echo ALL_STATIC:' '$(ALL_STATIC) + @echo DISABLE_FRONTEND:' '$(DISABLE_FRONTEND) + @echo DISABLE_SHARED:' '$(DISABLE_SHARED) + @echo DISABLE_STATIC:' '$(DISABLE_STATIC) + +.display-host: + @$(CC) $(CFLAGS) -dumpmachine + +.display-cc: + @echo $(CC) + +.display-cflags: + @echo $(CFLAGS) + + +.PHONY: all install shared static app \ + package-app \ + shared-objs shared-lib \ + shared-soname shared-solink \ + package-shared-soname package-shared-solink \ + static-objs static-lib \ + default-app shared-app static-app \ + install-shared install-static \ + install-soname install-solink \ + package-install-soname package-install-solink \ + install-headers install-app \ + install-headers-default install-headers-custom \ + clean distclean clean-implib version \ + .display .conf \ + .display-project .display-env .display-tools .display-flags \ + .display-pe .display-elf .display-dirs .display-build \ + implib implib-ver implib-soname implib-solink \ + install-implib install-implib-ver \ + install-implib-soname install-implib-solink diff --git a/config.project b/config.project new file mode 100644 index 0000000..5eaef9c --- /dev/null +++ b/config.project @@ -0,0 +1,62 @@ +# project +mb_package=ntux +mb_require_out_of_tree=no +mb_custom_install_headers=no +mb_avoid_version=no + + +# 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_common="-std=c99 -D_XOPEN_SOURCE=700" +mb_default_cflags_common="$mb_default_cflags_common -I\$(PROJECT_DIR)/src/internal" +mb_default_cflags_common="$mb_default_cflags_common -I\$(PROJECT_DIR)/src/internal/nolibc" +mb_default_cflags_common="$mb_default_cflags_common -I\$(PROJECT_DIR)/include" +mb_default_cflags_common="$mb_default_cflags_common -Ibuild" + +mb_default_cflags_debug= +mb_default_cflags_cmdline= +mb_default_cflags_config= +mb_default_cflags_sysroot= +mb_default_cflags_path= +mb_default_cflags_strict= +mb_default_cflags_util= +mb_default_cflags_last= +mb_default_cflags_once= + +mb_default_ldflags_common="-Llib" +mb_default_ldflags_debug= +mb_default_ldflags_cmdline= +mb_default_ldflags_config= +mb_default_ldflags_sysroot= +mb_default_ldflags_path= +mb_default_ldflags_strict= +mb_default_ldflags_util= +mb_default_ldflags_last= +mb_default_ldflags_once= + +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= + + +# config +mb_all_static=yes +mb_all_shared= +mb_disable_frontend= +mb_disable_static=yes +mb_disable_shared=yes diff --git a/config.usage b/config.usage new file mode 100644 index 0000000..4a351e4 --- /dev/null +++ b/config.usage @@ -0,0 +1,111 @@ +configure: a skinny configuration script. + +supported switches: +------------------- + --help + + --nickname + --avoid-version + --source-dir + + --prefix + --exec-prefix + --bindir + --libdir + --includedir + --mandir + --docdir + --libexecdir + + --build + --host + --target + --arch + --compiler + --toolchain + --sysroot + --cross-compile + --shell + --debug + + --strict + --ccstrict + --ldstrict + + --all-static + --all-shared + --enable-static + --enable-shared + --disable-static + --disable-shared + + --enable-app + --enable-frontend + --disable-app + --disable-frontend + + +supported variables: +-------------------- + NICKNAME + SOURCE_DIR + + PREFIX + EXEC_PREFIX + BINDIR + LIBDIR + INCLUDEDIR + 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 + CFLAGS_STRICT + CFLAGS_UTIL + CFLAGS_LAST + CFLAGS_ONCE + + LDFLAGS + LDFLAGS_DEBUG + LDFLAGS_COMMON + LDFLAGS_CMDLINE + LDFLAGS_CONFIG + LDFLAGS_SYSROOT + LDFLAGS_PATH + LDFLAGS_STRICT + LDFLAGS_UTIL + LDFLAGS_LAST + LDFLAGS_ONCE + + 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..1c326f7 --- /dev/null +++ b/configure @@ -0,0 +1,668 @@ +#!/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 +} + +warning_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 + + # project + mb_nickname=$NICKNAME + mb_source_dir=$SOURCE_DIR + + # dirs + mb_prefix=$PREFIX + mb_exec_prefix=$EXEC_PREFIX + mb_bindir=$BINDIR + mb_libdir=$LIBDIR + mb_includedir=$INCLUDEDIR + 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_cflags_strict=$CFLAGS_STRICT + mb_cflags_util=$CFLAGS_UTIL + mb_cflags_last=$CFLAGS_LAST + mb_cflags_once=$CFLAGS_ONCE + + 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_ldflags_strict=$LDFLAGS_STRICT + mb_ldflags_util=$LDFLAGS_UTIL + mb_ldflags_last=$LDFLAGS_LAST + mb_ldflags_once=$LDFLAGS_ONCE + + 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 +} + + +verify_source_directory() +{ + if [ -z "$mb_source_dir" ]; then + if [ "$mb_require_source_dir" = yes ]; then + error_msg "$mb_package: specifying an external source directory is required." + error_msg "you can set the source directory either via --source-dir=," + error_msg "or by setting the SOURCE_DIR variable." + exit 2 + fi + fi +} + + +common_defaults() +{ + # git + if [ -n "$mb_source_dir" ]; then + if [ -d "$mb_source_dir/.git" ]; then + mb_git_reference_index="\$(SOURCE_DIR)/.git/index" + fi + elif [ -d "$mb_project_dir/.git" ]; then + mb_git_reference_index="\$(PROJECT_DIR)/.git/index" + fi + + # project + [ -z "$mb_nickname" ] && mb_nickname=$mb_package + [ -z "$mb_source_dir" ] && mb_source_dir=$mb_project_dir + [ -z "$mb_avoid_version" ] && mb_avoid_version='no' + + # dirs + [ -z "$mb_prefix" ] && [ -z "$mb_prefix_set" ] \ + && mb_prefix='/usr/local' + + [ -z "$mb_exec_prefix" ] && [ -z "$mb_exec_prefix_set" ] \ + && mb_exec_prefix=$mb_prefix + + [ -z "$mb_bindir" ] && mb_bindir=$mb_exec_prefix/bin + [ -z "$mb_libdir" ] && mb_libdir=$mb_exec_prefix/lib + [ -z "$mb_includedir" ] && mb_includedir=$mb_prefix/include + [ -z "$mb_datarootdir" ] && mb_datarootdir=$mb_prefix/share + [ -z "$mb_mandir" ] && mb_mandir=$mb_datarootdir/man + [ -z "$mb_docdir" ] && mb_docdir=$mb_datarootdir/doc + [ -z "$mb_libexecdir" ] && mb_libexecdir=$mb_exec_prefix/libexec + + # 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_cflags_strict" ] && mb_cflags_strict=$mb_default_cflags_strict + [ -z "$mb_cflags_util" ] && mb_cflags_util=$mb_default_cflags_util + [ -z "$mb_cflags_last" ] && mb_cflags_last=$mb_default_cflags_last + [ -z "$mb_cflags_once" ] && mb_cflags_once=$mb_default_cflags_once + + [ -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_ldflags_strict" ] && mb_ldflags_strict=$mb_default_ldflags_strict + [ -z "$mb_ldflags_util" ] && mb_ldflags_util=$mb_default_ldflags_util + [ -z "$mb_ldflags_last" ] && mb_ldflags_last=$mb_default_ldflags_last + [ -z "$mb_ldflags_once" ] && mb_ldflags_once=$mb_default_ldflags_once + + [ -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 + + # config + [ -z "$mb_all_static" ] && mb_all_static='no' + [ -z "$mb_all_shared" ] && mb_all_shared='no' + [ -z "$mb_disable_frontend" ] && mb_disable_frontend='no' + [ -z "$mb_disable_static" ] && mb_disable_static='no' + [ -z "$mb_disable_shared" ] && mb_disable_shared='no' + + # 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="--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 -q '__clang__' && mb_compiler='clang' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep -q '__GCC' && mb_compiler='gcc' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep -q "^gcc" && mb_compiler='gcc' + fi + + if [ -z "$mb_compiler" ]; then + $mb_native_cc -dM -E - < /dev/null | grep -q '__CPARSER__' && 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 + if [ -z "$mb_native_os" ]; then + mb_native_os=`uname | tr '[:upper:]' '[:lower:]'` + fi + + mb_native_os_sizeof_pointer=`$mb_native_cc -dM -E - < /dev/null \ + | awk '$2 == "__SIZEOF_POINTER__" { print $3 }'` + + mb_native_os_bits=$((8 * ${mb_native_os_sizeof_pointer:-0})) + + 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 + warning_msg "config error: could not determine size of pointer on native system." + fi + + # grumpily support crooked uname output + if ! [ -f $mb_project_dir/sysinfo/os/$mb_native_os.mk ]; then + mb_native_os=`echo $mb_native_os | cut -d'_' -f1` + fi + + # fallback os recipe + if ! [ -f $mb_project_dir/sysinfo/os/$mb_native_os.mk ]; then + mb_native_os='any-os'; + fi +} + + +cross_defaults() +{ + if [ -z "$mb_cross_compile" ] && [ "$mb_host" != native ]; then + mb_cross_compile=$mb_host'-' + fi +} + + +config_flags() +{ + mb_ldflags_tmp=" $mb_ldflags " + mb_ldflags_libs=`echo "$mb_ldflags_tmp" | sed 's/ -static / /g'` + + if [ "$mb_ldflags_tmp" != "$mb_ldflags_libs" ]; then + mb_ldflags="$mb_ldflags_libs" + mb_ldflags_util="$mb_ldflags_util -static" + fi + + # ccstrict + if [ "$mb_ccstrict" = 'yes' ]; then + mb_cflags_strict='-Wall -Werror -Wextra -Wundef' + fi + + # ldstrict + if [ "$mb_ldstrict" = 'yes' ]; then + mb_ldflags_strict='-Wl,--no-undefined' + fi +} + + +config_copy() +{ + sed -e 's^@package@^'"$mb_package"'^g' \ + -e 's^@nickname@^'"$mb_nickname"'^g' \ + -e 's^@project_dir@^'"$mb_project_dir"'^g' \ + -e 's^@source_dir@^'"$mb_source_dir"'^g' \ + -e 's^@git_reference_index@^'"$mb_git_reference_index"'^g' \ + -e 's^@custom_install_headers@^'"$mb_custom_install_headers"'^g' \ + -e 's^@avoid_version@^'"$mb_avoid_version"'^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^@cflags_strict@^'"$mb_cflags_strict"'^g' \ + -e 's^@cflags_util@^'"$mb_cflags_util"'^g' \ + -e 's^@cflags_last@^'"$mb_cflags_last"'^g' \ + -e 's^@cflags_once@^'"$mb_cflags_once"'^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^@ldflags_strict@^'"$mb_ldflags_strict"'^g' \ + -e 's^@ldflags_util@^'"$mb_ldflags_util"'^g' \ + -e 's^@ldflags_last@^'"$mb_ldflags_last"'^g' \ + -e 's^@ldflags_once@^'"$mb_ldflags_once"'^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^@exec_prefix@^'"$mb_exec_prefix"'^g' \ + -e 's^@bindir@^'"$mb_bindir"'^g' \ + -e 's^@libdir@^'"$mb_libdir"'^g' \ + -e 's^@includedir@^'"$mb_includedir"'^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' \ + \ + -e 's^@all_static@^'"$mb_all_static"'^g' \ + -e 's^@all_shared@^'"$mb_all_shared"'^g' \ + -e 's^@disable_frontend@^'"$mb_disable_frontend"'^g' \ + -e 's^@disable_static@^'"$mb_disable_static"'^g' \ + -e 's^@disable_shared@^'"$mb_disable_shared"'^g' \ + $mb_project_dir/Makefile.in > $mb_pwd/Makefile +} + + +config_support() +{ + [ "$mb_disable_shared" = 'yes' ] && return 0 + + mbt_cc=`make .display-cc` + mbt_cflags=`make .display-cflags` + mbt_source='int foo(int x){return ++x;}' + mbt_result='no' + + rm -f a.out + echo "$mbt_source" | "$mbt_cc" -shared -o a.out -xc - + stat a.out >/dev/null 2>&1 && mbt_result='yes' + rm -f a.out + + if [ "$mbt_result" = 'no' ]; then + mb_disable_shared='yes' + config_copy + fi +} + + +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_set=yes + mb_prefix=${arg#*=} + ;; + --exec-prefix=*) + mb_exec_prefix_set=yes + mb_exec_prefix=${arg#*=} + ;; + --bindir=*) + mb_bindir=${arg#*=} + ;; + --libdir=*) + mb_libdir=${arg#*=} + ;; + --includedir=*) + mb_includedir=${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' + ;; + + # config + --all-static) + mb_all_static='yes' + ;; + --all-shared) + mb_all_shared='yes' + ;; + --disable-frontend) + mb_disable_frontend='yes' + ;; + --disable-app) + mb_disable_frontend='yes' + ;; + --enable-frontend) + mb_disable_frontend='no' + ;; + --enable-app) + mb_disable_frontend='no' + ;; + --disable-static) + mb_disable_static='yes' + ;; + --disable-shared) + mb_disable_shared='yes' + ;; + --enable-static) + mb_disable_static='no' + ;; + --enable-shared) + mb_disable_shared='no' + ;; + + # convenience + --strict) + mb_ccstrict='yes' + mb_ldstrict='yes' + ;; + --ccstrict) + mb_ccstrict='yes' + ;; + --ldstrict) + mb_ldstrict='yes' + ;; + + # project + --nickname=*) + mb_nickname=${arg#*=} + ;; + --avoid-version) + mb_avoid_version='yes' + ;; + --source-dir=*) + mb_source_dir=${arg#*=} + ;; + + *) + error_msg ${arg#}: "unsupported config argument." + exit 2 + ;; + esac +done + + + +# three: validation +verify_source_directory + + + +# four: defaults +common_defaults +native_defaults +cross_defaults + + + +# five: config +config_flags +config_copy +config_support +config_host +config_status + + +# all done +exit 0 diff --git a/include/ntux/ntux.h b/include/ntux/ntux.h new file mode 100644 index 0000000..896f301 --- /dev/null +++ b/include/ntux/ntux.h @@ -0,0 +1,84 @@ +#ifndef NTUX_H +#define NTUX_H + +#include + +#include "ntux_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* pre-alpha */ +#ifndef NTUX_APP +#ifndef NTUX_PRE_ALPHA +#error libntux: pre-alpha: ABI is not final! +#error to use the library, please pass -DNTUX_PRE_ALPHA to the compiler. +#endif +#endif + +/* status codes */ +#define NTUX_OK 0x00 +#define NTUX_USAGE 0x01 +#define NTUX_ERROR 0x02 + +/* driver flags */ +#define NTUX_DRIVER_VERBOSITY_NONE 0x0000 +#define NTUX_DRIVER_VERBOSITY_ERRORS 0x0001 +#define NTUX_DRIVER_VERBOSITY_STATUS 0x0002 +#define NTUX_DRIVER_VERBOSITY_USAGE 0x0004 +#define NTUX_DRIVER_CLONE_VECTOR 0x0008 + +#define NTUX_DRIVER_VERSION 0x0010 +#define NTUX_DRIVER_DRY_RUN 0x0020 + +struct ntux_source_version { + int major; + int minor; + int revision; + const char * commit; +}; + +struct ntux_error_info { + const struct ntux_driver_ctx * edctx; + const struct ntux_unit_ctx * euctx; + const char * eunit; + int esyscode; + int elibcode; + const char * efunction; + int eline; + unsigned eflags; + void * eany; +}; + +struct ntux_common_ctx { + uint64_t drvflags; + uint64_t actflags; + uint64_t fmtflags; +}; + +struct ntux_driver_ctx { + const char ** units; + const char * program; + const char * module; + const struct ntux_common_ctx * cctx; + struct ntux_error_info ** errv; + void * any; +}; + +/* package info */ +ntux_api const struct ntux_source_version * ntux_source_version(void); + +/* driver api */ +ntux_api int ntux_get_driver_ctx (char ** argv, char ** envp, uint32_t flags, struct ntux_driver_ctx **); +ntux_api int ntux_create_driver_ctx (const struct ntux_common_ctx *, struct ntux_driver_ctx **); +ntux_api void ntux_free_driver_ctx (struct ntux_driver_ctx *); + +/* utility api */ +ntux_api int ntux_main (int, char **, char **); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/ntux/ntux_api.h b/include/ntux/ntux_api.h new file mode 100644 index 0000000..5a5767f --- /dev/null +++ b/include/ntux/ntux_api.h @@ -0,0 +1,33 @@ +#ifndef NTUX_API_H +#define NTUX_API_H + +/* ntux_export */ +#if defined(__dllexport) +#define ntux_export __dllexport +#else +#define ntux_export +#endif + +/* ntux_import */ +#if defined(__dllimport) +#define ntux_import __dllimport +#else +#define ntux_import +#endif + +/* ntux_api */ +#ifndef NTUX_APP +#if defined (NTUX_EXPORT) +#define ntux_api ntux_export +#elif defined (NTUX_IMPORT) +#define ntux_api ntux_import +#elif defined (NTUX_STATIC) +#define ntux_api +#else +#define ntux_api +#endif +#else +#define ntux_api +#endif + +#endif diff --git a/project/arch.mk b/project/arch.mk new file mode 100644 index 0000000..caab091 --- /dev/null +++ b/project/arch.mk @@ -0,0 +1,5 @@ +src/internal/nolibc/ntux_compiler.lo: $(PROJECT_DIR)/src/internal/nolibc/$(ARCH)/ntux_compiler.s host.tag tree.tag + $(CC) -c -o $@ $< + +src/internal/nolibc/ntux_compiler.o: $(PROJECT_DIR)/src/internal/nolibc/$(ARCH)/ntux_compiler.s host.tag tree.tag + $(CC) -c -o $@ $< diff --git a/project/common.mk b/project/common.mk new file mode 100644 index 0000000..c1491b3 --- /dev/null +++ b/project/common.mk @@ -0,0 +1,17 @@ +DRIVER_SRCS = \ + src/driver/ntux_amain.c \ + src/driver/ntux_driver_ctx.c \ + src/skin/ntux_skin_default.c \ + +INTERNAL_SRCS = \ + src/internal/nolibc/ntux_compiler.c \ + src/internal/ntux_memfn_impl.c \ + src/internal/ntux_nolibc_impl.c \ + src/internal/ntux_ntaio_impl.c \ + +APP_SRCS = \ + src/ntux.c + +COMMON_SRCS = \ + $(DRIVER_SRCS) \ + $(INTERNAL_SRCS) \ 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..27b746c --- /dev/null +++ b/project/extras.mk @@ -0,0 +1,20 @@ +CFLAGS_SHARED_ATTR += -DNTUX_PRE_ALPHA -DNTUX_EXPORT +CFLAGS_STATIC_ATTR += -DNTUX_PRE_ALPHA -DNTUX_STATIC +CFLAGS_APP_ATTR += -DNTUX_APP + +CFLAGS_CONFIG += -ffreestanding +CFLAGS_CONFIG += -D_MIDIPIX_FREESTANDING -D__NT$(HOST_BITS) +CFLAGS_CONFIG += -UWIN32 -U_WIN32 -U__WIN32 -U__WIN32__ +CFLAGS_CONFIG += -UWIN64 -U_WIN64 -U__WIN64 -U__WIN64__ + +src/driver/ntux_driver_ctx.o: version.tag +src/driver/ntux_driver_ctx.lo: version.tag + +LDFLAGS_COMMON += -Wl,--entry -Wl,$(HOST_UNDERSCORE)$(PACKAGE)_entry_point +LDFLAGS_COMMON += -nostdlib + +LDFLAGS_SHARED += -lpsxscl +LDFLAGS_SHARED += -Wl,--exclude-all-symbols + +LDFLAGS_APP += -lpsxscl +LDFLAGS_STATIC += -static -lpsxscl -lntapi -lpemagine -ldalist diff --git a/project/headers.mk b/project/headers.mk new file mode 100644 index 0000000..c47901c --- /dev/null +++ b/project/headers.mk @@ -0,0 +1,12 @@ +API_HEADERS = \ + $(SOURCE_DIR)/include/$(PACKAGE)/ntux.h \ + $(SOURCE_DIR)/include/$(PACKAGE)/ntux_api.h \ + +INTERNAL_HEADERS = \ + $(SOURCE_DIR)/src/internal/argv/argv.h \ + $(SOURCE_DIR)/src/internal/$(PACKAGE)_driver_impl.h \ + $(SOURCE_DIR)/src/internal/$(PACKAGE)_init_impl.h \ + $(SOURCE_DIR)/src/internal/$(PACKAGE)_memfn_impl.h \ + $(SOURCE_DIR)/src/internal/$(PACKAGE)_nolibc_impl.h \ + +ALL_HEADERS = $(API_HEADERS) $(INTERNAL_HEADERS) diff --git a/project/osforce.mk b/project/osforce.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/project/osforce.mk 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/tagver.mk b/project/tagver.mk new file mode 100644 index 0000000..ab916aa --- /dev/null +++ b/project/tagver.mk @@ -0,0 +1,5 @@ +VER_NAMESPACE = NTUX + +VER_MAJOR = 0 +VER_MINOR = 0 +VER_PATCH = 0 diff --git a/project/tree.mk b/project/tree.mk new file mode 100644 index 0000000..2aadd88 --- /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/internal/nolibc + mkdir -p src/logic + mkdir -p src/skin + touch tree.tag diff --git a/sofort/custom.mk b/sofort/custom.mk new file mode 100644 index 0000000..8e0bbc4 --- /dev/null +++ b/sofort/custom.mk @@ -0,0 +1,76 @@ +ifeq ($(OS_BINFMT),PE) +include $(PROJECT_DIR)/sysinfo/os/pe.mk +endif + +ifeq ($(OS_BINFMT),ELF) +include $(PROJECT_DIR)/sysinfo/os/elf.mk +endif + + + +ifeq ($(DISABLE_STATIC),yes) +package-static: +package-install-static: +else +package-static: static +package-install-static: install-static +endif + +ifeq ($(DISABLE_SHARED),yes) +package-shared: +package-install-shared: +else +package-shared: shared +package-install-shared: install-shared +endif + + + +ifeq ($(DISABLE_FRONTEND),yes) +app-tag: +package-install-app: +package-install-extras: +else +app-tag: package-app app.tag +package-install-app: install-app +package-install-extras: install-extras +endif + + + +ifeq ($(ALL_STATIC),yes) + +package-app: static-app +app: PACKAGE_APP = $(STATIC_APP) +app-tag: PACKAGE_APP = $(STATIC_APP) +app.tag: $(STATIC_APP) + + +else ifeq ($(ALL_SHARED),yes) + +package-app: shared-app +app: PACKAGE_APP = $(SHARED_APP) +app-tag: PACKAGE_APP = $(SHARED_APP) +app.tag: $(SHARED_APP) + + +else + +package-app: default-app +app: PACKAGE_APP = $(DEFAULT_APP) +app-tag: PACKAGE_APP = $(DEFAULT_APP) +app.tag: $(DEFAULT_APP) + +endif + + + +ifeq ($(CUSTOM_INSTALL_HEADERS),yes) + +install-headers:install-headers-custom + +else + +install-headers:install-headers-default + +endif diff --git a/sofort/defs.mk b/sofort/defs.mk new file mode 100644 index 0000000..5810783 --- /dev/null +++ b/sofort/defs.mk @@ -0,0 +1,65 @@ +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) + +STATIC_LIB = lib/$(OS_LIB_PREFIX)$(PACKAGE)$(OS_ARCHIVE_EXT) + +DSO_VER = $(OS_LIB_PREFIX)$(PACKAGE)$(OS_LIB_SUFFIX)$(VER_XYZ) +DSO_SONAME = $(OS_LIB_PREFIX)$(PACKAGE)$(OS_LIB_SUFFIX)$(VER_SONAME) +DSO_SOLINK = $(OS_LIB_PREFIX)$(PACKAGE)$(OS_LIB_SUFFIX) + +SHARED_LIB = lib/$(DSO_VER) +SHARED_SONAME = lib/$(DSO_SONAME) +SHARED_SOLINK = lib/$(DSO_SOLINK) + +IMP_DEF = $(OS_LIB_PREFIX)$(PACKAGE)$(VER_XYZ)$(OS_LIBDEF_EXT) +IMP_VER = $(OS_LIB_PREFIX)$(PACKAGE)$(VER_XYZ)$(OS_IMPLIB_EXT) +IMP_SONAME = $(OS_LIB_PREFIX)$(PACKAGE)$(VER_SONAME)$(OS_IMPLIB_EXT) +IMP_SOLINK = $(OS_LIB_PREFIX)$(PACKAGE)$(OS_IMPLIB_EXT) + +IMPLIB_DEF = lib/$(IMP_DEF) +IMPLIB_VER = lib/$(IMP_VER) +IMPLIB_SONAME = lib/$(IMP_SONAME) +IMPLIB_SOLINK = lib/$(IMP_SOLINK) + +APP = bin/$(OS_APP_PREFIX)$(NICKNAME)$(OS_APP_SUFFIX) +DEFAULT_APP = bin/$(OS_APP_PREFIX)$(NICKNAME)-default$(OS_APP_SUFFIX) +SHARED_APP = bin/$(OS_APP_PREFIX)$(NICKNAME)-shared$(OS_APP_SUFFIX) +STATIC_APP = bin/$(OS_APP_PREFIX)$(NICKNAME)-static$(OS_APP_SUFFIX) + +CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_CONFIG) $(CFLAGS_SYSROOT) \ + $(CFLAGS_COMMON) $(CFLAGS_CMDLINE) $(CFLAGS_HOST) \ + $(CFLAGS_PATH) $(CFLAGS_OS) $(CFLAGS_SITE) \ + $(CFLAGS_VERSION) $(CFLAGS_STRICT) \ + $(CFLAGS_LAST) $(CFLAGS_ONCE) + +CFLAGS_SHARED = $(CFLAGS) $(CFLAGS_PIC) $(CFLAGS_SHARED_ATTR) +CFLAGS_STATIC = $(CFLAGS) $(CFLAGS_OBJ) $(CFLAGS_STATIC_ATTR) +CFLAGS_APP = $(CFLAGS) $(CFLAGS_OBJ) $(CFLAGS_APP_ATTR) $(CFLAGS_UTIL) + +LDFLAGS_SHARED = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(SHARED_LIB_DEPS) $(LDFLAGS_STRICT) \ + $(LDFLAGS_LAST) $(LDFLAGS_ONCE) + +LDFLAGS_APP = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(SHARED_APP_DEPS) $(LDFLAGS_STRICT) \ + $(LDFLAGS_UTIL) $(LDFLAGS_LAST) $(LDFLAGS_ONCE) + +LDFLAGS_STATIC = $(LDFLAGS_DEBUG) $(LDFLAGS_CONFIG) $(LDFLAGS_SYSROOT) \ + $(LDFLAGS_COMMON) $(LDFLAGS_CMDLINE) $(LDFLAGS_HOST) \ + $(LDFLAGS_PATH) $(STATIC_APP_DEPS) $(LDFLAGS_STRICT) \ + $(LDFLAGS_LAST) $(LDFLAGS_ONCE) diff --git a/sofort/version.mk b/sofort/version.mk new file mode 100644 index 0000000..5ef0ee2 --- /dev/null +++ b/sofort/version.mk @@ -0,0 +1,63 @@ +include $(PROJECT_DIR)/project/tagver.mk + +CFLAGS_VERSION += -D$(VER_NAMESPACE)_TAG_VER_MAJOR=$(VER_MAJOR) +CFLAGS_VERSION += -D$(VER_NAMESPACE)_TAG_VER_MINOR=$(VER_MINOR) +CFLAGS_VERSION += -D$(VER_NAMESPACE)_TAG_VER_PATCH=$(VER_PATCH) + +ifeq ($(AVOID_VERSION),yes) + +VER_XYZ = +VER_SONAME = + +package-shared-soname: +package-shared-solink: +package-install-soname: +package-install-solink: + +else + +VER_XYZ = .$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) +VER_SONAME = .$(VER_MAJOR) + +package-shared-soname: shared-soname +package-shared-solink: shared-solink +package-install-soname: install-soname +package-install-solink: install-solink + + + +# libfoo.so (common) +install-solink: install-lib + rm -f $(SHARED_SOLINK).tmp + ln -s $(DSO_VER) $(SHARED_SOLINK).tmp + mv $(SHARED_SOLINK).tmp $(DESTDIR)$(LIBDIR)/$(DSO_SOLINK) + +$(SHARED_SOLINK): $(SHARED_LIB) + rm -f $@.tmp + ln -s $(DSO_VER) $@.tmp + mv $@.tmp $@ + +# libfoo.so.x (symlink) +ifeq ($(OS_SONAME),symlink) +$(SHARED_SONAME): $(SHARED_LIB) + rm -f $@.tmp + ln -s $(DSO_VER) $@.tmp + mv $@.tmp $@ + +install-soname: install-lib + rm -f $(SHARED_SONAME).tmp + ln -s $(DSO_VER) $(SHARED_SONAME).tmp + mv $(SHARED_SONAME).tmp $(DESTDIR)$(LIBDIR)/$(DSO_SONAME) +endif + + +# libfoo.so.x (copy) +ifeq ($(OS_SONAME),copy) +install-soname: install-lib + cp $(SHARED_LIB) $(DESTDIR)$(LIBDIR)/$(DSO_SONAME) + +$(SHARED_SONAME): $(SHARED_LIB) + cp $(SHARED_LIB) $(SHARED_SONAME) +endif + +endif diff --git a/src/driver/ntux_amain.c b/src/driver/ntux_amain.c new file mode 100644 index 0000000..709c73b --- /dev/null +++ b/src/driver/ntux_amain.c @@ -0,0 +1,71 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include + +#include +#include "ntux_driver_impl.h" +#include "ntux_nolibc_impl.h" + +#ifndef NTUX_DRIVER_FLAGS +#define NTUX_DRIVER_FLAGS NTUX_DRIVER_VERBOSITY_ERRORS \ + | NTUX_DRIVER_VERBOSITY_USAGE +#endif + +static const char vermsg[] = "%s%s%s (git://midipix.org/ntux): " + "version %s%d.%d.%d%s.\n" + "[commit reference: %s%s%s]\n"; + +static const char * const ntux_ver_color[6] = { + "\x1b[1m\x1b[35m","\x1b[0m", + "\x1b[1m\x1b[32m","\x1b[0m", + "\x1b[1m\x1b[34m","\x1b[0m" +}; + +static const char * const ntux_ver_plain[6] = { + "","", + "","", + "","" +}; + +static ssize_t ntux_version(struct ntux_driver_ctx * dctx) +{ + const struct ntux_source_version * verinfo; + const char * const * verclr; + + verinfo = ntux_source_version(); + verclr = isatty(STDOUT_FILENO) ? ntux_ver_color : ntux_ver_plain; + + return fprintf(stdout,vermsg, + verclr[0],dctx->program,verclr[1], + verclr[2],verinfo->major,verinfo->minor, + verinfo->revision,verclr[3], + verclr[4],verinfo->commit,verclr[5]); +} + +static int ntux_exit(struct ntux_driver_ctx * dctx, int ret) +{ + ntux_free_driver_ctx(dctx); + return ret; +} + +int ntux_main(int argc, char ** argv, char ** envp) +{ + int ret; + struct ntux_driver_ctx * dctx; + + if ((ret = ntux_get_driver_ctx(argv,envp,NTUX_DRIVER_FLAGS,&dctx))) + return (ret == NTUX_USAGE) + ? !--argc + : NTUX_ERROR; + + if (dctx->cctx->drvflags & NTUX_DRIVER_VERSION) + if ((ntux_version(dctx)) < 0) + return ntux_exit(dctx,NTUX_ERROR); + + return ntux_exit(dctx,dctx->errv[0] ? NTUX_ERROR : NTUX_OK); +} diff --git a/src/driver/ntux_driver_ctx.c b/src/driver/ntux_driver_ctx.c new file mode 100644 index 0000000..2cd3cdf --- /dev/null +++ b/src/driver/ntux_driver_ctx.c @@ -0,0 +1,227 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include + +#include +#include "ntux_init_impl.h" +#include "ntux_nolibc_impl.h" + +#define ARGV_DRIVER + +#include "ntux_version.h" +#include "ntux_driver_impl.h" +#include "argv/argv.h" + +/* framework integration */ +#include + +__attr_section_decl__(".midipix") +static const nt_tty_affiliation tty_affiliation + __attr_section__(".midipix") + = NT_TTY_AFFILIATION_DEFAULT; + +/* ntapi accessor table */ +const ntapi_vtbl * ntux_ntapi; + +/* package info */ +static const struct ntux_source_version ntux_src_version = { + NTUX_TAG_VER_MAJOR, + NTUX_TAG_VER_MINOR, + NTUX_TAG_VER_PATCH, + NTUX_GIT_VERSION +}; + +struct ntux_driver_ctx_alloc { + struct argv_meta * meta; + struct ntux_driver_ctx_impl ctx; + uint64_t guard; + const char * units[]; +}; + +static uint32_t ntux_argv_flags(uint32_t flags) +{ + uint32_t ret = 0; + + if (flags & NTUX_DRIVER_VERBOSITY_NONE) + ret |= ARGV_VERBOSITY_NONE; + + if (flags & NTUX_DRIVER_VERBOSITY_ERRORS) + ret |= ARGV_VERBOSITY_ERRORS; + + if (flags & NTUX_DRIVER_VERBOSITY_STATUS) + ret |= ARGV_VERBOSITY_STATUS; + + return ret; +} + +static int ntux_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] ...\n" "Options:\n", + program); + + argv_usage(stdout,header,options,arg); + argv_free(meta); + + return NTUX_USAGE; +} + +static struct ntux_driver_ctx_impl * ntux_driver_ctx_alloc( + struct argv_meta * meta, + const struct ntux_common_ctx * cctx, + size_t nunits) +{ + struct ntux_driver_ctx_alloc * ictx; + size_t size; + struct argv_entry * entry; + const char ** units; + int elements; + + (void)tty_affiliation; + + size = sizeof(struct ntux_driver_ctx_alloc); + size += (nunits+1)*sizeof(const char *); + + if (!(ictx = calloc(1,size))) + return 0; + + elements = sizeof(ictx->ctx.erribuf) / sizeof(*ictx->ctx.erribuf); + + ictx->ctx.errinfp = &ictx->ctx.erriptr[0]; + ictx->ctx.erricap = &ictx->ctx.erriptr[--elements]; + + 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; + ictx->ctx.ctx.errv = ictx->ctx.errinfp; + return &ictx->ctx; +} + +static int ntux_get_driver_ctx_fail(struct argv_meta * meta) +{ + argv_free(meta); + return -1; +} + +int ntux_get_driver_ctx( + char ** argv, + char ** envp, + uint32_t flags, + struct ntux_driver_ctx ** pctx) +{ + struct ntux_driver_ctx_impl * ctx; + struct ntux_common_ctx cctx; + const struct argv_option * options; + struct argv_meta * meta; + struct argv_entry * entry; + size_t nunits; + const char * program; + + (void)envp; + + options = ntux_default_options; + + if (ntux_init()) + return -1; + + if (!(meta = argv_get(argv,options,ntux_argv_flags(flags)))) + return -1; + + nunits = 0; + program = argv_program_name(argv[0]); + memset(&cctx,0,sizeof(cctx)); + cctx.drvflags = flags; + + if (!argv[1] && (flags & NTUX_DRIVER_VERBOSITY_USAGE)) + return ntux_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 & NTUX_DRIVER_VERBOSITY_USAGE) + return ntux_driver_usage(program,entry->arg,options,meta); + + case TAG_VERSION: + cctx.drvflags |= NTUX_DRIVER_VERSION; + break; + } + } else + nunits++; + } + + if (!(ctx = ntux_driver_ctx_alloc(meta,&cctx,nunits))) + return ntux_get_driver_ctx_fail(meta); + + ctx->ctx.program = program; + ctx->ctx.cctx = &ctx->cctx; + + *pctx = &ctx->ctx; + return NTUX_OK; +} + +int ntux_create_driver_ctx( + const struct ntux_common_ctx * cctx, + struct ntux_driver_ctx ** pctx) +{ + struct argv_meta * meta; + struct ntux_driver_ctx_impl * ctx; + char * argv[] = {"ntux_driver",0}; + + if (ntux_init()) + return -1; + + if (!(meta = argv_get(argv,ntux_default_options,0))) + return -1; + + if (!(ctx = ntux_driver_ctx_alloc(meta,cctx,0))) + return ntux_get_driver_ctx_fail(0); + + ctx->ctx.cctx = &ctx->cctx; + memcpy(&ctx->cctx,cctx,sizeof(*cctx)); + *pctx = &ctx->ctx; + return NTUX_OK; +} + +static void ntux_free_driver_ctx_impl(struct ntux_driver_ctx_alloc * ictx) +{ + argv_free(ictx->meta); + free(ictx); +} + +void ntux_free_driver_ctx(struct ntux_driver_ctx * ctx) +{ + struct ntux_driver_ctx_alloc * ictx; + uintptr_t addr; + + if (ctx) { + addr = (uintptr_t)ctx - offsetof(struct ntux_driver_ctx_impl,ctx); + addr = addr - offsetof(struct ntux_driver_ctx_alloc,ctx); + ictx = (struct ntux_driver_ctx_alloc *)addr; + ntux_free_driver_ctx_impl(ictx); + } +} + +const struct ntux_source_version * ntux_source_version(void) +{ + return &ntux_src_version; +} diff --git a/src/internal/argv/argv.h b/src/internal/argv/argv.h new file mode 100644 index 0000000..3ddc311 --- /dev/null +++ b/src/internal/argv/argv.h @@ -0,0 +1,909 @@ +/****************************************************************************/ +/* argv.h: a thread-safe argument vector parser and usage screen generator */ +/* Copyright (C) 2015--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/* This file is (also) part of sofort: portable software project template. */ +/****************************************************************************/ + +#ifndef ARGV_H +#define ARGV_H + +#include +#include +#include +#include +#include +#include +#include + +#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,) */ +/* 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_ONLY \ + | 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 (!fhybrid && (option->flags & ARGV_OPTION_HYBRID_ONLY)) + ferr = ARGV_ERROR_HYBRID_ONLY; + else if (option->optarg == ARGV_OPTARG_NONE) { + if (val[0]) { + ferr = ARGV_ERROR_OPTARG_NONE; + ctx->errch = val + 1; + } else + fval = false; + } 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) +{ + char opt_short_name[2] = {0,0}; + + if (ctx->erropt && ctx->erropt->short_name) + opt_short_name[0] = ctx->erropt->short_name; + + 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%s%s%s%s] " + "(option values may not be specified)\n", + ctx->errch, + opt_short_name[0] ? "-" : "", + opt_short_name, + opt_short_name[0] ? "," : "", + ctx->erropt->long_name ? "--" : "", + ctx->erropt->long_name); + break; + + case ARGV_ERROR_OPTARG_REQUIRED: + fprintf(stderr,"option [%s%s%s%s%s] requires %s %s%s%s\n", + opt_short_name[0] ? "-" : "", + opt_short_name, + opt_short_name[0] ? "," : "", + 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%s%s%s%s]={%s}\n", + ctx->errch, + opt_short_name[0] ? "-" : "", + opt_short_name, + opt_short_name[0] ? "," : "", + 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 = ""; + + (void)ctx; + + 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," := %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; iargv[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) { + 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) { + 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,fboth; + size_t len,optlen,desclen; + char cache; + char * prefix; + char * desc; + char * mark; + char * cap; + char description[4096]; + char optstr [72]; + const size_t optcap = 64; + const size_t width = 80; + const char indent[] = " "; + const char creset[] = "\x1b[0m"; + const char cbold [] = "\x1b[1m"; + const char cgreen[] = "\x1b[32m"; + const char cblue [] = "\x1b[34m"; + const char ccyan [] = "\x1b[36m"; + const char * color = ccyan; + bool fcolor; + + fshort = mode ? !strcmp(mode,"short") : 0; + flong = fshort ? 0 : mode && !strcmp(mode,"long"); + fboth = !fshort && !flong; + fcolor = isatty(fileno(file)); + + if (fcolor) + fprintf(file,"%s%s",cbold,cgreen); + + if (header) + fprintf(file,"%s",header); + + option = options; + optlen = 0; + + for (; option->short_name || option->long_name; option++) { + /* indent + comma */ + len = fboth ? sizeof(indent) + 1 : sizeof(indent); + + /* -o */ + if (fshort || fboth) + len += option->short_name + ? 2 : 0; + + /* --option */ + if (flong || fboth) + len += option->long_name + ? 2 + strlen(option->long_name) : 0; + + /* optlen */ + if (len > optlen) + optlen = len; + } + + if (optlen >= optcap) { + fprintf(stderr, + "Option strings exceed %zu characters, " + "please generate the usage screen manually.\n", + optcap); + return; + } + + optlen += ARGV_TAB_WIDTH; + optlen &= (~(ARGV_TAB_WIDTH-1)); + desclen = (optlen < width / 2) ? width - optlen : optlen; + + for (option=options; option->short_name || option->long_name; option++) { + /* color */ + if (fcolor) { + color = (color == ccyan) ? cblue : ccyan; + fputs(color,file); + } + + /* description, using either paradigm or argname if applicable */ + snprintf(description,sizeof(description),option->description, + option->paradigm + ? option->paradigm + : option->argname ? option->argname : ""); + description[sizeof(description)-1] = 0; + + /* long/hybrid option prefix (-/--) */ + prefix = option->flags & ARGV_OPTION_HYBRID_ONLY + ? " -" : "--"; + + /* option string */ + if (fboth && option->short_name && option->long_name) + sprintf(optstr,"%s-%c,%s%s", + indent,option->short_name,prefix,option->long_name); + + else if ((fshort || fboth) && option->short_name) + sprintf(optstr,"%s-%c",indent,option->short_name); + + else if (flong && option->long_name) + sprintf(optstr,"%s%s%s", + indent,prefix,option->long_name); + + else if (fboth && option->long_name) + sprintf(optstr,"%s %s%s", + indent,prefix,option->long_name); + + else + optstr[0] = 0; + + /* right-indented option buffer */ + if (description[0]) { + len = strlen(optstr); + sprintf(&optstr[len],"%-*c",(int)(optlen-len),' '); + } + + /* single line? */ + if (optlen + strlen(description) < width) { + fprintf(file,"%s%s\n",optstr,description); + + } else { + desc = description; + cap = desc + strlen(description); + + while (desc < cap) { + mark = (desc + desclen >= cap) + ? cap : desc + desclen; + + while (*mark && (mark > desc) + && (*mark != ' ') + && (*mark != '|') + && (*mark != '\t') + && (*mark != '\n')) + mark--; + + if (mark == desc) { + mark = (desc + desclen >= cap) + ? cap : desc + desclen; + cache = *mark; + *mark = 0; + } else if (*mark == '|') { + cache = *mark; + *mark = 0; + } else { + cache = 0; + *mark = 0; + } + + /* first line? */ + if (desc == description) + fprintf(file,"%s%s\n",optstr,desc); + else + fprintf(file,"%-*c %s\n", + (*desc == '|') + ? (int)(optlen+1) + : (int)optlen, + ' ',desc); + + if (cache) + *mark = cache; + else + mark++; + + desc = mark; + } + } + } + + if (fcolor) + fputs(creset,file); +} + +#endif + +#endif diff --git a/src/internal/nolibc/nt32/ntux_compiler.asm b/src/internal/nolibc/nt32/ntux_compiler.asm new file mode 100644 index 0000000..fa1e9da --- /dev/null +++ b/src/internal/nolibc/nt32/ntux_compiler.asm @@ -0,0 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ntux: native translation und extension ;; +;; Copyright (C) 2016 Z. Gilboa ;; +;; Released under GPLv2 and GPLv3; see COPYING.NTUX. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; ___chkstk_ms and _pei386_runtime_relocator are not needed by the framework +; and are provided here in the form of no-op functions in order to satisfy +; compiler-generated dependencies. + +TITLE __psx_compiler + +.model flat +.code + +___chkstk PROC EXPORT + ret +___chkstk ENDP + +END diff --git a/src/internal/nolibc/nt32/ntux_compiler.s b/src/internal/nolibc/nt32/ntux_compiler.s new file mode 100644 index 0000000..89e2840 --- /dev/null +++ b/src/internal/nolibc/nt32/ntux_compiler.s @@ -0,0 +1,20 @@ +############################################################ +## ntux: native translation und extension ## +## Copyright (C) 2016 Z. Gilboa ## +## Released under GPLv2 and GPLv3; see COPYING.NTUX. ## +############################################################ + +# ___chkstk_ms and _pei386_runtime_relocator are not needed by the framework +# and are provided here in the form of no-op functions in order to satisfy +# compiler-generated dependencies. + +.section .text + +.global _pei386_runtime_relocator +.global ___chkstk_ms + +_pei386_runtime_relocatorr: + ret + +___chkstk_ms: + ret diff --git a/src/internal/nolibc/nt64/ntux_compiler.asm b/src/internal/nolibc/nt64/ntux_compiler.asm new file mode 100644 index 0000000..d6011bd --- /dev/null +++ b/src/internal/nolibc/nt64/ntux_compiler.asm @@ -0,0 +1,19 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ntux: native translation und extension ;; +;; Copyright (C) 2016 Z. Gilboa ;; +;; Released under GPLv2 and GPLv3; see COPYING.NTUX. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; ___chkstk_ms and _pei386_runtime_relocator are not needed by the framework +; and are provided here in the form of no-op functions in order to satisfy +; compiler-generated dependencies. + +TITLE __psx_compiler + +.code + +__chkstk PROC EXPORT + ret +__chkstk ENDP + +END diff --git a/src/internal/nolibc/nt64/ntux_compiler.s b/src/internal/nolibc/nt64/ntux_compiler.s new file mode 100644 index 0000000..89e2840 --- /dev/null +++ b/src/internal/nolibc/nt64/ntux_compiler.s @@ -0,0 +1,20 @@ +############################################################ +## ntux: native translation und extension ## +## Copyright (C) 2016 Z. Gilboa ## +## Released under GPLv2 and GPLv3; see COPYING.NTUX. ## +############################################################ + +# ___chkstk_ms and _pei386_runtime_relocator are not needed by the framework +# and are provided here in the form of no-op functions in order to satisfy +# compiler-generated dependencies. + +.section .text + +.global _pei386_runtime_relocator +.global ___chkstk_ms + +_pei386_runtime_relocatorr: + ret + +___chkstk_ms: + ret diff --git a/src/internal/nolibc/stdbool.h b/src/internal/nolibc/stdbool.h new file mode 100644 index 0000000..45fc6f9 --- /dev/null +++ b/src/internal/nolibc/stdbool.h @@ -0,0 +1,11 @@ +#ifndef _STDBOOL_H +#define _STDBOOL_H + +#ifndef __cplusplus + +#define true 1 +#define false 0 +#define bool _Bool + +#endif +#endif diff --git a/src/internal/nolibc/stddef.h b/src/internal/nolibc/stddef.h new file mode 100644 index 0000000..8288bae --- /dev/null +++ b/src/internal/nolibc/stddef.h @@ -0,0 +1,6 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 )) + +#endif diff --git a/src/internal/nolibc/stdint.h b/src/internal/nolibc/stdint.h new file mode 100644 index 0000000..831d865 --- /dev/null +++ b/src/internal/nolibc/stdint.h @@ -0,0 +1,6 @@ +#ifndef _STDINT_H +#define _STDINT_H + +#include + +#endif diff --git a/src/internal/nolibc/stdio.h b/src/internal/nolibc/stdio.h new file mode 100644 index 0000000..610533e --- /dev/null +++ b/src/internal/nolibc/stdio.h @@ -0,0 +1,8 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#endif diff --git a/src/internal/nolibc/stdlib.h b/src/internal/nolibc/stdlib.h new file mode 100644 index 0000000..8a24bec --- /dev/null +++ b/src/internal/nolibc/stdlib.h @@ -0,0 +1,4 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#endif diff --git a/src/internal/nolibc/string.h b/src/internal/nolibc/string.h new file mode 100644 index 0000000..f8e3b8e --- /dev/null +++ b/src/internal/nolibc/string.h @@ -0,0 +1,4 @@ +#ifndef _STRING_H +#define _STRING_H + +#endif diff --git a/src/internal/nolibc/unistd.h b/src/internal/nolibc/unistd.h new file mode 100644 index 0000000..2e39dc8 --- /dev/null +++ b/src/internal/nolibc/unistd.h @@ -0,0 +1,4 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#endif diff --git a/src/internal/ntux_driver_impl.h b/src/internal/ntux_driver_impl.h new file mode 100644 index 0000000..815f3ef --- /dev/null +++ b/src/internal/ntux_driver_impl.h @@ -0,0 +1,33 @@ +#ifndef NTUX_DRIVER_IMPL_H +#define NTUX_DRIVER_IMPL_H + +#include +#include +#include +#include + +#include +#include "argv/argv.h" + +extern const struct argv_option ntux_default_options[]; +extern const ntapi_vtbl * ntux_ntapi; + +#define ntapi ntux_ntapi + +enum app_tags { + TAG_HELP, + TAG_VERSION, +}; + +struct ntux_driver_ctx_impl { + struct ntux_common_ctx cctx; + struct ntux_driver_ctx ctx; + struct __psx_context xctx; + const char * eunit; + struct ntux_error_info ** errinfp; + struct ntux_error_info ** erricap; + struct ntux_error_info * erriptr[64]; + struct ntux_error_info erribuf[64]; +}; + +#endif diff --git a/src/internal/ntux_init_impl.h b/src/internal/ntux_init_impl.h new file mode 100644 index 0000000..69d008a --- /dev/null +++ b/src/internal/ntux_init_impl.h @@ -0,0 +1,25 @@ +#ifndef NTUX_INIT_IMPL_H +#define NTUX_INIT_IMPL_H + +#include +#include +#include + +extern const ntapi_vtbl * ntux_ntapi; + +static int ntux_init(void) +{ + int32_t status; + ntapi_vtbl * pvtbl; + + if ((status = __xfi_ntapi_init(&pvtbl))) + return status; + + at_locked_cas( + (intptr_t *)&ntux_ntapi, + 0,(intptr_t)pvtbl); + + return 0; +} + +#endif diff --git a/src/internal/ntux_memfn_impl.c b/src/internal/ntux_memfn_impl.c new file mode 100644 index 0000000..1bcc753 --- /dev/null +++ b/src/internal/ntux_memfn_impl.c @@ -0,0 +1,94 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include "ntux_memfn_impl.h" +#include "ntux_driver_impl.h" + +void * ntux_calloc(size_t n, size_t size) +{ + struct ntux_memory_block block; + + if (!n || (size > (size_t)(-1) / n)) + return 0; + + size *= n; + size += 0xf; + size &= ~(size_t)0xf; + + block.addr = 0; + block.size = size + sizeof(block); + + if (ntapi->zw_allocate_virtual_memory( + NT_CURRENT_PROCESS_HANDLE, + &block.addr, + 0, + &block.size, + NT_MEM_COMMIT, + NT_PAGE_READWRITE)) + return 0; + + block.used = size; + block.avail = block.size - block.used; + + return (char *)block.addr + offsetof(struct ntux_memory_block,buffer); +} + +void * ntux_balloc( + struct ntux_memory_block * cache, + struct ntux_memory_block * block, + size_t n, size_t size) +{ + char * baddr; + void * addr = 0; + + if (!n || (size > (size_t)(-1) / n)) + return 0; + + if (!cache || !cache->addr) + addr = ntux_calloc(n,size); + + size *= n; + size += 0xf; + size &= ~(size_t)0xf; + + if (size < block->avail) + addr = ntux_calloc(n,size); + + /* newly allocated block? */ + if (addr) { + baddr = addr; + baddr -= offsetof(struct ntux_memory_block,buffer); + + ntapi->tt_aligned_block_memcpy( + (uintptr_t *)block, + (uintptr_t *)baddr, + sizeof(*block)); + + return addr; + } + + /* cache */ + addr = &block->buffer[block->used / sizeof(size_t)]; + block->used += size; + block->avail -= size; + return addr; +} + +void ntux_free(void * addr) +{ + struct ntux_memory_block block; + + block.addr = addr; + block.size = 0; + + ntapi->zw_free_virtual_memory( + NT_CURRENT_PROCESS_HANDLE, + &block.addr, + &block.size, + NT_MEM_RELEASE); +} diff --git a/src/internal/ntux_memfn_impl.h b/src/internal/ntux_memfn_impl.h new file mode 100644 index 0000000..bb8e300 --- /dev/null +++ b/src/internal/ntux_memfn_impl.h @@ -0,0 +1,22 @@ +#ifndef NTUX_MEMFN_IMPL_H +#define NTUX_MEMFN_IMPL_H + +#include + +struct ntux_memory_block { + void * addr; + size_t size; + size_t used; + size_t avail; + size_t buffer[]; +}; + +void * ntux_calloc(size_t n, size_t size); +void ntux_free(void * addr); + +void * ntux_balloc( + struct ntux_memory_block * cache, + struct ntux_memory_block * block, + size_t n, size_t size); + +#endif diff --git a/src/internal/ntux_nolibc_impl.c b/src/internal/ntux_nolibc_impl.c new file mode 100644 index 0000000..1b5867d --- /dev/null +++ b/src/internal/ntux_nolibc_impl.c @@ -0,0 +1,73 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include + +extern const ntapi_vtbl * ntux_ntapi; + +void * ntux_memcpy(void * dst, const void * src, size_t n) +{ + return ntux_ntapi->tt_generic_memcpy(dst,src,n); +} + +void * ntux_memset(void * ch, int c, size_t n) +{ + return ntux_ntapi->tt_generic_memset(ch,c,n); +} + +char * ntux_strcpy(char * dst, const char * src) +{ + return ntux_ntapi->tt_generic_memcpy( + dst,src, + ntux_ntapi->tt_string_null_offset_multibyte(src)); +} + +size_t ntux_strlen(const char * ch) +{ + return ntux_ntapi->tt_string_null_offset_multibyte(ch); +} + +int ntux_strcmp(const char * a, const char * b) +{ + return ntux_ntapi->tt_strcmp_multibyte(a,b); +} + +int ntux_strncmp(const char * a, const char * b, size_t n) +{ + return ntux_ntapi->tt_strncmp_multibyte(a,b,n); +} + +char * ntux_strchr(const char * ch, int c) +{ + for (; *ch; ch++) + if (*ch == c) + return (char *)ch; + return 0; +} + +char * ntux_strrchr(const char * ch, int c) +{ + const char * base; + + base = ch; + ch += ntux_ntapi->tt_string_null_offset_multibyte(ch); + + for (; ch >= base; ch--) + if (*ch == c) + return (char *)ch; + return 0; +} + +#ifdef NTUX_EXPORT +int __stdcall ntux_entry_point(void * hinstance, uint32_t reason, void * reserved) +{ + (void)hinstance; + (void)reason; + (void)reserved; + + return 1; +} +#endif diff --git a/src/internal/ntux_nolibc_impl.h b/src/internal/ntux_nolibc_impl.h new file mode 100644 index 0000000..d048bd4 --- /dev/null +++ b/src/internal/ntux_nolibc_impl.h @@ -0,0 +1,52 @@ +#ifndef NTUX_NOLIBC_IMPL_H +#define NTUX_NOLIBC_IMPL_H + +#define isatty ntux_isatty +#define fileno ntux_fileno + +#define fputs ntux_fputs +#define fprintf ntux_fprintf +#define sprintf ntux_sprintf +#define snprintf ntux_snprintf + +#define memcpy ntux_memcpy +#define memset ntux_memset + +#define strcpy ntux_strcpy +#define strlen ntux_strlen +#define strcmp ntux_strcmp +#define strncmp ntux_strncmp +#define strchr ntux_strchr +#define strrchr ntux_strrchr + +#define calloc ntux_calloc +#define free ntux_free + +#define stdin (void *)0 +#define stdout (void *)1 +#define stderr (void *)2 + +typedef struct ntux_file FILE; + +int ntux_isatty(int fildes); +int ntux_fileno(void * any); + +int ntux_sprintf(char * str, const char * fmt, ...); +int ntux_snprintf(char * str, size_t n, const char * fmt, ...); +int ntux_fprintf(FILE *__restrict, const char *__restrict, ...); +int ntux_fputs(const char * str, FILE * file); + +void * ntux_memcpy(void * dst, const void * src, size_t n); +void * memset(void * ch, int c, size_t n); + +char * ntux_strcpy(char * dst, const char * src); +size_t ntux_strlen(const char * ch); +int ntux_strcmp(const char * a, const char * b); +int ntux_strncmp(const char * a, const char * b, size_t n); +char * ntux_strchr(const char * ch, int c); +char * ntux_strrchr(const char * ch, int c); + +void * ntux_calloc(size_t n, size_t size); +void ntux_free(void *); + +#endif diff --git a/src/internal/ntux_ntaio_impl.c b/src/internal/ntux_ntaio_impl.c new file mode 100644 index 0000000..377a833 --- /dev/null +++ b/src/internal/ntux_ntaio_impl.c @@ -0,0 +1,114 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include + +extern const ntapi_vtbl * ntux_ntapi; + +typedef struct ntux_file { + void * hany; +} FILE; + +int ntux_fputs(const char * str, FILE * file) +{ + ssize_t ret; + size_t size; + size_t nbytes; + + size = ntux_ntapi->tt_string_null_offset_multibyte(str); + nbytes = size; + + while (nbytes) { + ret = __sys_write( + (int)(intptr_t)file, + str,nbytes); + + if (ret == -EINTR) + (void)0; + + else if (ret < 0) + return -1; + + else { + str += ret; + nbytes -= ret; + } + } + + /* all done */ + return (int)size; +} + +int ntux_fprintf(FILE * file, const char * fmt, ...) +{ + va_list ap; + char * str; + size_t buffer[32768/sizeof(size_t)]; + + ntux_ntapi->tt_aligned_block_memset( + buffer,0,sizeof(buffer)); + + str = (char *)buffer; + + va_start(ap, fmt); + ntux_ntapi->vsnprintf(str, sizeof(buffer), fmt, ap); + va_end(ap); + + str[sizeof(buffer)-1] = 0; + + return ntux_fputs(str,file); +} + +int ntux_sprintf(char * str, const char * fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = ntux_ntapi->vsprintf(str, fmt, ap); + va_end(ap); + + return ret; +} + +int ntux_snprintf(char * str, size_t n, const char * fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = ntux_ntapi->vsnprintf(str, n, fmt, ap); + va_end(ap); + + return ret; +} + +int ntux_isatty(int fildes) +{ + nt_runtime_data * rtdata; + + if ((ntux_ntapi->tt_get_runtime_data(&rtdata,0))) + return 0; + + if (fildes == 0) + return (rtdata->stdin_type == NT_FILE_TYPE_PTY); + + else if (fildes == 1) + return (rtdata->stdout_type == NT_FILE_TYPE_PTY); + + else if (fildes == 2) + return (rtdata->stderr_type == NT_FILE_TYPE_PTY); + + else + return 0; +} + +int ntux_fileno(void * any) +{ + return (int)(intptr_t)any; +} diff --git a/src/ntux.c b/src/ntux.c new file mode 100644 index 0000000..6c70d0b --- /dev/null +++ b/src/ntux.c @@ -0,0 +1,34 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include "ntux_driver_impl.h" + +int ntux_entry_point(void) +{ + int argc; + char ** argv; + char ** envp; + struct __psx_context ctx = {0,0,0,0,0,0,0,0,0,0,0}; + + /* ctx */ + ctx.size = sizeof(ctx); + + /* __psx_init must succeed... */ + if (__psx_init(&argc,&argv,&envp,&ctx)) + return -1; + + /* ...and conform */ + else if (envp != argv + (argc + 1)) + return -1; + + /* invoke main */ + __sys_exit_group( + ntux_main(argc,argv,envp)); + + return NT_STATUS_INTERNAL_ERROR; +} diff --git a/src/skin/ntux_skin_default.c b/src/skin/ntux_skin_default.c new file mode 100644 index 0000000..7bb0045 --- /dev/null +++ b/src/skin/ntux_skin_default.c @@ -0,0 +1,12 @@ +#include "ntux_driver_impl.h" +#include "argv/argv.h" + +const struct argv_option ntux_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/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..b3975ae --- /dev/null +++ b/sysinfo/host/host.sh @@ -0,0 +1,48 @@ +#!/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 +} + +# 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 + + +# 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-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-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..cf8ec00 --- /dev/null +++ b/sysinfo/os/any-os.mk @@ -0,0 +1,12 @@ +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 +OS_SONAME = symlink +OS_BINFMT = ELF + +.PHONY: $(IMPLIB_DEF) $(IMPLIB_VER) $(IMPLIB_SONAME) $(IMPLIB_SOLINK) diff --git a/sysinfo/os/cygwin.mk b/sysinfo/os/cygwin.mk new file mode 100644 index 0000000..a257b88 --- /dev/null +++ b/sysinfo/os/cygwin.mk @@ -0,0 +1,12 @@ +OS = cygwin +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 +OS_SONAME = copy +OS_BINFMT = PE + +CFLAGS_PIC = diff --git a/sysinfo/os/midipix.mk b/sysinfo/os/midipix.mk new file mode 100644 index 0000000..31ba374 --- /dev/null +++ b/sysinfo/os/midipix.mk @@ -0,0 +1,10 @@ +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 +OS_SONAME = copy +OS_BINFMT = PE diff --git a/sysinfo/os/mingw.mk b/sysinfo/os/mingw.mk new file mode 100644 index 0000000..c13e61d --- /dev/null +++ b/sysinfo/os/mingw.mk @@ -0,0 +1,13 @@ +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 +OS_SONAME = copy +OS_BINFMT = PE + +CFLAGS_PIC = +CFLAGS_OS += -U__STRICT_ANSI__ diff --git a/sysinfo/os/mingw32.mk b/sysinfo/os/mingw32.mk new file mode 100644 index 0000000..542b6a9 --- /dev/null +++ b/sysinfo/os/mingw32.mk @@ -0,0 +1 @@ +include $(PROJECT_DIR)/sysinfo/os/mingw.mk diff --git a/sysinfo/os/mingw64.mk b/sysinfo/os/mingw64.mk new file mode 100644 index 0000000..542b6a9 --- /dev/null +++ b/sysinfo/os/mingw64.mk @@ -0,0 +1 @@ +include $(PROJECT_DIR)/sysinfo/os/mingw.mk diff --git a/sysinfo/os/msys.mk b/sysinfo/os/msys.mk new file mode 100644 index 0000000..b70cc78 --- /dev/null +++ b/sysinfo/os/msys.mk @@ -0,0 +1,13 @@ +OS = msys +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 +OS_SONAME = copy +OS_BINFMT = PE + +CFLAGS_PIC = +CFLAGS_OS += -U__STRICT_ANSI__ diff --git a/sysinfo/os/pe.mk b/sysinfo/os/pe.mk new file mode 100644 index 0000000..bbb74b2 --- /dev/null +++ b/sysinfo/os/pe.mk @@ -0,0 +1,74 @@ +LDFLAGS_IMPLIB += -Wl,--output-def +LDFLAGS_IMPLIB += -Wl,$(IMPLIB_DEF) +LDFLAGS_SHARED += $(LDFLAGS_IMPLIB) + +LDFLAGS_SONAME += -Wl,-soname +LDFLAGS_SONAME += -Wl,$(DSO_SONAME) +LDFLAGS_SHARED += $(LDFLAGS_SONAME) + +PE_SUBSYSTEM ?= windows +LDFLAGS_COMMON += -Wl,--subsystem=$(PE_SUBSYSTEM) + +implib: implib-ver package-implib-soname package-implib-solink + +implib-ver: shared-lib $(IMPLIB_VER) + +implib-soname: shared-lib $(IMPLIB_SONAME) + +implib-solink: shared-lib $(IMPLIB_SOLINK) + +$(IMPLIB_DEF): shared-lib + +$(IMPLIB_VER): $(IMPLIB_DEF) + $(DLLTOOL) -l $(IMPLIB_VER) -d $(IMPLIB_DEF) -D $(DSO_VER) + +install-implib: install-implib-ver \ + package-install-implib-soname \ + package-install-implib-solink + +install-implib-ver: implib-ver + mkdir -p $(DESTDIR)$(LIBDIR) + cp $(IMPLIB_VER) $(DESTDIR)$(LIBDIR) + +clean-implib: + rm -f $(SHARED_LIB) + rm -f $(IMPLIB_DEF) + rm -f $(IMPLIB_VER) + rm -f $(IMPLIB_SONAME) + rm -f $(IMPLIB_SOLINK) + + +ifeq ($(AVOID_VERSION),yes) + +package-implib-soname: +package-implib-solink: +package-install-implib-soname: +package-install-implib-solink: + +else + +package-implib-soname: implib-soname +package-implib-solink: implib-solink +package-install-implib-soname: install-implib-soname +package-install-implib-solink: install-implib-solink + + +$(IMPLIB_SONAME): $(IMPLIB_DEF) + $(DLLTOOL) -l $(IMPLIB_SONAME) -d $(IMPLIB_DEF) -D $(DSO_SONAME) + +$(IMPLIB_SOLINK): $(IMPLIB_SONAME) + rm -f $(IMPLIB_SOLINK).tmp + ln -s $(IMP_SONAME) $(IMPLIB_SOLINK).tmp + mv $(IMPLIB_SOLINK).tmp $(IMPLIB_SOLINK) + +install-implib-soname: implib-soname + mkdir -p $(DESTDIR)$(LIBDIR) + cp $(IMPLIB_SONAME) $(DESTDIR)$(LIBDIR) + +install-implib-solink: implib-soname + mkdir -p $(DESTDIR)$(LIBDIR) + rm -f $(IMPLIB_SOLINK).tmp + ln -s $(IMP_SONAME) $(IMPLIB_SOLINK).tmp + mv $(IMPLIB_SOLINK).tmp $(DESTDIR)$(LIBDIR)/$(IMP_SOLINK) + +endif diff --git a/sysinfo/toolchain/binutils.mk b/sysinfo/toolchain/binutils.mk new file mode 100644 index 0000000..3232915 --- /dev/null +++ b/sysinfo/toolchain/binutils.mk @@ -0,0 +1,18 @@ +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 +DLLTOOL = $(CROSS_COMPILE)dlltool diff --git a/sysinfo/toolchain/llvm.mk b/sysinfo/toolchain/llvm.mk new file mode 100644 index 0000000..65b5396 --- /dev/null +++ b/sysinfo/toolchain/llvm.mk @@ -0,0 +1,18 @@ +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 +DLLTOOL = $(CROSS_COMPILE)dlltool diff --git a/sysinfo/version.sh b/sysinfo/version.sh new file mode 100755 index 0000000..0b948bc --- /dev/null +++ b/sysinfo/version.sh @@ -0,0 +1,62 @@ +#!/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 +mkdir -p `dirname "$output"` || exit 2 +printf "#define $macro\t\"$gitver\"\n" > "$output" + +# all done +exit 0