├── .gitignore ├── .gitmodules ├── LICENSE ├── Prefix.pch ├── README.md ├── bin ├── bootstrap.sh ├── deb_build_num.sh ├── denicify.pl ├── fakeroot.sh ├── generate_private_framework.sh ├── install.copyFile ├── install.exec ├── install.mergeDir ├── lib │ ├── Logos │ │ ├── Class.pm │ │ ├── Generator.pm │ │ ├── Generator │ │ │ ├── Base │ │ │ │ ├── Class.pm │ │ │ │ ├── Generator.pm │ │ │ │ ├── Group.pm │ │ │ │ ├── Method.pm │ │ │ │ ├── StaticClassGroup.pm │ │ │ │ └── Subclass.pm │ │ │ ├── MobileSubstrate │ │ │ │ ├── Class.pm │ │ │ │ ├── Generator.pm │ │ │ │ ├── Method.pm │ │ │ │ └── Subclass.pm │ │ │ ├── Thunk.pm │ │ │ └── internal │ │ │ │ ├── Class.pm │ │ │ │ ├── Generator.pm │ │ │ │ ├── Method.pm │ │ │ │ └── Subclass.pm │ │ ├── Group.pm │ │ ├── Ivar.pm │ │ ├── Method.pm │ │ ├── Patch.pm │ │ ├── Patch │ │ │ └── Source │ │ │ │ └── Generator.pm │ │ ├── StaticClassGroup.pm │ │ ├── Subclass.pm │ │ └── Util.pm │ ├── NIC │ │ ├── Bridge │ │ │ ├── Context.pm │ │ │ ├── Directory.pm │ │ │ ├── File.pm │ │ │ ├── NICBase.pm │ │ │ ├── NICType.pm │ │ │ ├── Symlink.pm │ │ │ ├── Tie │ │ │ │ └── WrappedMethod.pm │ │ │ ├── _BridgedObject.pm │ │ │ └── _Undefined.pm │ │ ├── Formats │ │ │ ├── NIC1.pm │ │ │ ├── NICTar.pm │ │ │ └── NICTar │ │ │ │ ├── Directory.pm │ │ │ │ ├── File.pm │ │ │ │ ├── Symlink.pm │ │ │ │ └── _TarMixin.pm │ │ ├── NICBase.pm │ │ ├── NICBase │ │ │ ├── Directory.pm │ │ │ ├── File.pm │ │ │ └── Symlink.pm │ │ ├── NICType.pm │ │ └── Tie │ │ │ ├── Method.pm │ │ │ └── PrefixedHandleRedirect.pm │ ├── aliased.pm │ └── parent.pm ├── logify.pl ├── logos.pl ├── nic.pl ├── nicify.pl ├── package_version.sh ├── target.pl └── vercmp.pl ├── documentation ├── Makefile └── makefiles.docbook ├── extras └── vim │ ├── README │ ├── ftplugin │ └── logos.vim │ ├── indent │ └── logos.vim │ └── syntax │ └── logos.vim ├── git-submodule-recur.sh ├── lib └── .keep ├── makefiles ├── aggregate.mk ├── application.mk ├── bundle.mk ├── common.mk ├── framework.mk ├── install │ ├── deb_local.mk │ ├── deb_remote.mk │ ├── none_local.mk │ ├── none_remote.mk │ ├── pkg_local.mk │ ├── pkg_remote.mk │ ├── rpm_local.mk │ └── rpm_remote.mk ├── instance │ ├── application.mk │ ├── bundle.mk │ ├── framework.mk │ ├── library.mk │ ├── null.mk │ ├── rules.mk │ ├── shared │ │ └── bundle.mk │ ├── subproject.mk │ ├── tool.mk │ └── tweak.mk ├── legacy.mk ├── library.mk ├── master │ ├── aggregate.mk │ ├── application.mk │ ├── bundle.mk │ ├── framework.mk │ ├── library.mk │ ├── null.mk │ ├── rules.mk │ ├── subproject.mk │ ├── tool.mk │ └── tweak.mk ├── messages.mk ├── null.mk ├── package.mk ├── package │ ├── deb.mk │ ├── none.mk │ ├── pkg.mk │ └── rpm.mk ├── platform │ ├── Darwin-arm.mk │ ├── Darwin.mk │ └── Linux.mk ├── rules.mk ├── stage.mk ├── subproject.mk ├── targets │ ├── Darwin-arm │ │ ├── iphone.mk │ │ └── native.mk │ ├── Darwin │ │ ├── iphone.mk │ │ ├── macosx.mk │ │ ├── native.mk │ │ └── simulator.mk │ ├── Linux │ │ ├── iphone.mk │ │ ├── linux.mk │ │ └── native.mk │ └── _common │ │ ├── darwin.mk │ │ ├── darwin_flat_bundle.mk │ │ ├── darwin_hierarchial_bundle.mk │ │ └── linux.mk ├── tool.mk └── tweak.mk ├── mod └── .keep └── templates └── iphone ├── application.nic.tar ├── library.nic.tar ├── preference_bundle.nic.tar ├── tool.nic.tar └── tweak.nic.tar /.gitignore: -------------------------------------------------------------------------------- 1 | lib/libsubstrate.dylib 2 | .DS_Store 3 | ._* 4 | .bootstrap 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpetrich/theos/6b05eac5169242b99a599a94e692d0d9e8baa855/.gitmodules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Theos (and by extension, Logos) is available under the provisions of the GNU 2 | General Public License, version 3 (or later), available here: 3 | http://www.gnu.org/licenses/gpl-3.0.html. 4 | 5 | Projects created using Theos and/or Logos are not considered derivative works 6 | (from a licensing standpoint, or, for that matter, any other standpoint) and 7 | are, as such, not required to be licensed under the GNU GPL. 8 | 9 | The included project templates are license-free. The use of a template does 10 | not confer a license to your project. 11 | -------------------------------------------------------------------------------- /Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifndef __has_feature 2 | #define __has_feature(feature) (0) 3 | #endif 4 | #ifndef __has_extension 5 | #define __has_extension(extension) (0) 6 | #endif 7 | 8 | #ifdef __OBJC__ 9 | #define CLASS(cls) objc_getClass(#cls) 10 | 11 | #ifdef DEBUG 12 | #define __DEBUG__ 13 | #endif 14 | 15 | #ifndef __clang__ 16 | #define weak assign 17 | #define strong retain 18 | #define instancetype id 19 | #define nullable 20 | #endif 21 | 22 | #import 23 | 24 | #ifndef __clang__ 25 | // Fix old GCC versions not identifying the correct response type on [[NSDictionary alloc] initWithContentsOfFile:...] and other similar calls 26 | #define THEOS_WORKAROUND_ALLOC(type) @interface type() + (type *)alloc; @end 27 | THEOS_WORKAROUND_ALLOC(NSDictionary); 28 | THEOS_WORKAROUND_ALLOC(NSMutableDictionary); 29 | THEOS_WORKAROUND_ALLOC(NSArray); 30 | THEOS_WORKAROUND_ALLOC(NSMutableArray); 31 | #undef THEOS_WORKAROUND_ALLOC 32 | // Workaround NS_AVAILABLE being used in enums, by disabling entirely :( 33 | #undef NS_AVAILABLE 34 | #define NS_AVAILABLE(osx, ios) 35 | #endif 36 | 37 | #ifdef __DEBUG__ 38 | #define CMLog(format, ...) NSLog(@"(%s) in [%s:%d] ::: %@", __PRETTY_FUNCTION__, __FILE__, __LINE__, [NSString stringWithFormat:format, ## __VA_ARGS__]) 39 | #define MARK CMLog(@"%s", __PRETTY_FUNCTION__); 40 | #define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; 41 | #define END_TIMER(msg) NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@"%@ Time = %f", msg, stop-start]) 42 | #else 43 | #define CMLog(format, ...) 44 | #define MARK 45 | #define START_TIMER 46 | #define END_TIMER(msg) 47 | //#define NSLog(...) 48 | #endif 49 | 50 | #define NB [NSBundle mainBundle] 51 | #define UD [NSUserDefaults standardUserDefaults] 52 | #define FM [NSFileManager defaultManager] 53 | 54 | #endif 55 | 56 | #ifndef __clang__ 57 | #if defined(TARGET_MACOSX) || defined(TARGET_IPHONEOS) 58 | #import 59 | #undef NS_AVAILABLE 60 | #define NS_AVAILABLE(osx, ios) 61 | #undef __OSX_AVAILABLE_STARTING 62 | #define __OSX_AVAILABLE_STARTING(osx, ios) 63 | #include 64 | #endif 65 | #endif 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a fork of DHowett's theos. For the original see http://github.com/DHowett/theos 2 | 3 | #Theos 4 | A user-friendly framework for creating open iPhone projects 5 | ## Initial Setup 6 | ### Mac OS X 7 | 1. Download and install iPhone SDK. Be sure to include the iPhone 3.0 SDK version 8 | 2. Download and install latest git version from Google Code 9 | 3. Type `cd ~ && git clone git://github.com/rpetrich/theos.git` inside a shell (via Terminal.app) 10 | 11 | ## Project Setup 12 | 13 | 1. Open a command shell and `cd` to the directory where you store your projects 14 | 2. `~/theos/new-tweak.sh tweakname` (where _tweakname_ is the name of the new project you are creating) 15 | 3. `cd tweakname` 16 | 17 | You are now inside the new project's directory 18 | 19 | ## Using Theos 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
makeBuilds all targets by compiling the necessary files and linking them
make cleanCleans all targets and removes temporary files
make packageCreates a debian package using the contents of layout directory and the compiled build targets
make update-frameworkUpdates your project to use the latest version of the theos framework
38 | -------------------------------------------------------------------------------- /bin/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | bootstrap_version=2 3 | 4 | ARGV0=$0 5 | [[ -z "$THEOS" ]] && THEOS=$(cd $(dirname $0); cd ..; pwd) 6 | THEOSDIR="$THEOS" 7 | 8 | function makeSubstrateStub() { 9 | PROJECTDIR=$(mktemp -d /tmp/theos.XXXXXX) 10 | cd $PROJECTDIR 11 | ln -s "$THEOSDIR" theos 12 | 13 | cat > Makefile << __EOF 14 | TARGET_IPHONEOS_DEPLOYMENT_VERSION = 2.0 15 | IPHONE_ARCHS=armv7 armv7s arm64 16 | SDKVERSION_armv6 = 5.1 17 | ifneq (\$(THEOS_PLATFORM_SDK_ROOT_armv6),) 18 | IPHONE_ARCHS += armv6 19 | endif 20 | 21 | include theos/makefiles/common.mk 22 | LIBRARY_NAME = libsubstrate 23 | libsubstrate_FILES = Hooker.cc 24 | libsubstrate_INSTALL_PATH = /usr/lib 25 | ifeq (\$(THEOS_PLATFORM_NAME),macosx) 26 | libsubstrate_LDFLAGS = -Wl,-allow_sub_type_mismatches 27 | endif 28 | include \$(THEOS_MAKE_PATH)/library.mk 29 | 30 | after-libsubstrate-all:: 31 | @\$(TARGET_STRIP) -x -c \$(THEOS_OBJ_DIR)/libsubstrate.dylib 32 | @mkdir -p \$(THEOS_PROJECT_DIR)/_out 33 | @cp \$(THEOS_OBJ_DIR)/libsubstrate.dylib \$(THEOS_PROJECT_DIR)/_out/libsubstrate.dylib 34 | 35 | __EOF 36 | 37 | cat > Hooker.cc << __EOF 38 | typedef void *id; 39 | typedef void *SEL; 40 | typedef void *Class; 41 | typedef id (*IMP)(id, SEL); 42 | 43 | bool MSDebug = false; 44 | extern "C" { 45 | typedef const void *MSImageRef; 46 | void MSHookFunction(void *symbol, void *replace, void **result) { }; 47 | void *MSFindSymbol(const void *image, const char *name) { return (void*)0; } 48 | MSImageRef MSGetImageByName(const char *file) { return (MSImageRef)0; } 49 | 50 | #ifdef __APPLE__ 51 | #ifdef __arm__ 52 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix = (char *)0) { return (IMP)0; } 53 | #endif 54 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result) { } 55 | #endif 56 | } 57 | __EOF 58 | 59 | unset MAKE MAKELEVEL 60 | unset TARGET_CC TARGET_CXX TARGET_LD TARGET_STRIP TARGET_CODESIGN_ALLOCATE TARGET_CODESIGN TARGET_CODESIGN_FLAGS 61 | unset THEOS_BUILD_DIR THEOS_OBJ_DIR THEOS_OBJ_DIR_NAME 62 | unset THEOS_PROJECT_DIR 63 | echo -n " Compiling iPhoneOS CydiaSubstrate stub..." 64 | ( echo -n " default target?"; make libsubstrate target=iphone &> /dev/null; ) || 65 | echo -n " failed, what?" 66 | echo 67 | 68 | #if [[ "$(uname -s)" == "Darwin" && "$(uname -p)" != "arm" ]]; then 69 | # echo " Compiling native CydiaSubstrate stub..." 70 | # make CydiaSubstrate target=native > /dev/null 71 | #fi 72 | 73 | files=(_out/*) 74 | if [[ ${#files[*]} -eq 0 ]]; then 75 | echo "I didn't actually end up with a file here... I should probably bail out." 76 | exit 1 77 | elif [[ ${#files[*]} -eq 1 ]]; then 78 | cp _out/* libsubstrate.dylib 79 | else 80 | lipo _out/* -create -output libsubstrate.dylib 81 | fi 82 | 83 | cp libsubstrate.dylib "$THEOSDIR/lib/libsubstrate.dylib" 84 | 85 | cd "$THEOSDIR" 86 | rm -rf $PROJECTDIR 87 | } 88 | 89 | function copySystemSubstrate() { 90 | if [[ -f "/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate" ]]; then 91 | echo " Copying system CydiaSybstrate..." 92 | cp "/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate" "$THEOSDIR/lib/libsubstrate.dylib" 93 | return 0 94 | else 95 | return 1 96 | fi 97 | } 98 | 99 | function makeSubstrateHeader() { 100 | echo " Generating substrate.h header..." 101 | cat > "$THEOSDIR/include/substrate.h" << __EOF 102 | #include 103 | #include 104 | #include 105 | #ifdef __cplusplus 106 | #define _default(x) = x 107 | extern "C" { 108 | #else 109 | #define _default(x) 110 | #endif 111 | typedef const void *MSImageRef; 112 | void MSHookFunction(void *symbol, void *replace, void **result); 113 | void *MSFindSymbol(const void *image, const char *name); 114 | MSImageRef MSGetImageByName(const char *file); 115 | 116 | #ifdef __APPLE__ 117 | #ifdef __arm__ 118 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix _default(NULL)); 119 | #endif 120 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result); 121 | #endif 122 | #ifdef __cplusplus 123 | } 124 | #endif 125 | __EOF 126 | } 127 | 128 | function copySystemSubstrateHeader() { 129 | if [[ -f "/Library/Frameworks/CydiaSubstrate.framework/Headers/CydiaSubstrate.h" ]]; then 130 | echo " Copying system CydiaSubstrate header..." 131 | cp "/Library/Frameworks/CydiaSubstrate.framework/Headers/CydiaSubstrate.h" "$THEOSDIR/include/substrate.h" 132 | return 0 133 | else 134 | return 1 135 | fi 136 | } 137 | 138 | function checkWritability() { 139 | if ! touch "$THEOSDIR/.perm" &> /dev/null; then 140 | retval=1 141 | return 1 142 | fi 143 | rm "$THEOSDIR/.perm" &> /dev/null 144 | return 0 145 | } 146 | 147 | function getCurrentBootstrapVersion { 148 | v=1 149 | if [[ -f "$THEOSDIR/.bootstrap" ]]; then 150 | v=$(< "$THEOSDIR/.bootstrap") 151 | fi 152 | echo -n "$v" 153 | } 154 | 155 | function bootstrapSubstrate { 156 | [ -f "$THEOSDIR/lib/libsubstrate.dylib" ] || copySystemSubstrate || makeSubstrateStub 157 | [ -f "$THEOSDIR/include/substrate.h" ] || copySystemSubstrateHeader || makeSubstrateHeader 158 | echo -n "$bootstrap_version" > "$THEOSDIR/.bootstrap" 159 | } 160 | 161 | if ! checkWritability; then 162 | echo "$THEOSDIR is not writable. Please run \`$ARGV0 $@\` manually, with privileges." 1>&2 163 | exit 1 164 | fi 165 | 166 | # The use of 'p' denotes a query. 167 | # http://en.wikipedia.org/wiki/P_convention 168 | 169 | if [[ "$1" == "substrate" ]]; then 170 | echo "Bootstrapping CydiaSubstrate..." 171 | bootstrapSubstrate 172 | elif [[ "$1" == "version-p" ]]; then 173 | echo -n $(getCurrentBootstrapVersion) 174 | elif [[ "$1" == "newversion-p" ]]; then 175 | echo -n "$bootstrap_version" 176 | elif [[ "$1" == "update-p" ]]; then 177 | test $(getCurrentBootstrapVersion) -lt $bootstrap_version; exit $? 178 | #elif [[ "$1" == "update" ]]; then 179 | #echo "Updating CydiaSubstrate..." 180 | #bootstrapSubstrate 181 | fi 182 | -------------------------------------------------------------------------------- /bin/deb_build_num.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | GETONLY=0 3 | if [[ $1 == "-g" ]]; then 4 | GETONLY=1 5 | shift 6 | fi 7 | 8 | if [[ $# -lt 2 ]]; then 9 | echo "Syntax: $0 [-g] packagename versionname" >&2 10 | exit 1 11 | fi 12 | 13 | if [[ ! -d $TOP_DIR/.debmake ]]; then 14 | mkdir $TOP_DIR/.debmake 15 | fi 16 | 17 | PACKAGE=$1 18 | VERSION=$2 19 | INFOFILE=$TOP_DIR/.debmake/$PACKAGE-$VERSION 20 | if [[ ! -e $INFOFILE ]]; then 21 | echo -n 1 > $INFOFILE 22 | echo -n 1 23 | exit 0 24 | else 25 | CURNUM=$(cat $INFOFILE) 26 | if [[ $GETONLY -eq 0 ]]; then 27 | let CURNUM++ 28 | echo -n $CURNUM > $INFOFILE 29 | fi 30 | echo $CURNUM 31 | fi 32 | -------------------------------------------------------------------------------- /bin/denicify.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use warnings; 4 | use FindBin; 5 | use lib "$FindBin::Bin/lib"; 6 | 7 | use Module::Load::Conditional 'can_load'; 8 | 9 | $nicfile = $ARGV[0] if($ARGV[0]); 10 | $outputdir = $ARGV[1]; 11 | if(!$nicfile || !$outputdir) { 12 | exitWithError("Syntax: $0 nicfile outputdir"); 13 | } 14 | 15 | ### LOAD THE NICFILE! ### 16 | open(my $nichandle, "<", $nicfile); 17 | my $line = <$nichandle>; 18 | my $nicversion = 1; 19 | if($line =~ /^nic (\w+)$/) { 20 | $nicversion = $1; 21 | } 22 | seek($nichandle, 0, 0); 23 | 24 | my $NICPackage = "NIC$nicversion"; 25 | exitWithError("I don't understand NIC version $nicversion!") if(!can_load(modules => {"NIC::Formats::$NICPackage" => undef})); 26 | my $NIC = "NIC::Formats::$NICPackage"->new(); 27 | $NIC->load($nichandle); 28 | $NIC->addConstraint("package"); 29 | close($nichandle); 30 | ### YAY! ### 31 | 32 | $NIC->build($outputdir); 33 | $NIC->dumpPreamble("pre.NIC"); 34 | 35 | sub exitWithError { 36 | my $error = shift; 37 | print STDERR "[error] ", $error, $/; 38 | exit 1; 39 | } 40 | -------------------------------------------------------------------------------- /bin/fakeroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | required=0 3 | persistence=/tmp/dhbxxx 4 | 5 | while getopts ":p:rc" flag; do 6 | case "$flag" in 7 | :) echo "$0: Option -$OPTARG requires an argument." 1>&2 8 | exit 1 9 | ;; 10 | \?) echo "$0: Option -$OPTARG unrecognized." 1>&2 11 | exit 1 12 | ;; 13 | p) persistence="$OPTARG" ;; 14 | r) required=1 ;; 15 | c) delpersistence=1 ;; 16 | esac 17 | done 18 | shift $((OPTIND-1)) 19 | cmd=$* 20 | 21 | mkdir -p $(dirname $persistence) 22 | touch $persistence 23 | 24 | if [[ $delpersistence -eq 1 ]]; then 25 | rm -f $persistence 26 | exit 0 27 | fi 28 | 29 | if [[ "$USER" == "root" ]]; then 30 | fakeroot="" 31 | elif type fauxsu &> /dev/null; then 32 | fakeroot="fauxsu -p $persistence -- " 33 | elif type fakeroot-ng &> /dev/null; then 34 | fakeroot="fakeroot-ng -p $persistence -- " 35 | elif type fakeroot &> /dev/null; then 36 | fakeroot="fakeroot -i $persistence -s $persistence -- " 37 | else 38 | if [[ $required -eq 1 ]]; then 39 | fakeroot="" 40 | else 41 | fakeroot=": " 42 | fi 43 | fi 44 | 45 | #echo $fakeroot $cmd 46 | $fakeroot $cmd 47 | -------------------------------------------------------------------------------- /bin/generate_private_framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | framework_path="$1" 4 | framework="$2" 5 | destination_framework="$3" 6 | fallback_framework_path="$4" 7 | 8 | if [ -e "$framework_path/$framework" ]; then 9 | mkdir -p `dirname "$destination_framework"` 10 | exec ln -s "$framework_path/$framework" "$destination_framework" 11 | fi 12 | 13 | framework_name="${framework%.*}" 14 | 15 | if [ ! -e "$fallback_framework_path/$framework/$framework_name" ]; then 16 | echo "Missing private framework $framework for this target. Expected private frameworks at $1" 17 | exit 1 18 | fi 19 | 20 | echo "Generating $framework/$framework_name.tbd..." 21 | 22 | mkdir -p "$destination_framework" 23 | # I can't YAML 24 | ( 25 | echo '---' 26 | echo 'archs: [ armv7, armv7s, arm64 ]' 27 | echo 'platform: ios' 28 | echo "install-name: /System/Library/PrivateFrameworks/$framework/$framework_name" 29 | echo "exports:" 30 | echo ' - archs: [ armv7, armv7s, arm64 ]' 31 | printf ' symbols: [ ' 32 | nm -gUj "$fallback_framework_path/$framework/$framework_name" | sort | uniq | tr '\n' ',' | sed -e 's/,$/ ]/g' -e 's/,/, /g' 33 | echo '...' 34 | ) > "$destination_framework/$framework_name.tbd" 35 | -------------------------------------------------------------------------------- /bin/install.copyFile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ TARGET_INSTALL_REMOTE -eq 1 ]]; then 3 | scp -P $THEOS_DEVICE_PORT "$1" $THEOS_DEVICE_USER@$THEOS_DEVICE_IP:$2 4 | else 5 | cp "$1" "$2" 6 | fi 7 | -------------------------------------------------------------------------------- /bin/install.exec: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ TARGET_INSTALL_REMOTE -eq 1 ]]; then 3 | exec ssh -p $THEOS_DEVICE_PORT $THEOS_DEVICE_USER@$THEOS_DEVICE_IP "$@" 4 | else 5 | exec sh -c "$@" 6 | fi 7 | -------------------------------------------------------------------------------- /bin/install.mergeDir: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$1" 3 | # Use fakeroot.sh to ensure that permissions are preserved, and install.exec to ensure that we are running tar -x on the right system. 4 | fakeroot.sh -r tar -c . | install.exec "tar -x -C \"$2\"" 5 | -------------------------------------------------------------------------------- /bin/lib/Logos/Class.pm: -------------------------------------------------------------------------------- 1 | package Logos::Class; 2 | use strict; 3 | 4 | sub new { 5 | my $proto = shift; 6 | my $class = ref($proto) || $proto; 7 | my $self = {}; 8 | $self->{NAME} = undef; 9 | $self->{EXPR} = undef; 10 | $self->{METAEXPR} = undef; 11 | $self->{TYPE} = undef; 12 | $self->{META} = 0; 13 | $self->{INST} = 0; 14 | $self->{OVERRIDDEN} = 0; 15 | $self->{REQUIRED} = 0; 16 | $self->{METHODS} = []; 17 | $self->{NUM_METHODS} = 0; 18 | $self->{GROUP} = undef; 19 | bless($self, $class); 20 | return $self; 21 | } 22 | 23 | ##################### # 24 | # Setters and Getters # 25 | # ##################### 26 | sub name { 27 | my $self = shift; 28 | if(@_) { $self->{NAME} = shift; } 29 | return $self->{NAME}; 30 | } 31 | 32 | sub expression { 33 | my $self = shift; 34 | if(@_) { 35 | $self->{EXPR} = shift; 36 | $self->type("id"); 37 | $self->{OVERRIDDEN} = 1; 38 | } 39 | return $self->{EXPR}; 40 | } 41 | 42 | sub metaexpression { 43 | my $self = shift; 44 | if(@_) { 45 | $self->{METAEXPR} = shift; 46 | $self->{OVERRIDDEN} = 1; 47 | } 48 | return $self->{METAEXPR}; 49 | } 50 | 51 | sub type { 52 | my $self = shift; 53 | if(@_) { $self->{TYPE} = shift; } 54 | return $self->{TYPE} if $self->{TYPE}; 55 | return $self->{NAME}."*"; 56 | } 57 | 58 | sub hasmetahooks { 59 | my $self = shift; 60 | if(@_) { $self->{META} = shift; } 61 | return $self->{META}; 62 | } 63 | 64 | sub hasinstancehooks { 65 | my $self = shift; 66 | if(@_) { $self->{INST} = shift; } 67 | return $self->{INST}; 68 | } 69 | 70 | sub group { 71 | my $self = shift; 72 | if(@_) { $self->{GROUP} = shift; } 73 | return $self->{GROUP}; 74 | } 75 | 76 | sub required { 77 | my $self = shift; 78 | if(@_) { $self->{REQUIRED} = shift; } 79 | return $self->{REQUIRED}; 80 | } 81 | 82 | sub overridden { 83 | my $self = shift; 84 | return $self->{OVERRIDDEN}; 85 | } 86 | 87 | sub methods { 88 | my $self = shift; 89 | return $self->{METHODS}; 90 | } 91 | 92 | sub initRequired { 93 | my $self = shift; 94 | return $self->required || scalar @{$self->{METHODS}} > 0; 95 | } 96 | 97 | ##### # 98 | # END # 99 | # ##### 100 | 101 | sub addMethod { 102 | my $self = shift; 103 | my $hook = shift; 104 | push(@{$self->{METHODS}}, $hook); 105 | $self->{NUM_METHODS}++; 106 | } 107 | 108 | 1; 109 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator; 2 | use strict; 3 | use Logos::Generator::Thunk; 4 | use Scalar::Util qw(blessed); 5 | use Module::Load::Conditional qw(can_load); 6 | $Module::Load::Conditional::VERBOSE = 1; 7 | our $GeneratorPackage = ""; 8 | 9 | my %cache; 10 | 11 | sub for { 12 | my $object = shift; 13 | my $dequalified = undef; 14 | my $cachekey; 15 | if(defined $object) { 16 | $cachekey = $object; 17 | my $class = blessed($object); 18 | ($dequalified = $class) =~ s/.*::// if defined $class 19 | } 20 | $cachekey = "-" if !$cachekey; 21 | $dequalified .= "Generator" if !defined $dequalified; 22 | return $cache{$cachekey} if $cache{$cachekey}; 23 | 24 | my $qualified = $GeneratorPackage."::".$dequalified; 25 | my $fallback = "Logos::Generator::Base::".$dequalified; 26 | 27 | my $shouldFallBack = 0; 28 | can_load(modules=>{$qualified=>undef},verbose=>0) || ($shouldFallBack = 1); 29 | can_load(modules=>{$fallback=>undef},verbose=>1) if $shouldFallBack; 30 | 31 | my $thunk = Logos::Generator::Thunk->for(($shouldFallBack ? $fallback : $qualified), $object); 32 | $cache{$cachekey} = $thunk; 33 | return $thunk; 34 | } 35 | 36 | sub use { 37 | my $generatorName = shift; 38 | if($generatorName =~ /^(\w+)@(.+)$/) { 39 | $generatorName = $1; 40 | unshift @INC, $2; 41 | } 42 | $GeneratorPackage = "Logos::Generator::".$generatorName; 43 | ::fileError(-1, "I can't find the $generatorName Generator!") if(!can_load(modules => { 44 | $GeneratorPackage."::Generator" => undef 45 | })); 46 | } 47 | 48 | 1; 49 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Base/Class.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Base::Class; 2 | use Logos::Generator; 3 | use strict; 4 | 5 | sub _initExpression { 6 | my $self = shift; 7 | my $class = shift; 8 | return $class->expression if $class->expression; 9 | return "objc_getClass(\"".$class->name."\")"; 10 | } 11 | 12 | sub _metaInitExpression { 13 | my $self = shift; 14 | my $class = shift; 15 | return $class->metaexpression if $class->metaexpression; 16 | return "object_getClass(".$self->variable($class).")"; 17 | } 18 | 19 | 20 | sub variable { 21 | my $self = shift; 22 | my $class = shift; 23 | return Logos::sigil("class").$class->group->name."\$".$class->name; 24 | } 25 | 26 | sub metaVariable { 27 | my $self = shift; 28 | my $class = shift; 29 | return Logos::sigil("metaclass").$class->group->name."\$".$class->name; 30 | } 31 | 32 | sub declarations { 33 | my $self = shift; 34 | my $class = shift; 35 | my $return = ""; 36 | for(@{$class->methods}) { 37 | $return .= Logos::Generator::for($_)->declarations; 38 | } 39 | return $return; 40 | } 41 | 42 | sub initializers { 43 | my $self = shift; 44 | my $class = shift; 45 | my $return = ""; 46 | for(@{$class->methods}) { 47 | $return .= Logos::Generator::for($_)->initializers; 48 | } 49 | return $return; 50 | } 51 | 52 | 1; 53 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Base/Generator.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Base::Generator; 2 | use strict; 3 | 4 | sub findPreamble { 5 | my $self = shift; 6 | my $aref = shift; 7 | my @matches = grep(/\s*#\s*(import|include)\s*[<"]logos\/logos\.h[">]/, @$aref); 8 | return @matches > 0; 9 | } 10 | 11 | sub preamble { 12 | return "" 13 | } 14 | 15 | sub staticDeclarations { 16 | my $self = shift; 17 | return <classes}) { 9 | $return .= Logos::Generator::for($_)->declarations if $_->initRequired; 10 | } 11 | return $return; 12 | } 13 | 14 | sub initializers { 15 | my $self = shift; 16 | my $group = shift; 17 | my $return = "{"; 18 | foreach(@{$group->classes}) { 19 | $return .= Logos::Generator::for($_)->initializers if $_->initRequired; 20 | } 21 | $return .= "}"; 22 | return $return; 23 | } 24 | 25 | 1; 26 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Base/Method.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Base::Method; 2 | use strict; 3 | use Logos::Util; 4 | 5 | sub originalFunctionName { 6 | my $self = shift; 7 | my $method = shift; 8 | return Logos::sigil(($method->scope eq "+" ? "meta_" : "")."orig").$method->groupIdentifier."\$".$method->class->name."\$".$method->_new_selector; 9 | } 10 | 11 | sub newFunctionName { 12 | my $self = shift; 13 | my $method = shift; 14 | return Logos::sigil(($method->scope eq "+" ? "meta_" : "")."method").$method->groupIdentifier."\$".$method->class->name."\$".$method->_new_selector; 15 | } 16 | 17 | sub definition { 18 | ::fileError(-1, "generator does not implement Method::definition"); 19 | } 20 | 21 | sub originalCall { 22 | ::fileError(-1, "generator does not implement Method::originalCall"); 23 | } 24 | 25 | sub selectorRef { 26 | my $self = shift; 27 | my $selector = shift; 28 | if ($selector eq "dealloc") { 29 | return "sel_registerName(\"".$selector."\")"; 30 | } 31 | return "\@selector(".$selector.")"; 32 | } 33 | 34 | sub selfTypeForMethod { 35 | my $self = shift; 36 | my $method = shift; 37 | if($method->scope eq "+") { 38 | return "_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST"; 39 | } 40 | if($method->methodFamily eq "init") { 41 | return "_LOGOS_SELF_TYPE_INIT ".$method->class->type; 42 | } 43 | return "_LOGOS_SELF_TYPE_NORMAL ".$method->class->type." _LOGOS_SELF_CONST"; 44 | } 45 | 46 | sub returnTypeForMethod { 47 | my $self = shift; 48 | my $method = shift; 49 | if($method->methodFamily ne "") { 50 | return $method->class->type; 51 | } 52 | my $result = $method->return; 53 | if ($result eq "instancetype") { 54 | return $method->class->type; 55 | } 56 | return $result; 57 | } 58 | 59 | sub functionAttributesForMethod { 60 | my $self = shift; 61 | my $method = shift; 62 | if($method->methodFamily ne "") { 63 | return " _LOGOS_RETURN_RETAINED"; 64 | } 65 | return ""; 66 | } 67 | 68 | sub buildLogCall { 69 | my $self = shift; 70 | my $method = shift; 71 | my $args = shift; 72 | # Log preamble 73 | my $build = "NSLog(\@\"".$method->scope."[<".$method->class->name.": %p>"; 74 | my $argnamelist = ""; 75 | if($method->numArgs > 0) { 76 | # For each argument, add its keyword and a format char to the log string. 77 | map $build .= " ".$method->selectorParts->[$_].":".Logos::Method::formatCharForArgType($method->argtypes->[$_]), (0..$method->numArgs - 1); 78 | # This builds a list of args by making sure the format char isn't -- (or, what we're using for non-operational types) 79 | # Map (in list context) "format char == -- ? nothing : arg name" over the indices of the arg list. 80 | my @newarglist = map(Logos::Method::printArgForArgType($method->argtypes->[$_], $method->argnames->[$_]), (0..$method->numArgs - 1)); 81 | my @existingargs = grep(defined($_), @newarglist); 82 | if(scalar(@existingargs) > 0) { 83 | $argnamelist = ", ".join(", ", grep(defined($_), @existingargs)); 84 | } 85 | } else { 86 | # Space and then the only keyword in the selector. 87 | $build .= " ".$method->selector; 88 | } 89 | 90 | my @extraFormatSpecifiers; 91 | my @extraArguments; 92 | for(Logos::Util::smartSplit(qr/\s*,\s*/, $args)) { 93 | my ($popen, $pclose) = matchedParenthesisSet($_); 94 | my $type = "id"; 95 | if(defined $popen) { 96 | $type = substr($_, $popen, $pclose-$popen-1); 97 | } 98 | push(@extraFormatSpecifiers, Logos::Method::formatCharForArgType($type)); 99 | my $n = Logos::Method::printArgForArgType($type, "($_)"); 100 | push(@extraArguments, $n) if $n; 101 | } 102 | 103 | # Log postamble 104 | $build .= "]"; 105 | $build .= ": ".join(", ", @extraFormatSpecifiers) if @extraFormatSpecifiers > 0; 106 | $build .= "\", self".$argnamelist; 107 | $build .= ", ".join(", ", @extraArguments) if @extraArguments > 0; 108 | $build .= ")"; 109 | } 110 | 111 | sub declarations { 112 | ::fileError(-1, "generator does not implement Method::declarations"); 113 | } 114 | 115 | sub initializers { 116 | ::fileError(-1, "generator does not implement Method::initializers"); 117 | } 118 | 119 | 1; 120 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Base/StaticClassGroup.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Base::StaticClassGroup; 2 | use strict; 3 | 4 | sub _methodForClassWithScope { 5 | my $self = shift; 6 | my $class = shift; 7 | my $scope = shift; 8 | my $return = ""; 9 | my $methodname = Logos::sigil($scope eq "+" ? "static_metaclass_lookup" : "static_class_lookup").$class; 10 | my $lookupMethod = $scope eq "+" ? "objc_getMetaClass" : "objc_getClass"; 11 | 12 | # This is a dirty assumption - we believe that we will always be using a compiler that defines __GNUC__ and respects GNU C attributes. 13 | return "static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class ".$methodname."(void) { static Class _klass; if(!_klass) { _klass = ".$lookupMethod."(\"".$class."\"); } return _klass; }"; 14 | } 15 | 16 | sub declarations { 17 | my $self = shift; 18 | my $group = shift; 19 | my $return = ""; 20 | return "" if scalar(keys %{$group->usedMetaClasses}) + scalar(keys %{$group->usedClasses}) + scalar(keys %{$group->declaredOnlyClasses}) == 0; 21 | foreach(keys %{$group->usedMetaClasses}) { 22 | $return .= $self->_methodForClassWithScope($_, "+"); 23 | } 24 | foreach(keys %{$group->usedClasses}) { 25 | $return .= $self->_methodForClassWithScope($_, "-"); 26 | } 27 | return $return; 28 | } 29 | 30 | sub initializers { 31 | return ""; 32 | } 33 | 34 | 1; 35 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Base/Subclass.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Base::Subclass; 2 | use strict; 3 | 4 | sub declarations { 5 | ::fileError(-1, "generator does not implement Subclass::declarations"); 6 | } 7 | 8 | sub initializers { 9 | ::fileError(-1, "generator does not implement Subclass::initializers"); 10 | } 11 | 12 | 1; 13 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/MobileSubstrate/Class.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::MobileSubstrate::Class; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Class); 4 | 5 | sub initializers { 6 | my $self = shift; 7 | my $class = shift; 8 | my $return = ""; 9 | if($class->required || $class->overridden || $class->hasinstancehooks || $class->hasmetahooks) { 10 | $return .= "Class ".$self->variable($class)." = ".$self->_initExpression($class)."; "; 11 | } 12 | if($class->hasmetahooks) { 13 | $return .= "Class ".$self->metaVariable($class)." = ".$self->_metaInitExpression($class)."; "; 14 | } 15 | $return .= $self->SUPER::initializers($class); 16 | return $return; 17 | } 18 | 19 | 1; 20 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/MobileSubstrate/Generator.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::MobileSubstrate::Generator; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Generator); 4 | 5 | sub findPreamble { 6 | my $self = shift; 7 | my $aref = shift; 8 | my @matches = grep(/\s*#\s*(import|include)\s*[<"]substrate\.h[">]/, @$aref); 9 | return $self->SUPER::findPreamble($aref) && @matches > 0; 10 | } 11 | 12 | sub preamble { 13 | my $self = shift; 14 | my $skipIncludes = shift; 15 | if ($skipIncludes) { 16 | return $self->SUPER::preamble(); 17 | } else { 18 | return join("\n", ($self->SUPER::preamble(), "#include ")); 19 | } 20 | } 21 | 22 | 1; 23 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/MobileSubstrate/Method.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::MobileSubstrate::Method; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Method); 4 | 5 | sub _originalMethodPointerDeclaration { 6 | my $self = shift; 7 | my $method = shift; 8 | if(!$method->isNew) { 9 | my $build = "static "; 10 | my $classargtype = $self->selfTypeForMethod($method); 11 | my $name = "(*".$self->originalFunctionName($method).")(".$classargtype.", SEL"; 12 | my $argtypelist = join(", ", @{$method->argtypes}); 13 | $name .= ", ".$argtypelist if $argtypelist; 14 | 15 | $name .= ")"; 16 | $build .= Logos::Method::declarationForTypeWithName($self->returnTypeForMethod($method), $name); 17 | $build .= $self->functionAttributesForMethod($method); 18 | return $build; 19 | } 20 | return undef; 21 | } 22 | 23 | sub _methodPrototype { 24 | my $self = shift; 25 | my $method = shift; 26 | my $includeArgNames = 0 || shift; 27 | my $build = "static "; 28 | my $classargtype = $self->selfTypeForMethod($method); 29 | my $arglist = ""; 30 | if($includeArgNames == 1) { 31 | map $arglist .= ", ".Logos::Method::declarationForTypeWithName($method->argtypes->[$_], $method->argnames->[$_]), (0..$method->numArgs - 1); 32 | } else { 33 | my $typelist = join(", ", @{$method->argtypes}); 34 | $arglist = ", ".$typelist if $typelist; 35 | } 36 | 37 | my $name = $self->newFunctionName($method)."(".$classargtype.($includeArgNames?" self":"").", SEL".($includeArgNames?" _cmd":"").$arglist.")"; 38 | $build .= Logos::Method::declarationForTypeWithName($self->returnTypeForMethod($method), $name); 39 | $build .= $self->functionAttributesForMethod($method); 40 | return $build; 41 | } 42 | 43 | sub definition { 44 | my $self = shift; 45 | my $method = shift; 46 | my $build = ""; 47 | $build .= $self->_methodPrototype($method, 1); 48 | return $build; 49 | } 50 | 51 | sub originalCall { 52 | my $self = shift; 53 | my $method = shift; 54 | my $customargs = shift; 55 | return "" if $method->isNew; 56 | 57 | my $build = $self->originalFunctionName($method)."(self, _cmd"; 58 | if(defined $customargs && $customargs ne "") { 59 | $build .= ", ".$customargs; 60 | } elsif($method->numArgs > 0) { 61 | $build .= ", ".join(", ",@{$method->argnames}); 62 | } 63 | $build .= ")"; 64 | return $build; 65 | } 66 | 67 | sub declarations { 68 | my $self = shift; 69 | my $method = shift; 70 | my $build = ""; 71 | my $orig = $self->_originalMethodPointerDeclaration($method); 72 | $build .= $orig."; " if $orig; 73 | $build .= $self->_methodPrototype($method)."; "; 74 | return $build; 75 | } 76 | 77 | sub initializers { 78 | my $self = shift; 79 | my $method = shift; 80 | my $cgen = Logos::Generator::for($method->class); 81 | my $classvar = ($method->scope eq "+" ? $cgen->metaVariable : $cgen->variable); 82 | if(!$method->isNew) { 83 | return "MSHookMessageEx(".$classvar.", ".$self->selectorRef($method->selector).", (IMP)&".$self->newFunctionName($method).", (IMP*)&".$self->originalFunctionName($method).");"; 84 | } else { 85 | my $r = ""; 86 | $r .= "{ "; 87 | if(!$method->type) { 88 | $r .= "char _typeEncoding[1024]; unsigned int i = 0; "; 89 | for ($method->return, "id", "SEL", @{$method->argtypes}) { 90 | my $typeEncoding = Logos::Method::typeEncodingForArgType($_); 91 | if(defined $typeEncoding) { 92 | my @typeEncodingBits = split(//, $typeEncoding); 93 | my $i = 0; 94 | for my $char (@typeEncodingBits) { 95 | $r .= "_typeEncoding[i".($i > 0 ? " + $i" : "")."] = '$char'; "; 96 | $i++; 97 | } 98 | $r .= "i += ".(scalar @typeEncodingBits)."; "; 99 | } else { 100 | $r .= "memcpy(_typeEncoding + i, \@encode($_), strlen(\@encode($_))); i += strlen(\@encode($_)); "; 101 | } 102 | } 103 | $r .= "_typeEncoding[i] = '\\0'; "; 104 | } else { 105 | $r .= "const char *_typeEncoding = \"".$method->type."\"; "; 106 | } 107 | $r .= "class_addMethod(".$classvar.", ".$self->selectorRef($method->selector).", (IMP)&".$self->newFunctionName($method).", _typeEncoding); "; 108 | $r .= "}"; 109 | return $r; 110 | } 111 | } 112 | 113 | 1; 114 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/MobileSubstrate/Subclass.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::MobileSubstrate::Subclass; 2 | use strict; 3 | use parent qw(Logos::Generator::MobileSubstrate::Class); 4 | 5 | # declarations is inherited from Class. 6 | 7 | sub _initExpression { 8 | my $self = shift; 9 | my $class = shift; 10 | my $cgen = Logos::Generator::for($class->superclass); 11 | return "objc_allocateClassPair(".$cgen->variable.", \"".$class->name."\", 0); objc_registerClassPair(".$self->variable($class).")"; 12 | } 13 | 14 | sub initializers { 15 | my $self = shift; 16 | my $class = shift; 17 | my $return = ""; 18 | $return .= "{ "; 19 | $return .= $self->SUPER::initializers($class)." "; 20 | # 21 | foreach(@{$class->ivars}) { 22 | $return .= Logos::Generator::for($_)->initializers; 23 | } 24 | # 25 | foreach(keys %{$class->protocols}) { 26 | $return .= "class_addProtocol(".$self->variable($class).", objc_getProtocol(\"$_\")); "; 27 | } 28 | $return .= "}"; 29 | return $return; 30 | } 31 | 32 | 1; 33 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/Thunk.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::Thunk; 2 | use strict; 3 | 4 | our $AUTOLOAD; 5 | 6 | my %subrefCache; 7 | 8 | sub AUTOLOAD { 9 | my $self = shift; 10 | my $method = $AUTOLOAD; 11 | return if $method eq "DESTROY"; 12 | 13 | $method =~ s/.*:://; 14 | my $fullyQualified = $self->{PACKAGE}."::".$method; 15 | my $subref = $subrefCache{$fullyQualified}; 16 | 17 | $subref = $self->can($method) if !$subref; 18 | 19 | unshift @_, $self->{OBJECT} if $self->{OBJECT}; 20 | goto &$subref; 21 | } 22 | 23 | sub can { 24 | my $self = shift; 25 | my $method = shift; 26 | my $subref = $self->SUPER::can($method); 27 | return $subref if $subref; 28 | 29 | $method =~ s/.*:://; 30 | my $fullyQualified = $self->{PACKAGE}."::".$method; 31 | return $subrefCache{$fullyQualified} if $subrefCache{$fullyQualified}; 32 | 33 | $subref = sub {unshift @_, $self->{PACKAGE}; goto &{$self->{PACKAGE}->can($method)}}; 34 | $subrefCache{$fullyQualified} = $subref; 35 | 36 | return $subref; 37 | } 38 | 39 | sub DESTROY { 40 | my $self = shift; 41 | $self->SUPER::destroy(); 42 | } 43 | 44 | sub for { 45 | my $proto = shift; 46 | my $class = ref($proto) || $proto; 47 | my $self = {}; 48 | $self->{PACKAGE} = shift; 49 | $self->{OBJECT} = shift; 50 | bless($self, $class); 51 | return $self; 52 | } 53 | 54 | 1; 55 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/internal/Class.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::internal::Class; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Class); 4 | 5 | sub superVariable { 6 | my $self = shift; 7 | my $class = shift; 8 | return Logos::sigil("superclass").$class->group->name."\$".$class->name; 9 | } 10 | 11 | sub superMetaVariable { 12 | my $self = shift; 13 | my $class = shift; 14 | return Logos::sigil("supermetaclass").$class->group->name."\$".$class->name; 15 | } 16 | 17 | sub declarations { 18 | my $self = shift; 19 | my $class = shift; 20 | my $return = ""; 21 | if($class->hasinstancehooks) { 22 | $return .= "static Class ".$self->superVariable($class)."; "; 23 | } 24 | if($class->hasmetahooks) { 25 | $return .= "static Class ".$self->superMetaVariable($class)."; "; 26 | } 27 | $return .= $self->SUPER::declarations($class); 28 | return $return; 29 | } 30 | 31 | sub initializers { 32 | my $self = shift; 33 | my $class = shift; 34 | my $return = ""; 35 | if($class->required || $class->overridden || $class->hasinstancehooks || $class->hasmetahooks) { 36 | $return .= "Class ".$self->variable($class)." = ".$self->_initExpression($class)."; "; 37 | } 38 | if($class->hasmetahooks) { 39 | $return .= "Class ".$self->metaVariable($class)." = ".$self->_metaInitExpression($class)."; "; 40 | } 41 | if ($class->hasinstancehooks) { 42 | $return .= $self->superVariable($class)." = class_getSuperclass(".$self->variable($class)."); "; 43 | } 44 | if ($class->hasmetahooks) { 45 | $return .= $self->superMetaVariable($class)." = class_getSuperclass(".$self->metaVariable($class)."); "; 46 | } 47 | $return .= $self->SUPER::initializers($class); 48 | return $return; 49 | } 50 | 51 | 1; 52 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/internal/Generator.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::internal::Generator; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Generator); 4 | 5 | sub findPreamble { 6 | my $self = shift; 7 | my $aref = shift; 8 | my @matches = grep(/\s*#\s*(import|include)\s*[<"]objc\/message\.h[">]/, @$aref); 9 | return $self->SUPER::findPreamble($aref) && @matches > 0; 10 | } 11 | 12 | sub preamble { 13 | my $self = shift; 14 | return join("\n", ( 15 | $self->SUPER::preamble(), 16 | "#include " 17 | )); 18 | } 19 | 20 | sub staticDeclarations { 21 | my $self = shift; 22 | return join("\n", ($self->SUPER::staticDeclarations(), 23 | "__attribute__((unused)) static void ".Logos::sigil("register_hook")."(Class _class, SEL _cmd, IMP _new, IMP *_old) {", 24 | "unsigned int _count, _i;", 25 | "Class _searchedClass = _class;", 26 | "Method *_methods;", 27 | "while (_searchedClass) {", 28 | "_methods = class_copyMethodList(_searchedClass, &_count);", 29 | "for (_i = 0; _i < _count; _i++) {", 30 | "if (method_getName(_methods[_i]) == _cmd) {", 31 | "if (_class == _searchedClass) {", 32 | "*_old = method_getImplementation(_methods[_i]);", 33 | "*_old = method_setImplementation(_methods[_i], _new);", 34 | "} else {", 35 | "class_addMethod(_class, _cmd, _new, method_getTypeEncoding(_methods[_i]));", 36 | "}", 37 | "free(_methods);", 38 | "return;", 39 | "}", 40 | "}", 41 | "free(_methods);", 42 | "_searchedClass = class_getSuperclass(_searchedClass);", 43 | "}", 44 | "}")); 45 | } 46 | 47 | 1; 48 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/internal/Method.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::internal::Method; 2 | use strict; 3 | use parent qw(Logos::Generator::Base::Method); 4 | 5 | sub originalCallParams { 6 | my $self = shift; 7 | my $method = shift; 8 | my $customargs = shift; 9 | return "" if $method->isNew; 10 | 11 | my $build = "(self, _cmd"; 12 | if(defined $customargs && $customargs ne "") { 13 | $build .= ", ".$customargs; 14 | } elsif($method->numArgs > 0) { 15 | $build .= ", ".join(", ",@{$method->argnames}); 16 | } 17 | $build .= ")"; 18 | return $build; 19 | } 20 | 21 | sub definition { 22 | my $self = shift; 23 | my $method = shift; 24 | my $build = ""; 25 | my $selftype = $self->selfTypeForMethod($method); 26 | my $classref = ""; 27 | my $cgen = Logos::Generator::for($method->class); 28 | if($method->scope eq "+") { 29 | $classref = $cgen->superMetaVariable; 30 | } else { 31 | $classref = $cgen->superVariable; 32 | } 33 | my $arglist = ""; 34 | map $arglist .= ", ".Logos::Method::declarationForTypeWithName($method->argtypes->[$_], $method->argnames->[$_]), (0..$method->numArgs - 1); 35 | my $functionAttributes = $self->functionAttributesForMethod($method); 36 | my $return = $self->returnTypeForMethod($method); 37 | my $parameters = "(".$selftype." self, SEL _cmd".$arglist.")"; 38 | $build .= "static ".Logos::Method::declarationForTypeWithName($return, $self->newFunctionName($method).$parameters).$functionAttributes; 39 | return $build; 40 | } 41 | 42 | sub originalCall { 43 | my $self = shift; 44 | my $method = shift; 45 | my $customargs = shift; 46 | my $classargtype = ""; 47 | my $classref = ""; 48 | my $cgen = Logos::Generator::for($method->class); 49 | if($method->scope eq "+") { 50 | $classargtype = "Class"; 51 | $classref = $cgen->superMetaVariable; 52 | } else { 53 | $classargtype = $method->class->type; 54 | $classref = $cgen->superVariable; 55 | } 56 | my $argtypelist = join(", ", @{$method->argtypes}); 57 | my $pointerType = "(*)(".$classargtype.", SEL"; 58 | $pointerType .= ", ".$argtypelist if $argtypelist; 59 | $pointerType .= ")"; 60 | return "(".$self->originalFunctionName($method)." ? ".$self->originalFunctionName($method)." : (__typeof__(".$self->originalFunctionName($method)."))class_getMethodImplementation(".$classref.", \@selector(".$method->selector.")))".$self->originalCallParams($method, $customargs); 61 | } 62 | 63 | sub declarations { 64 | my $self = shift; 65 | my $method = shift; 66 | my $build = ""; 67 | if(!$method->isNew) { 68 | my $selftype = $self->selfTypeForMethod($method); 69 | my $functionAttributes = $self->functionAttributesForMethod($method); 70 | $build .= "static "; 71 | my $name = ""; 72 | $name .= $functionAttributes."(*".$self->originalFunctionName($method).")(".$selftype.", SEL"; 73 | my $argtypelist = join(", ", @{$method->argtypes}); 74 | $name .= ", ".$argtypelist if $argtypelist; 75 | $name .= ")"; 76 | $build .= Logos::Method::declarationForTypeWithName($self->returnTypeForMethod($method), $name); 77 | $build .= ";"; 78 | } 79 | return $build; 80 | } 81 | 82 | sub initializers { 83 | my $self = shift; 84 | my $method = shift; 85 | my $cgen = Logos::Generator::for($method->class); 86 | my $classvar = ($method->scope eq "+" ? $cgen->metaVariable : $cgen->variable); 87 | my $r = "{ "; 88 | if(!$method->isNew) { 89 | $r .= Logos::sigil("register_hook") . "(" . $classvar . ", ".$self->selectorRef($method->selector).", (IMP)&".$self->newFunctionName($method).", (IMP *)&" . $self->originalFunctionName($method) . ");"; 90 | } else { 91 | if(!$method->type) { 92 | $r .= "char _typeEncoding[1024]; unsigned int i = 0; "; 93 | for ($method->return, "id", "SEL", @{$method->argtypes}) { 94 | my $typeEncoding = Logos::Method::typeEncodingForArgType($_); 95 | if(defined $typeEncoding) { 96 | my @typeEncodingBits = split(//, $typeEncoding); 97 | my $i = 0; 98 | for my $char (@typeEncodingBits) { 99 | $r .= "_typeEncoding[i".($i > 0 ? " + $i" : "")."] = '$char'; "; 100 | $i++; 101 | } 102 | $r .= "i += ".(scalar @typeEncodingBits)."; "; 103 | } else { 104 | $r .= "memcpy(_typeEncoding + i, \@encode($_), strlen(\@encode($_))); i += strlen(\@encode($_)); "; 105 | } 106 | } 107 | $r .= "_typeEncoding[i] = '\\0'; "; 108 | } else { 109 | $r .= "const char *_typeEncoding = \"".$method->type."\"; "; 110 | } 111 | $r .= "class_addMethod(".$classvar.", ".$self->selectorRef($method->selector).", (IMP)&".$self->newFunctionName($method).", _typeEncoding); "; 112 | } 113 | $r .= "}"; 114 | return $r; 115 | } 116 | 117 | 1; 118 | -------------------------------------------------------------------------------- /bin/lib/Logos/Generator/internal/Subclass.pm: -------------------------------------------------------------------------------- 1 | package Logos::Generator::internal::Subclass; 2 | use strict; 3 | use parent qw(Logos::Generator::internal::Class); 4 | 5 | # declarations is inherited from Class. 6 | 7 | sub _initExpression { 8 | my $self = shift; 9 | my $class = shift; 10 | my $cgen = Logos::Generator::for($class->superclass); 11 | return "objc_allocateClassPair(".$cgen->variable.", \"".$class->name."\", 0)"; 12 | } 13 | 14 | sub initializers { 15 | my $self = shift; 16 | my $class = shift; 17 | my $return = ""; 18 | $return .= "{ "; 19 | $return .= $self->SUPER::initializers($class)." "; 20 | # 21 | foreach(@{$class->ivars}) { 22 | $return .= Logos::Generator::for($_)->initializers; 23 | } 24 | # 25 | $return .= "objc_registerClassPair(".$self->variable($class)."); "; 26 | foreach(keys %{$class->protocols}) { 27 | $return .= "class_addProtocol(".$self->variable($class).", objc_getProtocol(\"$_\")); "; 28 | } 29 | $return .= "}"; 30 | return $return; 31 | } 32 | 33 | 1; 34 | -------------------------------------------------------------------------------- /bin/lib/Logos/Group.pm: -------------------------------------------------------------------------------- 1 | package Logos::Group; 2 | use strict; 3 | 4 | sub new { 5 | my $proto = shift; 6 | my $class = ref($proto) || $proto; 7 | my $self = {}; 8 | $self->{NAME} = undef; 9 | $self->{EXPLICIT} = 1; 10 | $self->{INITIALIZED} = 0; 11 | $self->{INITLINE} = -1; 12 | $self->{CLASSES} = []; 13 | bless($self, $class); 14 | return $self; 15 | } 16 | 17 | ##################### # 18 | # Setters and Getters # 19 | # ##################### 20 | sub name { 21 | my $self = shift; 22 | if(@_) { $self->{NAME} = shift; } 23 | return $self->{NAME}; 24 | } 25 | 26 | sub explicit { 27 | my $self = shift; 28 | if(@_) { $self->{EXPLICIT} = shift; } 29 | return $self->{EXPLICIT}; 30 | } 31 | 32 | sub initialized { 33 | my $self = shift; 34 | if(@_) { $self->{INITIALIZED} = shift; } 35 | return $self->{INITIALIZED}; 36 | } 37 | 38 | sub initRequired { 39 | my $self = shift; 40 | for(@{$self->{CLASSES}}) { 41 | return 1 if $_->initRequired; 42 | } 43 | return 0; 44 | } 45 | 46 | sub identifier { 47 | my $self = shift; 48 | return main::sanitize($self->{NAME}); 49 | } 50 | 51 | sub initLine { 52 | my $self = shift; 53 | if(@_) { $self->{INITLINE} = shift; } 54 | return $self->{INITLINE}; 55 | } 56 | 57 | sub classes { 58 | my $self = shift; 59 | return $self->{CLASSES}; 60 | } 61 | ##### # 62 | # END # 63 | # ##### 64 | 65 | sub addClass { 66 | my $self = shift; 67 | my $class = shift; 68 | $class->group($self); 69 | push(@{$self->{CLASSES}}, $class); 70 | } 71 | 72 | sub addClassNamed { 73 | my $self = shift; 74 | my $name = shift; 75 | 76 | my $class = $self->getClassNamed($name); 77 | return $class if defined($class); 78 | 79 | $class = ::Class()->new(); 80 | $class->name($name); 81 | $self->addClass($class); 82 | return $class; 83 | } 84 | 85 | sub getClassNamed { 86 | my $self = shift; 87 | my $name = shift; 88 | foreach(@{$self->{CLASSES}}) { 89 | return $_ if $_->name eq $name; 90 | } 91 | return undef; 92 | } 93 | 94 | 1; 95 | -------------------------------------------------------------------------------- /bin/lib/Logos/Ivar.pm: -------------------------------------------------------------------------------- 1 | package Logos::Ivar; 2 | use strict; 3 | 4 | sub new { 5 | my $proto = shift; 6 | my $class = ref($proto) || $proto; 7 | my $self = {}; 8 | $self->{NAME} = shift; 9 | $self->{TYPE} = shift; 10 | $self->{CLASS} = undef; 11 | bless($self, $class); 12 | return $self; 13 | } 14 | 15 | ##################### # 16 | # Setters and Getters # 17 | # ##################### 18 | sub name { 19 | my $self = shift; 20 | if(@_) { $self->{NAME} = shift; } 21 | return $self->{NAME}; 22 | } 23 | 24 | sub type { 25 | my $self = shift; 26 | if(@_) { $self->{TYPE} = shift; } 27 | return $self->{TYPE}; 28 | } 29 | 30 | sub class { 31 | my $self = shift; 32 | if(@_) { $self->{CLASS} = shift; } 33 | return $self->{CLASS}; 34 | } 35 | ##### # 36 | # END # 37 | # ##### 38 | 39 | 1; 40 | -------------------------------------------------------------------------------- /bin/lib/Logos/Method.pm: -------------------------------------------------------------------------------- 1 | package Logos::Method; 2 | use strict; 3 | use Logos::Util qw(matchedParenthesisSet); 4 | 5 | sub new { 6 | my $proto = shift; 7 | my $class = ref($proto) || $proto; 8 | my $self = {}; 9 | $self->{CLASS} = undef; 10 | $self->{SCOPE} = undef; 11 | $self->{RETURN} = undef; 12 | $self->{SELECTOR_PARTS} = []; 13 | $self->{ARGNAMES} = []; 14 | $self->{ARGTYPES} = []; 15 | $self->{NEW} = 0; 16 | $self->{TYPE} = ""; 17 | bless($self, $class); 18 | return $self; 19 | } 20 | 21 | ##################### # 22 | # Setters and Getters # 23 | # ##################### 24 | sub class { 25 | my $self = shift; 26 | if(@_) { $self->{CLASS} = shift; } 27 | return $self->{CLASS}; 28 | } 29 | 30 | sub scope { 31 | my $self = shift; 32 | if(@_) { $self->{SCOPE} = shift; } 33 | return $self->{SCOPE}; 34 | } 35 | 36 | sub return { 37 | my $self = shift; 38 | if(@_) { $self->{RETURN} = shift; } 39 | return $self->{RETURN}; 40 | } 41 | 42 | sub groupIdentifier { 43 | my $self = shift; 44 | return $self->class->group->identifier; 45 | } 46 | 47 | sub selectorParts { 48 | my $self = shift; 49 | if(@_) { @{$self->{SELECTOR_PARTS}} = @_; } 50 | return $self->{SELECTOR_PARTS}; 51 | } 52 | 53 | sub setNew { 54 | my $self = shift; 55 | if(@_) { $self->{NEW} = shift; } 56 | return $self->{NEW}; 57 | } 58 | 59 | sub isNew { 60 | my $self = shift; 61 | return $self->{NEW}; 62 | } 63 | 64 | sub type { 65 | my $self = shift; 66 | if(@_) { $self->{TYPE} = shift; } 67 | return $self->{TYPE}; 68 | } 69 | 70 | sub argnames { 71 | my $self = shift; 72 | return $self->{ARGNAMES}; 73 | } 74 | 75 | sub argtypes { 76 | my $self = shift; 77 | return $self->{ARGTYPES}; 78 | } 79 | ##### # 80 | # END # 81 | # ##### 82 | 83 | sub numArgs { 84 | my $self = shift; 85 | return scalar @{$self->{ARGTYPES}}; 86 | } 87 | 88 | sub addArgument { 89 | my $self = shift; 90 | my ($type, $name) = @_; 91 | push(@{$self->{ARGTYPES}}, $type); 92 | push(@{$self->{ARGNAMES}}, $name); 93 | } 94 | 95 | sub selector { 96 | my $self = shift; 97 | if($self->numArgs == 0) { 98 | return $self->{SELECTOR_PARTS}[0]; 99 | } else { 100 | return join(":", @{$self->{SELECTOR_PARTS}}).":"; 101 | } 102 | } 103 | 104 | sub _new_selector { 105 | my $self = shift; 106 | if($self->numArgs == 0) { 107 | return $self->{SELECTOR_PARTS}[0]; 108 | } else { 109 | return join("\$", @{$self->{SELECTOR_PARTS}})."\$"; 110 | } 111 | } 112 | 113 | sub methodFamily { 114 | my $self = shift; 115 | my $selector = $self->selector; 116 | if ($self->scope eq "+") { 117 | if ($selector =~ /^alloc($|[A-Z,:])/) { 118 | return "alloc" if $self->return eq "id" || $self->return eq "instancetype"; 119 | } 120 | if ($selector eq "new") { 121 | return "new" if $self->return eq "id" || $self->return eq "instancetype"; 122 | } 123 | } else { 124 | if ($selector =~ /^init($|[A-Z,:])/) { 125 | return "init" if $self->return eq "id" || $self->return eq "instancetype"; 126 | } 127 | if (($selector eq "copy") || ($selector eq "copyWithZone:")) { 128 | return "copy"; 129 | } 130 | if (($selector eq "mutableCopy") || ($selector eq "mutableCopyWithZone:")) { 131 | return "mutableCopy"; 132 | } 133 | } 134 | return ""; 135 | } 136 | 137 | sub printArgForArgType { 138 | my $argtype = shift; 139 | my $argname = shift; 140 | 141 | my ($formatchar, $fallthrough) = formatCharForArgType($argtype); 142 | return undef if $formatchar eq "--"; 143 | 144 | $argtype =~ s/^\s+//g; 145 | $argtype =~ s/\s+$//g; 146 | 147 | return "NSStringFromSelector($argname)" if $argtype =~ /^SEL$/; 148 | return "$argname.location, $argname.length" if $argtype =~ /^NSRange$/; 149 | return "$argname.origin.x, $argname.origin.y, $argname.size.width, $argname.size.height" if $argtype =~ /^(CG|NS)Rect$/; 150 | return "$argname.x, $argname.y" if $argtype =~ /^(CG|NS)Point$/; 151 | return "$argname.width, $argname.height" if $argtype =~ /^(CG|NS)Size$/; 152 | return "(long)$argname" if $argtype =~ /^NS(Integer|SocketNativeHandle|StringEncoding|SortOptions|ComparisonResult|EnumerationOptions|(Hash|Map)TableOptions|SearchPath(Directory|DomainMask))$/i; 153 | return "(unsigned long)$argname" if $argtype =~ /^NSUInteger$/i; 154 | 155 | return ($fallthrough ? "(unsigned int)" : "").$argname; 156 | } 157 | 158 | sub formatCharForArgType { 159 | local $_ = shift; 160 | s/^\s+//g; 161 | s/\s+$//g; 162 | 163 | # Integral Types 164 | # Straight characters get %c. Signed/Unsigned characters get %hhu/%hhd. 165 | return "'%c'" if /^char$/; 166 | if(/^((signed|unsigned)\s+)?(unsigned|signed|int|long|long\s+long|bool|BOOL|_Bool|char|short)$/) { 167 | my $conversion = "d"; 168 | $conversion = "u" if /\bunsigned\b/; 169 | 170 | my $length; 171 | $length = "" if /\bint\b/; 172 | $length = "l" if /\blong\b/; 173 | $length = "ll" if /\blong long\b/; 174 | $length = "h" if /\bshort\b/; 175 | $length = "hh" if /\bchar\b/; 176 | 177 | return "%".$length.$conversion; 178 | } 179 | return "%ld" if /^NS(Integer|SocketNativeHandle|StringEncoding|SortOptions|ComparisonResult|EnumerationOptions|(Hash|Map)TableOptions|SearchPath(Directory|DomainMask))$/i; 180 | return "%lu" if /^NSUInteger$/i; 181 | return "%d" if /^GS(FontTraitMask)$/i; 182 | 183 | # Pointer Types 184 | return "%s" if /^char\s*\*$/; 185 | return "%p" if /^void\s*\*$/; # void * 186 | return "%p" if /^id\s*\*$/; # id * 187 | return "%p" if /^((unsigned|signed)\s+)?(unsigned|signed|int|long|long\s+long|bool|BOOL|_Bool|char|short|float|double)\s*\*+$/; 188 | return "%p" if /^NS.*?(Pointer|Array)$/; 189 | return "%p" if /^NSZone\s*\*$/; 190 | return "%p" if /^struct.*\*$/; # struct pointer 191 | return "%p" if /\*\*+$/; # anything with more than one pointer indirection 192 | return "%p" if /\[.*\]$/; # any array 193 | 194 | # Objects 195 | return "%@" if /^id$/; # id is an objc_object. 196 | return "%@" if /^\w+\s*\*$/; # try to treat *any* other pointer as an objc_object. 197 | return "%@" if /^\w+Ref$/; # *Ref can be printed with %@. 198 | 199 | # Floating-Point Types 200 | return "%f" if /^(double|float|CGFloat|CGDouble|NSTimeInterval)$/; 201 | 202 | # Special Types (should also have an entry in printArgForArgType 203 | return "%@" if /^SEL$/; 204 | 205 | # Even-more-special expanded types 206 | return "(%d:%d)" if /^NSRange$/; 207 | return "{{%g, %g}, {%g, %g}}" if /^(CG|NS)Rect$/; 208 | return "{%g, %g}" if /^(CG|NS)Point$/; 209 | return "{%g, %g}" if /^(CG|NS)Size$/; 210 | 211 | # Discarded Types 212 | return "--" if /^(CG\w*|CF\w*|void)$/; 213 | return "--" if /^NS(HashTable(Callbacks)?|Map(Table((Key|Value)Callbacks)?|Enumerator))$/; 214 | return "--" if /^struct/; # structs that aren't covered by 'struct ... *' 215 | 216 | # Fallthrough - Treat everything we don't understand as POD. 217 | return ("0x%x", 1) if wantarray; # The 1 is the fallthrough flag - used to signal to argName(...) that we should be casting. 218 | return "0x%x"; 219 | } 220 | 221 | sub typeEncodingForArgType { 222 | local $_ = shift; 223 | s/^\s+//g; 224 | s/\s+$//g; 225 | 226 | return "c" if /^char$/; 227 | return "i" if /^int$/; 228 | return "s" if /^short$/; 229 | return "l" if /^long$/; 230 | return "q" if /^long long$/; 231 | 232 | return "C" if /^unsigned\s+char$/; 233 | return "I" if /^unsigned\s+int$/; 234 | return "S" if /^unsigned\s+short$/; 235 | return "L" if /^unsigned\s+long$/; 236 | return "Q" if /^unsigned\s+long long$/; 237 | 238 | return "f" if /^float$/; 239 | return "d" if /^double$/; 240 | return "B" if /^(bool|_Bool)$/; 241 | 242 | return "v" if /^void$/; 243 | 244 | return "*" if /^char\s*\*$/; 245 | 246 | return "@" if /^id$/; 247 | return "@" if /^instancetype$/; 248 | return "#" if /^Class$/; 249 | return ":" if /^SEL$/; 250 | 251 | if(/^([^*\s]+)\s*\*$/) { 252 | my $subEncoding = typeEncodingForArgType($1); 253 | return undef if(!defined $subEncoding); 254 | return "^".$subEncoding; 255 | } 256 | 257 | return undef; 258 | } 259 | 260 | sub declarationForTypeWithName { 261 | my $argtype = shift; 262 | my $argname = shift; 263 | if($argtype !~ /\(\s*[*^]/) { 264 | return $argtype." ".$argname; 265 | } 266 | my $substring = $argtype; 267 | my ($opening, $closing) = matchedParenthesisSet($substring, 0); 268 | my $offset = 0; 269 | while(1) { 270 | # We want to put the parameter name right before the closing ) in the deepest nested set if we found a (^ or (*. 271 | $substring = substr($substring, $opening, $closing - $opening - 1); 272 | $offset += $opening; 273 | my ($newopening, $newclosing) = matchedParenthesisSet($substring, 0); 274 | last if !defined $newopening; 275 | $opening = $newopening; 276 | $closing = $newclosing; 277 | } 278 | my $out = $argtype; 279 | substr($out, $offset-$opening+$closing-1, 0, $argname); 280 | return $out; 281 | } 282 | 283 | 1; 284 | -------------------------------------------------------------------------------- /bin/lib/Logos/Patch.pm: -------------------------------------------------------------------------------- 1 | package Logos::Patch; 2 | use strict; 3 | 4 | sub new { 5 | my $proto = shift; 6 | my $class = ref($proto) || $proto; 7 | my $self = {}; 8 | $self->{LINE} = -1; 9 | $self->{RANGE} = []; 10 | $self->{SOURCE} = undef; 11 | $self->{SQUASH} = 0; 12 | bless($self, $class); 13 | return $self; 14 | } 15 | 16 | ##################### # 17 | # Setters and Getters # 18 | # ##################### 19 | sub line { 20 | my $self = shift; 21 | if(@_) { $self->{LINE} = shift; } 22 | return $self->{LINE}; 23 | } 24 | 25 | sub range { 26 | my $self = shift; 27 | if(@_) { @{$self->{RANGE}} = @_; } 28 | return $self->{RANGE}; 29 | } 30 | 31 | sub start { 32 | my $self = shift; 33 | if(@_) { $self->{RANGE}[0] = shift; } 34 | return $self->{RANGE}[0]; 35 | } 36 | 37 | sub end { 38 | my $self = shift; 39 | if(@_) { $self->{RANGE}[1] = shift; } 40 | return $self->{RANGE}[1]; 41 | } 42 | 43 | sub source { 44 | my $self = shift; 45 | if(@_) { $self->{SOURCE} = shift; } 46 | return $self->{SOURCE}; 47 | } 48 | 49 | sub squash { 50 | my $self = shift; 51 | if(@_) { $self->{SQUASH} = shift; } 52 | return $self->{SQUASH}; 53 | } 54 | 55 | ##### # 56 | # END # 57 | # ##### 58 | 59 | sub evalSource { 60 | my $self = shift; 61 | my $source = shift; 62 | my $sourceref = ref($source); 63 | my @lines; 64 | if($sourceref) { 65 | if($sourceref eq "ARRAY") { 66 | for(@$source) { 67 | splice(@lines, scalar @lines, 0, $self->evalSource($_)); 68 | } 69 | } else { 70 | push(@lines, $source->eval()); 71 | } 72 | } else { 73 | push(@lines, $source); 74 | } 75 | return @lines; 76 | } 77 | 78 | sub apply { 79 | my $self = shift; 80 | my $lref = shift; 81 | my $line = $self->{LINE}; 82 | my ($start, $end) = @{$self->{RANGE}}; 83 | my $source = $self->{SOURCE}; 84 | my @lines = $self->evalSource($source); 85 | if(!defined $start) { 86 | push(@lines, ::generateLineDirectiveForPhysicalLine($line)); 87 | if($self->{SQUASH}) { 88 | push(@$lref, join('', @lines)); 89 | } else { 90 | splice(@$lref, $line, 0, @lines); 91 | } 92 | } else { 93 | substr($lref->[$line], $start, $end-$start) = join('', @lines); 94 | } 95 | return; 96 | } 97 | 98 | 1; 99 | -------------------------------------------------------------------------------- /bin/lib/Logos/Patch/Source/Generator.pm: -------------------------------------------------------------------------------- 1 | package Logos::Patch::Source::Generator; 2 | use strict; 3 | 4 | sub new { 5 | my $proto = shift; 6 | my $class = ref($proto) || $proto; 7 | my $self = {}; 8 | $self->{OBJECT} = shift; 9 | $self->{METHOD} = shift; 10 | my @args = @_; 11 | $self->{ARGS} = \@args; 12 | bless($self, $class); 13 | return $self; 14 | } 15 | 16 | sub eval { 17 | #no strict 'refs'; 18 | my $self = shift; 19 | my @args = @{$self->{ARGS}}; 20 | splice(@args, 0, 0, $self->{OBJECT}) if $self->{OBJECT}; 21 | return Logos::Generator::for($self->{OBJECT})->can($self->{METHOD})->(@args); 22 | #my $thunk = Logos::Generator::for($self->{OBJECT})->can($self->{METHOD})-(>${$self->{ARGS}});; 23 | #my $mname = $self->{METHOD}; 24 | #return $thunk->$mname(@{$self->{ARGS}}); 25 | } 26 | 27 | 1; 28 | -------------------------------------------------------------------------------- /bin/lib/Logos/StaticClassGroup.pm: -------------------------------------------------------------------------------- 1 | package Logos::StaticClassGroup; 2 | use Logos::Group; 3 | our @ISA = ('Logos::Group'); 4 | 5 | sub new { 6 | my $proto = shift; 7 | my $class = ref($proto) || $proto; 8 | my $self = Logos::Group->new(); 9 | $self->name("_staticClass"); 10 | $self->explicit(0); 11 | $self->{DECLAREDONLYCLASSES} = {}; 12 | $self->{USEDCLASSES} = {}; 13 | $self->{USEDMETACLASSES} = {}; 14 | bless($self, $class); 15 | return $self; 16 | } 17 | 18 | sub addUsedClass { 19 | my $self = shift; 20 | my $class = shift; 21 | $self->{USEDCLASSES}{$class}++; 22 | } 23 | 24 | sub addUsedMetaClass { 25 | my $self = shift; 26 | my $class = shift; 27 | $self->{USEDMETACLASSES}{$class}++; 28 | } 29 | 30 | sub addDeclaredOnlyClass { 31 | my $self = shift; 32 | my $class = shift; 33 | $self->{DECLAREDONLYCLASSES}{$class}++; 34 | } 35 | 36 | sub declaredOnlyClasses { 37 | my $self = shift; 38 | return $self->{DECLAREDONLYCLASSES}; 39 | } 40 | 41 | sub usedClasses { 42 | my $self = shift; 43 | return $self->{USEDCLASSES}; 44 | } 45 | 46 | sub usedMetaClasses { 47 | my $self = shift; 48 | return $self->{USEDMETACLASSES}; 49 | } 50 | 51 | 1; 52 | -------------------------------------------------------------------------------- /bin/lib/Logos/Subclass.pm: -------------------------------------------------------------------------------- 1 | package Logos::Subclass; 2 | use Logos::Class; 3 | our @ISA = ('Logos::Class'); 4 | 5 | sub new { 6 | my $proto = shift; 7 | my $class = ref($proto) || $proto; 8 | my $self = $class->SUPER::new(); 9 | $self->{SUPERCLASS} = undef; 10 | $self->{PROTOCOLS} = {}; 11 | $self->{IVARS} = []; 12 | $self->{OVERRIDDEN} = 1; 13 | bless($self, $class); 14 | return $self; 15 | } 16 | 17 | ##################### # 18 | # Setters and Getters # 19 | # ##################### 20 | sub superclass { 21 | my $self = shift; 22 | if(@_) { $self->{SUPERCLASS} = shift; } 23 | return $self->{SUPERCLASS}; 24 | } 25 | 26 | sub ivars { 27 | my $self = shift; 28 | return $self->{IVARS}; 29 | } 30 | 31 | sub protocols { 32 | my $self = shift; 33 | return $self->{PROTOCOLS}; 34 | } 35 | 36 | sub initRequired { 37 | my $self = shift; 38 | return 1; # Subclasses must always be initialized. 39 | } 40 | 41 | ##### # 42 | # END # 43 | # ##### 44 | 45 | sub addProtocol { 46 | my $self = shift; 47 | my $protocol = shift; 48 | $self->{PROTOCOLS}{$protocol}++; 49 | } 50 | 51 | sub addIvar { 52 | my $self = shift; 53 | my $ivar = shift; 54 | $ivar->class($self); 55 | push(@{$self->{IVARS}}, $ivar); 56 | } 57 | 58 | sub getIvarNamed { 59 | my $self = shift; 60 | my $name = shift; 61 | foreach(@{$self->{IVARS}}) { 62 | return $_ if $_->name eq $name; 63 | } 64 | return undef; 65 | } 66 | 67 | 1; 68 | -------------------------------------------------------------------------------- /bin/lib/Logos/Util.pm: -------------------------------------------------------------------------------- 1 | package Logos::Util; 2 | use 5.006; 3 | use strict; 4 | our @ISA = ('Exporter'); 5 | our @EXPORT = qw(quotes fallsBetween sanitize matchedParenthesisSet nestedParenString smartSplit); 6 | our $errorhandler = \&_defaultErrorHandler; 7 | 8 | sub _defaultErrorHandler { 9 | die shift; 10 | } 11 | 12 | sub quotes { 13 | my ($line) = @_; 14 | my @quotes = (); 15 | while($line =~ /(? 0) { 24 | my $start = shift; 25 | my $end = shift; 26 | return 1 if ($start < $idx && (!defined($end) || $end > $idx)) 27 | } 28 | return 0; 29 | } 30 | 31 | sub sanitize { 32 | my $input = shift; 33 | my $output = $input; 34 | $output =~ s/[^\w]//g; 35 | return $output; 36 | } 37 | 38 | sub matchedParenthesisSet { 39 | my $in = shift; 40 | my $atstart = shift; 41 | $atstart = 1 if !defined $atstart; 42 | 43 | my $opening = -1; 44 | my $closing = -1; 45 | if(!$atstart || $in =~ /^\s*\(/) { 46 | # If we encounter a ) that puts us back at zero, we found a ( 47 | # and have reached its closing ). 48 | my $parenmatch = $in; 49 | my $pdepth = 0; 50 | my @pquotes = quotes($parenmatch); 51 | while($parenmatch =~ /[;()]/g) { 52 | next if fallsBetween($-[0], @pquotes); 53 | 54 | if($& eq "(") { 55 | if($pdepth == 0) { $opening = $+[0]; } 56 | $pdepth++; 57 | } elsif($& eq ")") { 58 | $pdepth--; 59 | if($pdepth == 0) { $closing = $+[0]; last; } 60 | } 61 | } 62 | } 63 | 64 | return undef if $opening == -1; 65 | &$errorhandler("missing closing parenthesis") if $closing == -1; 66 | return ($opening, $closing); 67 | } 68 | 69 | sub nestedParenString { 70 | my $in = shift; 71 | my ($opening, $closing) = matchedParenthesisSet($in); 72 | 73 | my @ret; 74 | if(defined $opening) { 75 | $ret[0] = substr($in, $opening, $closing - $opening - 1); 76 | $in = substr($in, $closing); 77 | } 78 | $ret[1] = $in; 79 | return @ret; 80 | } 81 | 82 | sub smartSplit { 83 | my $re = shift; 84 | my $in = shift; 85 | return () if !$in || $in eq ""; 86 | 87 | my $limit = shift; 88 | $limit = 0 if !defined $limit; 89 | 90 | my @quotes = quotes($in); 91 | my @parens = matchedParenthesisSet($in, 0); 92 | 93 | my $lstart = 0; 94 | my @pieces = (); 95 | my $piece = ""; 96 | while($in =~ /$re/g) { 97 | next if (defined $parens[0] && fallsBetween($-[0], @parens)) || fallsBetween($-[0], @quotes); 98 | $piece = substr($in, $lstart, $-[0]-$lstart); 99 | push(@pieces, $piece); 100 | $lstart = $+[0]; 101 | $limit--; 102 | last if($limit == 1); # One item left? Bail out and throw the rest of the string into it! 103 | } 104 | $piece = substr($in, $lstart); 105 | push(@pieces, $piece); 106 | return @pieces; 107 | } 108 | 109 | 1; 110 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/Context.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::Context; 2 | use strict; 3 | use warnings; 4 | use subs qw(warn exit); 5 | use Module::Load::Conditional qw(can_load); 6 | use NIC::Tie::PrefixedHandleRedirect; 7 | use NIC::Bridge::NICBase; 8 | 9 | our %handlers = ( 10 | PROMPT => sub { }, 11 | ); 12 | 13 | sub import { 14 | my $package = shift; 15 | my %arg = @_; 16 | for(keys %arg) { 17 | $handlers{$_} = $arg{$_}; 18 | } 19 | } 20 | 21 | our $bridge = undef; 22 | our $global_ret = undef; 23 | our $errored_out = undef; 24 | 25 | sub NIC { 26 | return $bridge; 27 | } 28 | 29 | sub warn(@) { 30 | print STDERR "[".$bridge->{FOR}->name."/warning] ",@_,$/; 31 | } 32 | 33 | sub error(@) { 34 | print STDERR "[".$bridge->{FOR}->name."/error] ",@_,$/; 35 | $errored_out = 1; 36 | die; 37 | } 38 | 39 | sub exit { 40 | $global_ret = shift; 41 | die; 42 | } 43 | 44 | sub prompt { 45 | __PACKAGE__->_prompt($bridge->{FOR}, undef, @_); 46 | } 47 | 48 | sub _prompt { 49 | my $self = shift; 50 | my $nic = shift; 51 | 52 | my $n = scalar @_; 53 | my $opts = $_[$n-1]; 54 | if(ref $opts eq "HASH") { 55 | $n--; 56 | } else { 57 | $opts = {}; 58 | } 59 | 60 | my $variable; 61 | $variable = shift unless $n == 1; 62 | my $promptstring = shift; 63 | 64 | $handlers{PROMPT}->($nic, $variable, $promptstring, $opts->{default}); 65 | } 66 | 67 | sub _wrap { 68 | my $self = shift; 69 | my @r = map { 70 | my $wrap = $_; 71 | my $_wrapType = $wrap ? (ref $wrap) : "_Undefined"; 72 | if(!$_wrapType || (ref($wrap) && $wrap->isa("NIC::Bridge::_BridgedObject"))) { 73 | return $wrap; 74 | } else { 75 | $_wrapType =~ s/.*:://; 76 | my $wrappingClass = "NIC::Bridge::$_wrapType"; 77 | can_load(modules=>{$wrappingClass=>undef}, verbose=>0) or return undef; 78 | my $wrapper = $wrappingClass->new($self, $wrap); 79 | return $wrapper; 80 | } 81 | } (@_); 82 | return @r if wantarray; 83 | return (@r > 0 ? $r[0] : undef); 84 | } 85 | 86 | sub _unwrap { 87 | my $self = shift; 88 | my @r = map { (ref($_) && $_->isa("NIC::Bridge::_BridgedObject")) ? $_->{FOR} : $_; } (@_); 89 | return @r if wantarray; 90 | return (@r > 0 ? $r[0] : undef); 91 | } 92 | 93 | sub _execute { 94 | my $self = shift; 95 | my $nic = shift; 96 | my $script = shift; 97 | my $ret = 1; 98 | { 99 | local $global_ret; 100 | local $errored_out; 101 | local $bridge = NIC::Bridge::NICBase->new($self, $nic); 102 | local $SIG{__DIE__} = sub { }; 103 | tie *OVERRIDE, "NIC::Tie::PrefixedHandleRedirect", *STDERR, $nic->name; 104 | my $stdout = select(*OVERRIDE); 105 | eval("#line 1 ".$nic->name."/control.pl\n".$script); 106 | select($stdout); 107 | if(defined $errored_out) { 108 | $ret = 0; 109 | } elsif(defined $global_ret) { 110 | $ret = $global_ret; 111 | print STDERR "[".$nic->name."/error] Control script exited with status $ret.",$/; 112 | } elsif($@) { 113 | $ret = 0; 114 | print STDERR "[".$nic->name."/error] Control script exited due to an error: $@"; 115 | } 116 | } 117 | return $ret; 118 | } 119 | 120 | 1; 121 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/Directory.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::Directory; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::NICType); 5 | 6 | 1; 7 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/File.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::File; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::NICType); 5 | use NIC::Tie::Method; 6 | 7 | sub data :lvalue { 8 | my $self = shift; 9 | tie my $tied, 'NIC::Tie::Method', $self->{FOR}, "data"; 10 | $tied; 11 | } 12 | 13 | 1; 14 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/NICBase.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::NICBase; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::_BridgedObject); 5 | use NIC::NICBase::Directory; 6 | use NIC::NICBase::File; 7 | use NIC::NICBase::Symlink; 8 | 9 | sub variables { 10 | my $self = shift; 11 | return keys %{$self->{FOR}->{VARIABLES}}; 12 | } 13 | 14 | sub variable :lvalue { 15 | my $self = shift; 16 | $self->{FOR}->variable(@_); 17 | } 18 | 19 | sub mkdir { 20 | my $self = shift; 21 | my $dirname = shift; 22 | my $mode = shift; 23 | my $ref = $self->{FOR}->_getContent($dirname); 24 | NIC::NICBase::Directory->take($ref); 25 | $ref->mode($mode) if $mode; 26 | return $self->{CONTEXT}->_wrap($ref); 27 | } 28 | 29 | sub mkfile { 30 | my $self = shift; 31 | my $name = shift; 32 | my $mode = shift; 33 | my $ref = $self->{FOR}->_getContent($name); 34 | NIC::NICBase::File->take($ref); 35 | $ref->mode($mode) if $mode; 36 | return $self->{CONTEXT}->_wrap($ref); 37 | } 38 | 39 | sub symlink { 40 | my $self = shift; 41 | my $oldfile = shift; 42 | my $newfile = shift; 43 | my $ref = $self->{FOR}->_getContent($newfile); 44 | 45 | my $realtarget = ref($oldfile) ? $self->{CONTEXT}->_unwrap($oldfile) : $self->{FOR}->_getContentWithoutCreate($oldfile); 46 | $realtarget = $oldfile if !$realtarget; 47 | 48 | NIC::NICBase::Symlink->take($ref, $realtarget); 49 | 50 | return $self->{CONTEXT}->_wrap($ref); 51 | } 52 | 53 | sub lookup { 54 | my $self = shift; 55 | my $name = shift; 56 | return $self->{CONTEXT}->_wrap($self->{FOR}->_getContentWithoutCreate($name)); 57 | } 58 | 59 | sub setConstraint { 60 | my $self = shift; 61 | my $constraint = shift; 62 | $self->{FOR}->addConstraint($constraint); 63 | } 64 | 65 | sub clearConstraint { 66 | my $self = shift; 67 | my $constraint = shift; 68 | $self->{FOR}->removeConstraint($constraint); 69 | } 70 | 71 | sub prompt { 72 | my $self = shift; 73 | $self->{CONTEXT}->_prompt($self->{FOR}, @_); 74 | } 75 | 76 | 1; 77 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/NICType.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::NICType; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::_BridgedObject); 5 | use NIC::Tie::Method; 6 | 7 | sub name :lvalue { 8 | my $self = shift; 9 | tie my $tied, 'NIC::Tie::Method', $self->{FOR}, "name"; 10 | $tied; 11 | } 12 | 13 | sub mode :lvalue { 14 | my $self = shift; 15 | tie my $tied, 'NIC::Tie::Method', $self->{FOR}, "mode"; 16 | $tied; 17 | } 18 | 19 | sub constraints { 20 | my $self = shift; 21 | return $self->{FOR}->constraints; 22 | } 23 | 24 | sub constrain { 25 | my $self = shift; 26 | $self->{FOR}->addConstraint(shift); 27 | } 28 | 29 | 1; 30 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/Symlink.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::Symlink; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::NICType); 5 | use NIC::Bridge::Tie::WrappedMethod; 6 | 7 | sub target :lvalue { 8 | my $self = shift; 9 | tie my $tied, 'NIC::Bridge::Tie::WrappedMethod', $self->{CONTEXT}, $self->{FOR}, "target"; 10 | $tied; 11 | } 12 | 13 | 1; 14 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/Tie/WrappedMethod.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::Tie::WrappedMethod; 2 | use strict; 3 | use warnings; 4 | use parent qw(Tie::Scalar); 5 | 6 | sub TIESCALAR { 7 | my $class = shift; 8 | my $self = { CONTEXT => shift, FOR => shift, METHOD => shift }; 9 | bless($self, $class); 10 | return $self; 11 | } 12 | 13 | sub FETCH { 14 | my $self = shift; 15 | my $obj = $self->{FOR}; 16 | my $ret = $self->{FOR}->can($self->{METHOD})->($self->{FOR}); 17 | return $self->{CONTEXT}->_wrap($ret); 18 | } 19 | 20 | sub STORE { 21 | my $self = shift; 22 | my $obj = $self->{FOR}; 23 | my $in = shift; 24 | $self->{FOR}->can($self->{METHOD})->($self->{FOR}, $self->{CONTEXT}->_unwrap($in)); 25 | } 26 | 27 | 1; 28 | 29 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/_BridgedObject.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::_BridgedObject; 2 | use strict; 3 | use warnings; 4 | 5 | use overload '""' => sub { 6 | my $self = shift; 7 | return "[".($self->{FOR}//"(undefined)")."]"; 8 | }; 9 | 10 | sub new { 11 | my $proto = shift; 12 | my $class = ref($proto) || $proto; 13 | my $self = { CONTEXT => shift, FOR => shift }; 14 | bless($self, $proto); 15 | return $self; 16 | } 17 | 18 | 19 | 1; 20 | -------------------------------------------------------------------------------- /bin/lib/NIC/Bridge/_Undefined.pm: -------------------------------------------------------------------------------- 1 | package NIC::Bridge::_Undefined; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::Bridge::_BridgedObject); 5 | 6 | use overload "bool" => sub { 7 | return 0; 8 | }; 9 | 10 | our $AUTOLOAD; 11 | sub AUTOLOAD { 12 | my $method = $AUTOLOAD; 13 | $method =~ s/.*:://; 14 | NIC::Bridge::Context::error("Method '$method' called on nonexistent NIC Bridge object."); 15 | } 16 | 17 | sub DESTROY { 18 | my $self = shift; 19 | } 20 | 21 | 1; 22 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NIC1.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NIC1; 2 | use parent NIC::NICBase; 3 | use strict; 4 | 5 | sub new { 6 | my $proto = shift; 7 | my $class = ref($proto) || $proto; 8 | 9 | my $fh = shift; 10 | my $self = NIC::NICBase->new(@_); 11 | bless($self, $class); 12 | 13 | $self->load($fh); 14 | return $self; 15 | } 16 | 17 | sub _processLine { 18 | my $self = shift; 19 | my $fh = shift; 20 | local $_ = shift; 21 | if(/^name \"(.*)\"$/) { 22 | $self->name($1); 23 | } elsif(/^dir (.+)$/) { 24 | $self->registerDirectory($1); 25 | } elsif(/^file (\d+) (.+)$/) { 26 | my $lines = $1; 27 | my $filename = $2; 28 | my $fref = $self->registerFile($filename); 29 | my $filedata = ""; 30 | while($lines > 0) { 31 | $filedata .= <$fh>; 32 | $lines--; 33 | } 34 | $fref->data($filedata); 35 | } elsif(/^prompt (\w+) \"(.*?)\"( \"(.*?)\")?$/) { 36 | my $key = $1; 37 | my $prompt = $2; 38 | my $default = $4 || undef; 39 | $self->registerPrompt($key, $prompt, $default); 40 | } elsif(/^symlink \"(.+)\" \"(.+)\"$/) { 41 | my $name = $1; 42 | my $dest = $2; 43 | $self->registerSymlink($name, $dest); 44 | } elsif(/^constrain file \"(.+)\" to (.+)$/) { 45 | my $constraint = $2; 46 | my $filename = $1; 47 | $self->registerFileConstraint($filename, $constraint); 48 | } 49 | } 50 | 51 | sub load { 52 | my $self = shift; 53 | my $fh = shift; 54 | while(<$fh>) { 55 | $self->_processLine($fh, $_); 56 | } 57 | $self->resolveSymlinks; 58 | } 59 | 60 | 1; 61 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NICTar.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NICTar; 2 | use parent NIC::NICBase; 3 | use strict; 4 | use NIC::Formats::NICTar::File; 5 | use NIC::Formats::NICTar::Directory; 6 | use NIC::Formats::NICTar::Symlink; 7 | use Archive::Tar; 8 | use File::Temp; 9 | use File::Path; 10 | use File::Spec; 11 | use NIC::Bridge::Context; 12 | $Archive::Tar::WARN = 0; 13 | 14 | sub new { 15 | my $proto = shift; 16 | my $fh_or_tar = shift; 17 | my $class = ref($proto) || $proto; 18 | 19 | my $tar = ref($fh_or_tar) eq "Archive::Tar" ? $fh_or_tar : Archive::Tar->new($fh_or_tar); 20 | return undef if(!$tar); 21 | 22 | my $control = _fileFromTar(undef, $tar, "NIC/control"); 23 | return undef if(!$control); 24 | 25 | my $self = NIC::NICBase->new(@_); 26 | $self->{_TAR} = $tar; 27 | bless($self, $class); 28 | 29 | $self->_processData($control->get_content); 30 | $self->load(); 31 | 32 | return $self; 33 | } 34 | 35 | sub _fileClass { "NIC::Formats::NICTar::File"; } 36 | sub _directoryClass { "NIC::Formats::NICTar::Directory"; } 37 | sub _symlinkClass { "NIC::Formats::NICTar::Symlink"; } 38 | 39 | sub _fileFromTar { 40 | my $self = shift; 41 | my $tar = $self ? $self->{_TAR} : shift; 42 | my $filename = shift; 43 | my @_tarfiles = $tar->get_files("./$filename", $filename); 44 | return (scalar @_tarfiles > 0) ? $_tarfiles[0] : undef; 45 | } 46 | 47 | sub _processData { 48 | my $self = shift; 49 | my $data = shift; 50 | for(split /\n\r?/, $data) { 51 | $self->_processLine($_); 52 | } 53 | } 54 | 55 | sub _processLine { 56 | my $self = shift; 57 | local $_ = shift; 58 | if(/^name\s+\"(.*)\"$/ || /^name\s+(.*)$/) { 59 | $self->name($1); 60 | } elsif(/^prompt (\w+) \"(.*?)\"( \"(.*?)\")?$/) { 61 | my $key = $1; 62 | my $prompt = $2; 63 | my $default = $4 || undef; 64 | $self->registerPrompt($key, $prompt, $default); 65 | } elsif(/^constrain (file )?\"(.+)\" to (.+)$/) { 66 | my $constraint = $3; 67 | my $filename = $2; 68 | $self->registerFileConstraint($filename, $constraint); 69 | } elsif(/^ignore (\w+)$/) { 70 | $self->ignoreVariable($1); 71 | } 72 | } 73 | 74 | sub load { 75 | my $self = shift; 76 | for($self->{_TAR}->get_files()) { 77 | next if !$_->full_path || $_->full_path =~ /^(\.\/)?NIC(\/|$)/; 78 | my $n = $_->full_path; 79 | $n =~ s/^\.\///; 80 | next if length $n == 0; 81 | if($_->is_dir) { 82 | my $ref = $self->registerDirectory($n); 83 | $ref->tarfile($_); 84 | } elsif($_->is_symlink) { 85 | my $target = $_->linkname; 86 | $target =~ s/^\.\///; 87 | 88 | my $ref = $self->registerSymlink($n, $target); 89 | $ref->tarfile($_); 90 | } elsif($_->is_file) { 91 | my $ref = $self->registerFile($n); 92 | $ref->tarfile($_); 93 | } 94 | } 95 | $self->resolveSymlinks; 96 | } 97 | 98 | sub _execPackageScript { 99 | my $self = shift; 100 | my $script = shift; 101 | my $tarfile = $self->_fileFromTar("NIC/$script"); 102 | return if !$tarfile || $tarfile->mode & 0500 != 0500; 103 | my $filename = File::Spec->catfile($self->{_TEMPDIR}, $script); 104 | my $nicfile = NIC::NICType->new($self, $filename); 105 | $self->_fileClass->take($nicfile); 106 | $nicfile->tarfile($tarfile); 107 | $nicfile->create(); 108 | my $ret = system $filename $script; 109 | return ($ret >> 8) == 0 110 | } 111 | 112 | sub prebuild { 113 | my $self = shift; 114 | return $self->_execPackageScript("prebuild"); 115 | } 116 | 117 | sub postbuild { 118 | my $self = shift; 119 | return $self->_execPackageScript("postbuild"); 120 | } 121 | 122 | sub exec { 123 | my $self = shift; 124 | my $_controlpl = $self->_fileFromTar("NIC/control.pl"); 125 | if($_controlpl) { 126 | return NIC::Bridge::Context->_execute($self, $_controlpl->get_content); 127 | } 128 | return 1; 129 | } 130 | 131 | sub build { 132 | my $self = shift; 133 | 134 | for(keys %{$self->{VARIABLES}}) { 135 | $ENV{"NIC_".$_} = $self->variable($_); 136 | } 137 | 138 | $self->{_TEMPDIR} = File::Temp::tempdir(); 139 | 140 | $self->SUPER::build(@_); 141 | 142 | File::Path::rmtree($self->{_TEMPDIR}); 143 | $self->{_TEMPDIR} = undef; 144 | } 145 | 146 | 1; 147 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NICTar/Directory.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NICTar::Directory; 2 | use parent qw(NIC::Formats::NICTar::_TarMixin NIC::NICBase::Directory); 3 | use strict; 4 | 5 | sub _take_init { 6 | my $self = shift; 7 | $self->NIC::NICBase::Directory::_take_init(@_); 8 | $self->NIC::Formats::NICTar::_TarMixin::_take_init(@_); 9 | } 10 | 11 | 1; 12 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NICTar/File.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NICTar::File; 2 | use parent qw(NIC::Formats::NICTar::_TarMixin NIC::NICBase::File); 3 | use strict; 4 | 5 | sub _take_init { 6 | my $self = shift; 7 | $self->NIC::NICBase::File::_take_init(@_); 8 | $self->NIC::Formats::NICTar::_TarMixin::_take_init(@_); 9 | } 10 | 11 | sub data { 12 | my $self = shift; 13 | return $self->SUPER::data(@_) // $self->tarfile->get_content; 14 | } 15 | 16 | 1; 17 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NICTar/Symlink.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NICTar::Symlink; 2 | use parent NIC::NICBase::Symlink; 3 | use strict; 4 | 5 | sub tarfile { 6 | my $self = shift; 7 | if(@_) { $self->{TARFILE} = shift; } 8 | return $self->{TARFILE}; 9 | } 10 | 11 | 1; 12 | -------------------------------------------------------------------------------- /bin/lib/NIC/Formats/NICTar/_TarMixin.pm: -------------------------------------------------------------------------------- 1 | package NIC::Formats::NICTar::_TarMixin; 2 | use strict; 3 | 4 | sub _take_init { 5 | my $self = shift; 6 | $self->{TARFILE} = undef; 7 | } 8 | 9 | sub tarfile { 10 | my $self = shift; 11 | if(@_) { $self->{TARFILE} = shift; } 12 | return $self->{TARFILE}; 13 | } 14 | 15 | sub _mode { 16 | my $self = shift; 17 | return $self->tarfile->mode; 18 | } 19 | 20 | 1; 21 | -------------------------------------------------------------------------------- /bin/lib/NIC/NICBase.pm: -------------------------------------------------------------------------------- 1 | package NIC::NICBase; 2 | use strict; 3 | use warnings; 4 | 5 | use NIC::NICBase::File; 6 | use NIC::NICBase::Directory; 7 | use NIC::NICBase::Symlink; 8 | 9 | use List::Util qw(first); 10 | 11 | sub new { 12 | my $proto = shift; 13 | my $class = ref($proto) || $proto; 14 | my $self = {}; 15 | $self->{NAME} = shift; 16 | $self->{CONTENTS} = []; 17 | $self->{VARIABLES} = {}; 18 | $self->{CONSTRAINTS} = {}; 19 | $self->{PROMPTS} = []; 20 | $self->{IGNORED_VARS} = {}; 21 | bless($self, $class); 22 | 23 | return $self; 24 | } 25 | 26 | sub _fileClass { "NIC::NICBase::File"; } 27 | sub _directoryClass { "NIC::NICBase::Directory"; } 28 | sub _symlinkClass { "NIC::NICBase::Symlink"; } 29 | 30 | sub _getContentWithoutCreate { 31 | my $self = shift; 32 | my $name = shift; 33 | return first { $_->name eq $name } @{$self->{CONTENTS}}; 34 | } 35 | 36 | sub _getContent { 37 | my $self = shift; 38 | my $ref = $self->_getContentWithoutCreate(@_); 39 | return $ref if $ref; 40 | $ref = NIC::NICType->new($self, @_); 41 | push(@{$self->{CONTENTS}}, $ref); 42 | return $ref; 43 | } 44 | 45 | sub _generate { 46 | my $self = shift; 47 | my $class = shift; 48 | my $name = shift; 49 | my $ref = $self->_getContent($name, @_); 50 | if($ref->type == NIC::NICType::TYPE_UNKNOWN) { 51 | $class->take($ref, @_); 52 | } 53 | return $ref; 54 | } 55 | 56 | sub registerDirectory { 57 | my $self = shift; 58 | my $dir = $self->_generate($self->_directoryClass, @_); 59 | return $dir; 60 | } 61 | 62 | sub registerFile { 63 | my $self = shift; 64 | my $file = $self->_generate($self->_fileClass, @_); 65 | return $file; 66 | } 67 | 68 | sub registerSymlink { 69 | my $self = shift; 70 | my $symlink = $self->_generate($self->_symlinkClass, @_); 71 | return $symlink; 72 | } 73 | 74 | sub registerPrompt { 75 | my($self, $key, $prompt, $default) = @_; 76 | push(@{$self->{PROMPTS}}, { 77 | name => $key, 78 | prompt => $prompt, 79 | default => $default 80 | }); 81 | } 82 | 83 | sub registerFileConstraint { 84 | my $self = shift; 85 | my $filename = shift; 86 | my $constraint = shift; 87 | $self->_getContent($filename)->addConstraint($constraint); 88 | } 89 | 90 | sub resolveSymlinks { 91 | my $self = shift; 92 | for(@{$self->{CONTENTS}}) { 93 | next unless $_->type == NIC::NICType::TYPE_SYMLINK; 94 | next if $_->target_type != NIC::NICType::TYPE_UNKNOWN; 95 | my $ref = $self->_getContentWithoutCreate($_->target); 96 | $_->target($ref) if $ref; 97 | } 98 | } 99 | 100 | sub variable: lvalue { 101 | my $self = shift; 102 | my $key = shift; 103 | $self->{VARIABLES}->{$key}; 104 | } 105 | 106 | sub name { 107 | my $self = shift; 108 | if(@_) { $self->{NAME} = shift; } 109 | return $self->{NAME} // "(unnamed template)"; 110 | } 111 | 112 | sub prompts { 113 | my $self = shift; 114 | return @{$self->{PROMPTS}}; 115 | } 116 | 117 | sub addConstraint { 118 | my $self = shift; 119 | my $constraint = shift; 120 | $self->{CONSTRAINTS}->{$constraint} = 1; 121 | } 122 | 123 | sub removeConstraint { 124 | my $self = shift; 125 | my $constraint = shift; 126 | delete $self->{CONSTRAINTS}->{$constraint}; 127 | } 128 | 129 | sub _constraintMatch { 130 | my $self = shift; 131 | my $constraint = shift; 132 | my $negated = 0; 133 | if(substr($constraint, 0, 1) eq "!") { 134 | $negated = 1; 135 | substr($constraint, 0, 1, ""); 136 | } 137 | return 0 if(!$negated && (!defined $self->{CONSTRAINTS}->{$constraint} || $self->{CONSTRAINTS}->{$constraint} != 1)); 138 | return 0 if($negated && (defined $self->{CONSTRAINTS}->{$constraint} || $self->{CONSTRAINTS}->{$constraint} != 0)); 139 | return 1; 140 | } 141 | 142 | sub _meetsConstraints { 143 | my $self = shift; 144 | my $content = shift; 145 | foreach ($content->constraints) { 146 | return 0 if !$self->_constraintMatch($_); 147 | } 148 | return 1; 149 | } 150 | 151 | sub substituteVariables { 152 | my $self = shift; 153 | my $line = shift; 154 | foreach my $key (keys %{$self->{VARIABLES}}) { 155 | my $value = $self->{VARIABLES}->{$key}; 156 | $line =~ s/\@\@$key\@\@/$value/g; 157 | } 158 | return $line; 159 | } 160 | 161 | sub ignoreVariable { 162 | my $self = shift; 163 | my $var = shift; 164 | $self->{IGNORED_VARS}->{$var}++; 165 | } 166 | 167 | sub variableIgnored { 168 | my $self = shift; 169 | my $var = shift; 170 | return defined $self->{IGNORED_VARS}->{$var}; 171 | } 172 | 173 | sub prebuild { 174 | 175 | } 176 | 177 | sub postbuild { 178 | 179 | } 180 | 181 | sub exec { 182 | return 1; 183 | } 184 | 185 | sub build { 186 | my $self = shift; 187 | my $dir = shift; 188 | mkdir($dir) or die "Failed to create the directory '$dir': $!\n"; 189 | chdir($dir) or die $!; 190 | $self->prebuild(); 191 | foreach my $content (sort { $a->type <=> $b->type } (@{$self->{CONTENTS}})) { 192 | next if $content->type == NIC::NICType::TYPE_UNKNOWN; 193 | next if !$self->_meetsConstraints($content); 194 | $content->create(); 195 | } 196 | $self->postbuild(); 197 | } 198 | 199 | sub dumpPreamble { 200 | my $self = shift; 201 | my $preamblefn = shift; 202 | open(my $pfh, ">", $preamblefn); 203 | print $pfh "name \"".$self->{NAME}."\"",$/; 204 | foreach my $prompt (@{$self->{PROMPTS}}) { 205 | print $pfh "prompt ".$prompt->{name}." \"".$prompt->{prompt}."\""; 206 | print $pfh " \"".$prompt->{default}."\"" if defined $prompt->{default}; 207 | print $pfh $/; 208 | } 209 | foreach my $filename (keys %{$self->{FILES}}) { 210 | my $file = $self->{FILES}->{$filename}; 211 | if(!defined $file->{constraints}) { 212 | next; 213 | } 214 | foreach (@{$file->{constraints}}) { 215 | print $pfh "constrain file \"".$filename."\" to ".$_,$/ 216 | } 217 | } 218 | close($pfh); 219 | } 220 | 221 | 1; 222 | -------------------------------------------------------------------------------- /bin/lib/NIC/NICBase/Directory.pm: -------------------------------------------------------------------------------- 1 | package NIC::NICBase::Directory; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::NICType); 5 | use File::Path qw(mkpath); 6 | 7 | sub type { 8 | my $self = shift; 9 | return NIC::NICType::TYPE_DIRECTORY; 10 | } 11 | 12 | sub _mode { 13 | return 0755; 14 | } 15 | 16 | sub create { 17 | my $self = shift; 18 | mkpath($self->{OWNER}->substituteVariables($self->{NAME}), { mode => $self->mode }) or return 0; 19 | return 1; 20 | } 21 | 22 | 23 | 1; 24 | 25 | -------------------------------------------------------------------------------- /bin/lib/NIC/NICBase/File.pm: -------------------------------------------------------------------------------- 1 | package NIC::NICBase::File; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::NICType); 5 | 6 | sub _take_init { 7 | my $self = shift; 8 | $self->{DATA} = undef; 9 | } 10 | 11 | sub type { 12 | my $self = shift; 13 | return NIC::NICType::TYPE_FILE; 14 | } 15 | 16 | sub _mode { 17 | return 0644; 18 | } 19 | 20 | sub data { 21 | my $self = shift; 22 | $self->{DATA} = shift if @_; 23 | $self->{DATA}; 24 | } 25 | 26 | sub create { 27 | my $self = shift; 28 | my $filename = $self->{OWNER}->substituteVariables($self->name); 29 | open(my $nicfile, ">", $filename) or return 0; 30 | print $nicfile $self->{OWNER}->substituteVariables($self->data); 31 | close($nicfile); 32 | chmod($self->mode, $filename); 33 | return 1; 34 | } 35 | 36 | 1; 37 | -------------------------------------------------------------------------------- /bin/lib/NIC/NICBase/Symlink.pm: -------------------------------------------------------------------------------- 1 | package NIC::NICBase::Symlink; 2 | use strict; 3 | use warnings; 4 | use parent qw(NIC::NICType); 5 | use Scalar::Util qw(refaddr); 6 | 7 | use overload '""' => sub { 8 | my $self = shift; 9 | my $ref = ref($self); 10 | $ref =~ s/^.*::(\w+)$/$1/g; 11 | my $target = (ref($self->target) && refaddr($self) == refaddr($self->target)) ? "itself" : "\"".$self->target."\""; 12 | return '"'.$self->name."\" ($ref to $target)"; 13 | }; 14 | 15 | sub _take_init { 16 | my $self = shift; 17 | $self->{TARGET} = shift // undef; 18 | } 19 | 20 | sub type { 21 | my $self = shift; 22 | return NIC::NICType::TYPE_SYMLINK; 23 | } 24 | 25 | sub target { 26 | my $self = shift; 27 | if(@_) { $self->{TARGET} = shift; } 28 | return $self->{TARGET}; 29 | } 30 | 31 | sub target_type { 32 | my $self = shift; 33 | my $t = $self->{TARGET}; 34 | return ref($t) ? $t->type : NIC::NICType::TYPE_UNKNOWN; 35 | } 36 | 37 | sub target_name { 38 | my $self = shift; 39 | my $t = $self->{TARGET}; 40 | return ref($t) ? $t->name : $t; 41 | } 42 | 43 | sub create { 44 | my $self = shift; 45 | my $name = $self->{OWNER}->substituteVariables($self->{NAME}); 46 | my $dest = $self->{OWNER}->substituteVariables($self->target_name); 47 | symlink($dest, $name) or return 0; 48 | return 1; 49 | } 50 | 51 | 1; 52 | 53 | -------------------------------------------------------------------------------- /bin/lib/NIC/NICType.pm: -------------------------------------------------------------------------------- 1 | package NIC::NICType; 2 | use strict; 3 | use warnings; 4 | 5 | use constant { 6 | TYPE_UNKNOWN => 0, 7 | TYPE_DIRECTORY => 1, 8 | TYPE_FILE => 2, 9 | TYPE_SYMLINK => 3 10 | }; 11 | 12 | use overload '""' => sub { 13 | my $self = shift; 14 | my $ref = ref($self); 15 | $ref =~ s/^.*::(\w+)$/$1/g; 16 | return '"'.$self->name."\" ($ref, mode ".sprintf("%4.04o", $self->mode).")"; 17 | }; 18 | 19 | sub new { 20 | my $proto = shift; 21 | my $class = ref($proto) || $proto; 22 | my $self = {}; 23 | $self->{OWNER} = shift // undef; 24 | $self->{NAME} = shift // undef; 25 | $self->{MODE} = undef; 26 | $self->{CONSTRAINTS} = []; 27 | bless($self, $class); 28 | 29 | return $self; 30 | } 31 | 32 | sub _take_init { 33 | } 34 | 35 | sub take { 36 | my $proto = shift; 37 | my $class = ref($proto) || $proto; 38 | my $obj = shift; 39 | bless($obj, $class); 40 | $obj->_take_init(@_); 41 | } 42 | 43 | sub name { 44 | my $self = shift; 45 | if(@_) { $self->{NAME} = shift; } 46 | return $self->{NAME}; 47 | } 48 | 49 | sub _mode { 50 | return 0; 51 | } 52 | 53 | sub mode { 54 | my $self = shift; 55 | if(@_) { $self->{MODE} = shift; } 56 | return $self->{MODE} // $self->_mode; 57 | } 58 | 59 | sub type { 60 | my $self = shift; 61 | return TYPE_UNKNOWN; 62 | } 63 | 64 | sub constraints { 65 | my $self = shift; 66 | return @{$self->{CONSTRAINTS}}; 67 | } 68 | 69 | sub addConstraint { 70 | my $self = shift; 71 | my $constraint = shift; 72 | push(@{$self->{CONSTRAINTS}}, $constraint); 73 | } 74 | 75 | sub create { 76 | return 0; 77 | } 78 | 79 | 1; 80 | -------------------------------------------------------------------------------- /bin/lib/NIC/Tie/Method.pm: -------------------------------------------------------------------------------- 1 | package NIC::Tie::Method; 2 | use parent qw(Tie::Scalar); 3 | 4 | sub TIESCALAR { 5 | my $class = shift; 6 | my $for = shift; 7 | my $method = shift; 8 | my $self = { FOR => $for, METHOD => $method }; 9 | bless($self, $class); 10 | return $self; 11 | } 12 | 13 | sub FETCH { 14 | my $self = shift; 15 | my $obj = $self->{FOR}; 16 | { unshift @_, $obj; goto &{$self->{FOR}->can($self->{METHOD})}; } 17 | } 18 | 19 | sub STORE { 20 | my $self = shift; 21 | my $obj = $self->{FOR}; 22 | { unshift @_, $obj; goto &{$self->{FOR}->can($self->{METHOD})}; } 23 | } 24 | 25 | 1; 26 | 27 | -------------------------------------------------------------------------------- /bin/lib/NIC/Tie/PrefixedHandleRedirect.pm: -------------------------------------------------------------------------------- 1 | package NIC::Tie::PrefixedHandleRedirect; 2 | use strict; 3 | use parent qw(Tie::Handle); 4 | sub TIEHANDLE { 5 | my $proto = shift; 6 | my $fh = shift; 7 | my $prefix = shift; 8 | return bless [$fh, $prefix], $proto; 9 | } 10 | 11 | sub _token { 12 | return "[".$_[0]->[1]."] "; 13 | } 14 | 15 | sub PRINT { 16 | my $t = $_[0]->_token; 17 | my $fh = $_[0]->[0]; 18 | shift; 19 | my $str = $t.join('', @_); 20 | $str =~ s#$/+$##g; 21 | $str =~ s#$/#$/$t#g; 22 | print $fh $str,$/; 23 | } 24 | 25 | sub PRINTF { 26 | my $t = $_[0]->_token; 27 | my $fh = $_[0]->[0]; 28 | shift; 29 | my $str = $t.sprintf(shift, @_); 30 | $str =~ s#$/+$##g; 31 | $str =~ s#$/#$/$t#g; 32 | print $fh $str,$/; 33 | } 34 | 1; 35 | -------------------------------------------------------------------------------- /bin/lib/parent.pm: -------------------------------------------------------------------------------- 1 | package parent; 2 | use strict; 3 | use vars qw($VERSION); 4 | $VERSION = '0.225'; 5 | 6 | sub import { 7 | my $class = shift; 8 | 9 | my $inheritor = caller(0); 10 | 11 | if ( @_ and $_[0] eq '-norequire' ) { 12 | shift @_; 13 | } else { 14 | for ( my @filename = @_ ) { 15 | if ( $_ eq $inheritor ) { 16 | warn "Class '$inheritor' tried to inherit from itself\n"; 17 | }; 18 | 19 | s{::|'}{/}g; 20 | require "$_.pm"; # dies if the file is not found 21 | } 22 | } 23 | 24 | { 25 | no strict 'refs'; 26 | push @{"$inheritor\::ISA"}, @_; 27 | }; 28 | }; 29 | 30 | "All your base are belong to us" 31 | 32 | __END__ 33 | 34 | =encoding utf8 35 | 36 | =head1 NAME 37 | 38 | parent - Establish an ISA relationship with base classes at compile time 39 | 40 | =head1 SYNOPSIS 41 | 42 | package Baz; 43 | use parent qw(Foo Bar); 44 | 45 | =head1 DESCRIPTION 46 | 47 | Allows you to both load one or more modules, while setting up inheritance from 48 | those modules at the same time. Mostly similar in effect to 49 | 50 | package Baz; 51 | BEGIN { 52 | require Foo; 53 | require Bar; 54 | push @ISA, qw(Foo Bar); 55 | } 56 | 57 | By default, every base class needs to live in a file of its own. 58 | If you want to have a subclass and its parent class in the same file, you 59 | can tell C not to load any modules by using the C<-norequire> switch: 60 | 61 | package Foo; 62 | sub exclaim { "I CAN HAS PERL" } 63 | 64 | package DoesNotLoadFooBar; 65 | use parent -norequire, 'Foo', 'Bar'; 66 | # will not go looking for Foo.pm or Bar.pm 67 | 68 | This is equivalent to the following code: 69 | 70 | package Foo; 71 | sub exclaim { "I CAN HAS PERL" } 72 | 73 | package DoesNotLoadFooBar; 74 | push @DoesNotLoadFooBar::ISA, 'Foo', 'Bar'; 75 | 76 | This is also helpful for the case where a package lives within 77 | a differently named file: 78 | 79 | package MyHash; 80 | use Tie::Hash; 81 | use parent -norequire, 'Tie::StdHash'; 82 | 83 | This is equivalent to the following code: 84 | 85 | package MyHash; 86 | require Tie::Hash; 87 | push @ISA, 'Tie::StdHash'; 88 | 89 | If you want to load a subclass from a file that C would 90 | not consider an eligible filename (that is, it does not end in 91 | either C<.pm> or C<.pmc>), use the following code: 92 | 93 | package MySecondPlugin; 94 | require './plugins/custom.plugin'; # contains Plugin::Custom 95 | use parent -norequire, 'Plugin::Custom'; 96 | 97 | =head1 DIAGNOSTICS 98 | 99 | =over 4 100 | 101 | =item Class 'Foo' tried to inherit from itself 102 | 103 | Attempting to inherit from yourself generates a warning. 104 | 105 | package Foo; 106 | use parent 'Foo'; 107 | 108 | =back 109 | 110 | =head1 HISTORY 111 | 112 | This module was forked from L to remove the cruft 113 | that had accumulated in it. 114 | 115 | =head1 CAVEATS 116 | 117 | =head1 SEE ALSO 118 | 119 | L 120 | 121 | =head1 AUTHORS AND CONTRIBUTORS 122 | 123 | Rafaël Garcia-Suarez, Bart Lateur, Max Maischein, Anno Siegel, Michael Schwern 124 | 125 | =head1 MAINTAINER 126 | 127 | Max Maischein C< corion@cpan.org > 128 | 129 | Copyright (c) 2007-10 Max Maischein C<< >> 130 | Based on the idea of C, which was introduced with Perl 5.004_04. 131 | 132 | =head1 LICENSE 133 | 134 | This module is released under the same terms as Perl itself. 135 | 136 | =cut 137 | -------------------------------------------------------------------------------- /bin/logify.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # logify.pl 3 | ############ 4 | # Converts an Objective-C header file (or anything containing a @interface and method definitions) 5 | #+into a Logos input file which causes all function calls to be logged. 6 | # 7 | # Accepts input on stdin or via filename specified on the commandline. 8 | 9 | # Lines are only processed if we were in an @interface, so you can run this on a file containing 10 | # an @implementation, as well. 11 | use strict; 12 | 13 | use FindBin; 14 | use lib "$FindBin::Bin/lib"; 15 | 16 | use Logos::Method; 17 | use Logos::Util; 18 | $Logos::Util::errorhandler = sub { 19 | die "$ARGV:$.: error: missing closing parenthesis$/" 20 | }; 21 | 22 | my $interface = 0; 23 | while(my $line = <>) { 24 | if($line =~ m/^[+-]\s*\((.*?)\).*?(?=;)/ && $interface == 1) { 25 | print logLineForDeclaration($&); 26 | } elsif($line =~ m/^\s*\@property\s*\((.*?)\)\s*(.*?)\b([\$a-zA-Z_][\$_a-zA-Z0-9]*)(?=;)/ && $interface == 1) { 27 | my @attributes = smartSplit(qr/\s*,\s*/, $1); 28 | my $propertyName = $3; 29 | my $type = $2; 30 | my $readonly = scalar(grep(/readonly/, @attributes)); 31 | my %methods = ("setter" => "set".ucfirst($propertyName).":", "getter" => $propertyName); 32 | foreach my $attribute (@attributes) { 33 | next if($attribute !~ /=/); 34 | my @x = smartSplit(qr/\s*=\s*/, $attribute); 35 | $methods{$x[0]} = $x[1]; 36 | } 37 | if($readonly == 0) { 38 | print logLineForDeclaration("- (void)".$methods{"setter"}."($type)$propertyName"); 39 | } 40 | print logLineForDeclaration("- ($type)".$methods{"getter"}); 41 | } elsif($line =~ m/^\@interface\s+(.*?)\s*[:(]/ && $interface == 0) { 42 | print "%hook $1\n"; 43 | $interface = 1; 44 | } elsif($line =~ m/^\@end/ && $interface == 1) { 45 | print "%end\n"; 46 | $interface = 0; 47 | } 48 | } 49 | 50 | sub logLineForDeclaration { 51 | my $declaration = shift; 52 | $declaration =~ m/^[+-]\s*\((.*?)\).*?/; 53 | my $rtype = $1; 54 | my $innards = "%log; "; 55 | if($rtype ne "void") { 56 | $innards .= "$rtype r = %orig; "; 57 | $innards .= "NSLog(@\" = ".Logos::Method::formatCharForArgType($rtype)."\", ".Logos::Method::printArgForArgType($rtype, "r")."); " if defined Logos::Method::printArgForArgType($rtype, "r"); 58 | $innards .= "return r; "; 59 | } else { 60 | $innards .= "%orig; "; 61 | } 62 | return "$declaration { $innards}\n"; 63 | } 64 | -------------------------------------------------------------------------------- /bin/nicify.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use File::Find; 6 | use File::Spec; 7 | use Archive::Tar; 8 | use Cwd qw(abs_path getcwd); 9 | 10 | use FindBin; 11 | use lib "$FindBin::Bin/lib"; 12 | use NIC::Formats::NICTar; 13 | 14 | package NIC::Archive::Tar::File; 15 | use parent "Archive::Tar::File"; 16 | sub new { 17 | my $class = shift; 18 | my $self = Archive::Tar::File->new(@_); 19 | bless($self, $class); 20 | return $self; 21 | } 22 | 23 | sub _prefix_and_file { 24 | my $self = shift; 25 | my $path = shift; 26 | my ($prefix, $file) = $self->SUPER::_prefix_and_file($path); 27 | $prefix =~ s/^/\.\// if $prefix ne "" && $prefix ne "." && $prefix !~ /^\.\//; 28 | return ($prefix, $file); 29 | } 30 | 1; 31 | package main; 32 | 33 | if(@ARGV == 0) { 34 | exitWithError("Syntax: $FindBin::Script "); 35 | } 36 | 37 | my $cwd = abs_path(getcwd()); 38 | my $tar = Archive::Tar->new(); 39 | my $controlfile = undef; 40 | our @tarfiles = ( 41 | NIC::Archive::Tar::File->new(data=>"./", "", {type=>Archive::Tar::Constant::DIR, uid=>0, gid=>0, mode=>0755}), 42 | NIC::Archive::Tar::File->new(data=>"./NIC/", "", {type=>Archive::Tar::Constant::DIR, uid=>0, gid=>0, mode=>0777}) 43 | ); 44 | 45 | chdir $ARGV[0]; 46 | 47 | my $control_in = undef; 48 | 49 | if(-f "pre.NIC") { 50 | warning("Using legacy pre.NIC as ./NIC/control."); 51 | $control_in = "./pre.NIC"; 52 | } elsif(-f "NIC/control") { 53 | $control_in = "./NIC/control"; 54 | } 55 | 56 | if(!$control_in) { 57 | exitWithError("No control file found at NIC/control."); 58 | exit 1; 59 | } 60 | 61 | $controlfile = NIC::Archive::Tar::File->new(file=>$control_in); 62 | $controlfile->prefix("./NIC"); 63 | $controlfile->name("control"); 64 | push(@tarfiles, $controlfile); 65 | 66 | find({wanted => \&wanted, preprocess => \&preprocess, follow => 0, no_chdir => 1}, "."); 67 | 68 | $tar->add_files(@tarfiles); 69 | 70 | chdir($cwd); 71 | my $newnic = NIC::Formats::NICTar->new($tar); 72 | if(!defined $newnic->name) { 73 | exitWithError("Template has no name. Please insert a `name \"\"` directive into $control_in."); 74 | } 75 | 76 | { my $_ = scalar @{$newnic->{CONTENTS}}; info("$_ entr".($_==1?"y.":"ies.")); } 77 | { my $_ = scalar @{$newnic->{PROMPTS}}; info("$_ prompt".($_==1?".":"s.")); } 78 | my $constraints = 0; 79 | { 80 | my %constrainthash; 81 | for(@{$newnic->{CONTENTS}}) { 82 | for my $c ($_->constraints) { 83 | $constrainthash{$c}++; 84 | } 85 | } 86 | $constraints = scalar keys %constrainthash; 87 | } 88 | { my $_ = $constraints; info("$_ constraint".($_==1?".":"s.")); } 89 | 90 | my $fixedfn = join("_", File::Spec->splitdir($newnic->name)); 91 | my $filename = $fixedfn.".nic.tar"; 92 | $tar->write($filename) and info("Archived template \"".$newnic->name."\" to $filename."); 93 | 94 | sub preprocess { 95 | my @list = @_; 96 | if($File::Find::dir eq "./NIC") { 97 | @list = grep !/^control$/, @list; 98 | } 99 | @list = grep !/^pre.NIC$/ && !/^\.svn$/ && !/^\.git$/ && !/^_MTN$/ && !/\.nic\.tar$/ && !/^\.DS_Store$/ && !/^\._/, @list; 100 | return @list; 101 | } 102 | 103 | sub wanted { 104 | local $_ = $File::Find::name; 105 | my $mode = (stat)[2]; 106 | 107 | my $tarfile = undef; 108 | if(-d) { 109 | s/$/\// if !/\/$/; 110 | return if /^\.\/$/; 111 | return if /^\.\/NIC\/?$/; 112 | $tarfile = NIC::Archive::Tar::File->new(data=>$_, "", {mode=>$mode, uid=>0, gid=>0, type=>Archive::Tar::Constant::DIR}); 113 | } elsif(-f && ! -l) { 114 | $tarfile = NIC::Archive::Tar::File->new(file=>$_); 115 | $tarfile->mode($mode); 116 | $tarfile->uid(0); 117 | $tarfile->gid(0); 118 | } elsif(-l) { 119 | $tarfile = NIC::Archive::Tar::File->new(data=>$_, "", {linkname=>readlink($_), uid=>0, gid=>0, type=>Archive::Tar::Constant::SYMLINK}); 120 | } 121 | push(@tarfiles, $tarfile) if $tarfile; 122 | } 123 | 124 | sub slurp { 125 | my $fn = shift; 126 | open(my($fh), "<", $fn); 127 | local $/ = undef; 128 | my $d = <$fh>; 129 | return $d; 130 | } 131 | 132 | sub info { 133 | my $text = shift; 134 | print STDERR "[info] ", $text, $/; 135 | } 136 | 137 | sub warning { 138 | my $text = shift; 139 | print STDERR "[warning] ", $text, $/; 140 | } 141 | 142 | sub exitWithError { 143 | my $error = shift; 144 | print STDERR "[error] ", $error, $/; 145 | exit 1; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /bin/package_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function build_num_from_file { 4 | version=$(< "$1") 5 | version=${version##*-} 6 | version=${version%%+*} 7 | version=${version%%~*} 8 | echo -n "$version" 9 | } 10 | 11 | while getopts ":N:V:" flag; do 12 | case "$flag" in 13 | :) echo "$0: Option -$OPTARG requires an argument." 1>&2 14 | exit 1 15 | ;; 16 | \?) echo "$0: What're you talking about?" 1>&2 17 | exit 1 18 | ;; 19 | N) package="$OPTARG" ;; 20 | V) version="$OPTARG" ;; 21 | esac 22 | done 23 | 24 | if [[ ! -d "${THEOS_PROJECT_DIR}/.theos/packages" ]]; then 25 | if [[ -d "${THEOS_PROJECT_DIR}/.debmake" ]]; then 26 | mkdir -p "${THEOS_PROJECT_DIR}/.theos" 27 | mv "${THEOS_PROJECT_DIR}/.debmake" "${THEOS_PROJECT_DIR}/.theos/packages" 28 | else 29 | mkdir -p "${THEOS_PROJECT_DIR}/.theos/packages" 30 | fi 31 | fi 32 | 33 | versionfile="${THEOS_PROJECT_DIR}/.theos/packages/$package-$version" 34 | build_number=0 35 | 36 | if [[ ! -e "$versionfile" ]]; then 37 | build_number=1 38 | else 39 | build_number=$(build_num_from_file "$versionfile") 40 | let build_number++ 41 | fi 42 | 43 | echo -n "$build_number" > "$versionfile" 44 | echo "$build_number" 45 | -------------------------------------------------------------------------------- /bin/target.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use File::Temp; 3 | 4 | my @o; 5 | for(reverse @ARGV) { 6 | my $i = 0; 7 | for my $a (split /:/) { 8 | if(length $a > 0) { 9 | @o = () if($i == 0 && $o[$i] && $o[$i] ne $a); 10 | $o[$i] = $a; 11 | } 12 | $i++; 13 | } 14 | } 15 | #print join(':', map { $_ eq "" ? "-" : $_ } @o); 16 | my $i = 0; 17 | my ($fh, $tempfile) = File::Temp::tempfile(); 18 | binmode($fh, ":utf8"); 19 | 20 | for(@o) { 21 | print $fh "export __THEOS_TARGET_ARG_$i := $_\n"; 22 | ++$i; 23 | } 24 | 25 | close($fh); 26 | print $tempfile,$/; 27 | -------------------------------------------------------------------------------- /bin/vercmp.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use warnings; 3 | use strict; 4 | if(@ARGV < 3) { 5 | exit 1; 6 | } 7 | my @afirst = split(/\./, $ARGV[0]); 8 | my $op = $ARGV[1]; 9 | my @asecond = split(/\./, $ARGV[2]); 10 | 11 | push(@afirst, 0) while(@afirst < @asecond); 12 | push(@asecond, 0) while(@asecond < @afirst); 13 | 14 | my $v1 = 0; 15 | my $v2 = 0; 16 | map { ($v1 *= 100) += $_ } (@afirst); 17 | map { ($v2 *= 100) += $_ } (@asecond); 18 | 19 | print "1" if $v1 > $v2 && $op eq "gt"; 20 | print "1" if $v1 < $v2 && $op eq "lt"; 21 | print "1" if $v1 >= $v2 && $op eq "ge"; 22 | print "1" if $v1 <= $v2 && $op eq "le"; 23 | print "1" if $v1 == $v2 && $op eq "eq"; 24 | -------------------------------------------------------------------------------- /documentation/Makefile: -------------------------------------------------------------------------------- 1 | all: makefiles.html 2 | 3 | %.html: %.docbook 4 | xsltproc --output $@ /usr/share/sgml/docbook/xsl-stylesheets/xhtml/docbook.xsl $< 5 | 6 | clean: 7 | rm *.html 8 | -------------------------------------------------------------------------------- /extras/vim/README: -------------------------------------------------------------------------------- 1 | Place the following in filetype.vim. 2 | 3 | au BufNewFile,BufRead *.xm,*.xmm,*.l.mm setf logos 4 | -------------------------------------------------------------------------------- /extras/vim/ftplugin/logos.vim: -------------------------------------------------------------------------------- 1 | " Vim filetype plugin file 2 | " Language: Logos (Objective-C++) 3 | " Maintainer: Dustin Howett 4 | " Latest Revision: December 22, 2009 5 | 6 | if exists("b:did_ftplugin") 7 | finish 8 | endif 9 | 10 | " Behaves just like Objective-C 11 | runtime! ftplugin/objc.vim 12 | -------------------------------------------------------------------------------- /extras/vim/indent/logos.vim: -------------------------------------------------------------------------------- 1 | " Vim filetype plugin file 2 | " Language: Logos (Objective-C++) 3 | " Maintainer: Dustin Howett 4 | " Latest Revision: December 22, 2009 5 | 6 | runtime! indent/objc.vim 7 | -------------------------------------------------------------------------------- /extras/vim/syntax/logos.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Logos (Objective-C++) 3 | " Maintainer: Dustin Howett 4 | " Latest Revision: April 2, 2011 5 | 6 | if exists("b:current_syntax") 7 | finish 8 | endif 9 | 10 | runtime! syntax/objc.vim 11 | 12 | syn match logosDirective '%\(hook\|group\|subclass\|ctor\)' display 13 | 14 | syn match logosDirective '%end' display 15 | 16 | syn match logosDirective '%class' display skipwhite nextgroup=logosClassName 17 | 18 | syn match logosDirective '%log' display contained containedin=logosHook,logosSubclass,logosGroup 19 | syn match logosDirective '%orig' display contained containedin=logosHook,logosSubclass,logosGroup 20 | 21 | syn match logosDirective '%init' display 22 | syn match logosDirective '%new' display 23 | syn region logosInit matchgroup=logosDirective start='%init(' end=')' contains=cParen 24 | 25 | syn region logosNew oneline matchgroup=logosNew start='%new(' end=')' contains=logosTypeEncoding,logosTypeEncodingUnion 26 | 27 | syn match logosTypeEncoding '[*@#:\[\]^?{}A-Za-z0-9$=]' display contained 28 | syn region logosTypeEncodingUnion oneline matchgroup=logosTypeEncoding start='(' end=')' contained transparent 29 | 30 | syn region logosInfixClass oneline matchgroup=logosInfixClass start='%c(' end=')' contains=logosClassName containedin=objcMessage 31 | syn match logosClassName '[A-Za-z$_][A-Za-z0-9_$]*' display contained 32 | 33 | syn region logosHook start="%hook" end="%end" fold transparent keepend extend 34 | syn region logosGroup start="%group" end="%end" fold transparent keepend extend 35 | syn region logosSubclass start="%subclass" end="%end" fold transparent keepend extend 36 | 37 | syn match logosError '\(@interface\|@implementation\)' contained containedin=logosHook,logosSubclass,logosGroup 38 | syn match logosError '\(%hook\|%group\|%subclass\)' contained containedin=objcImp,objcHeader 39 | 40 | syn match logosDirectiveArgument '\(%\(hook\|subclass\|group\)\)\@<=\s\+\k\+' display contained containedin=logosHook,logosSubclass,logosGroup 41 | syn match logosSubclassSuperclassName '\(%subclass\s\+\k\+\s*:\)\@<=\s*\k\+' display contained containedin=logosHook,logosSubclass,logosGroup 42 | 43 | syn cluster cParenGroup add=logosNew,logosInfixClass,logosInit 44 | syn cluster cParenGroup add=logosTypeEncoding,logosTypeEncodingUnion 45 | syn cluster cParenGroup add=logosClassName 46 | syn cluster cParenGroup add=logosDirectiveArgument,logosSubclassSuperclassName 47 | syn cluster cParenGroup add=logosError 48 | syn cluster cParenGroup add=logosHook,logosGroup,logosSubclass 49 | 50 | syn cluster cPreProcGroup add=logosClassName,logosDirective,logosTypeEncoding,logosTypeEncodingUnion 51 | 52 | syn cluster cMultiGroup add=logosTypeEncoding,logosTypeEncodingUnion,logosClassName 53 | 54 | syn sync match logosHookSync grouphere logosHook "%hook" 55 | syn sync match logosGroupSync grouphere logosGroup "%group" 56 | syn sync match logosSubclassSync grouphere logosSubclass "%subclass" 57 | syn sync match logosEndSync grouphere NONE "%end" 58 | 59 | let b:current_syntax = "logos" 60 | hi def link logosDirective PreProc 61 | hi def link logosDirectiveArgument String 62 | hi def link logosError Error 63 | 64 | hi def link logosTypeEncoding logosDirectiveArgument 65 | hi def link logosGroupName logosDirectiveArgument 66 | hi def link logosClassName logosDirectiveArgument 67 | hi def link logosSubclassSuperclassName logosClassName 68 | hi def link logosNew logosDirective 69 | hi def link logosInfixClass logosDirective 70 | -------------------------------------------------------------------------------- /git-submodule-recur.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SELF=$(cd ${0%/*} && echo $PWD/${0##*/}) 4 | 5 | case "$1" in 6 | "init") CMD="submodule update --init" ;; 7 | *) CMD="$*" ;; 8 | esac 9 | 10 | git $CMD 11 | git submodule foreach "$SELF" $CMD 12 | -------------------------------------------------------------------------------- /lib/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpetrich/theos/6b05eac5169242b99a599a94e692d0d9e8baa855/lib/.keep -------------------------------------------------------------------------------- /makefiles/aggregate.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_AGGREGATE_MK_LOADED),) 2 | _THEOS_AGGREGATE_MK_LOADED := 1 3 | 4 | ifeq ($(THEOS_CURRENT_INSTANCE),) 5 | include $(THEOS_MAKE_PATH)/master/aggregate.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/application.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/application.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),application) 5 | include $(THEOS_MAKE_PATH)/instance/application.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/bundle.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/bundle.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),bundle) 5 | include $(THEOS_MAKE_PATH)/instance/bundle.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/common.mk: -------------------------------------------------------------------------------- 1 | all:: 2 | 3 | ifeq ($(notdir $(firstword $(SUDO_COMMAND))),make) 4 | $(error Do not use 'sudo make') 5 | endif 6 | 7 | THEOS_PROJECT_DIR ?= $(shell pwd) 8 | _THEOS_LOCAL_DATA_DIR := $(THEOS_PROJECT_DIR)/.theos 9 | 10 | ### Functions 11 | # Function for getting a clean absolute path from cd. 12 | __clean_pwd = $(shell (unset CDPATH; cd "$(1)"; pwd)) 13 | # Truthiness 14 | _THEOS_TRUE := 1 15 | _THEOS_FALSE := 16 | __theos_bool = $(if $(filter Y y YES yes 1,$(1)),$(_THEOS_TRUE),$(_THEOS_FALSE)) 17 | # Existence 18 | __exists = $(if $(wildcard $(1)),$(_THEOS_TRUE),$(_THEOS_FALSE)) 19 | __executable = $(if $(shell PATH="$(THEOS_BIN_PATH):$$PATH" type "$(1)" > /dev/null 2>&1 && echo 1),$(_THEOS_TRUE),$(_THEOS_FALSE)) 20 | # Static redefinition 21 | __simplify = $(2)$(eval $(1):=$(2)) 22 | ### 23 | 24 | __THEOS_COMMON_MK_VERSION := 1r 25 | 26 | ifeq ($(_THEOS_PROJECT_MAKEFILE_NAME),) 27 | _THEOS_STATIC_MAKEFILE_LIST := $(filter-out $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 28 | export _THEOS_PROJECT_MAKEFILE_NAME := $(notdir $(lastword $(_THEOS_STATIC_MAKEFILE_LIST))) 29 | endif 30 | 31 | ifeq ($(_THEOS_INTERNAL_TRUE_PATH),) 32 | _THEOS_RELATIVE_MAKE_PATH := $(dir $(lastword $(MAKEFILE_LIST))) 33 | _THEOS_INTERNAL_TRUE_PATH := $(call __clean_pwd,$(_THEOS_RELATIVE_MAKE_PATH)/..) 34 | ifneq ($(words $(_THEOS_INTERNAL_TRUE_PATH)),1) # It's a hack, but it works. 35 | $(shell unlink /tmp/theos &> /dev/null; ln -Ffs "$(_THEOS_INTERNAL_TRUE_PATH)" /tmp/theos) 36 | _THEOS_INTERNAL_TRUE_PATH := /tmp/theos 37 | endif 38 | override THEOS := $(_THEOS_INTERNAL_TRUE_PATH) 39 | export _THEOS_INTERNAL_TRUE_PATH 40 | endif 41 | THEOS_MAKE_PATH := $(THEOS)/makefiles 42 | THEOS_BIN_PATH := $(THEOS)/bin 43 | THEOS_LIBRARY_PATH := $(THEOS)/lib 44 | THEOS_INCLUDE_PATH := $(THEOS)/include 45 | THEOS_FALLBACK_INCLUDE_PATH := $(THEOS)/include/_fallback 46 | THEOS_MODULE_PATH := $(THEOS)/mod 47 | export THEOS THEOS_BIN_PATH THEOS_MAKE_PATH THEOS_LIBRARY_PATH THEOS_INCLUDE_PATH THEOS_FALLBACK_INCLUDE_PATH 48 | export THEOS_PROJECT_DIR 49 | 50 | export PATH := $(THEOS_BIN_PATH):$(PATH) 51 | 52 | ifeq ($(THEOS_SCHEMA),) 53 | _THEOS_SCHEMA := $(shell echo "$(strip $(schema) $(SCHEMA))" | tr 'a-z' 'A-Z') 54 | _THEOS_ON_SCHEMA := DEFAULT $(filter-out -%,$(_THEOS_SCHEMA)) 55 | ifeq ($(call __theos_bool,$(or $(debug),$(DEBUG))),$(_THEOS_TRUE)) 56 | _THEOS_ON_SCHEMA += DEBUG 57 | endif 58 | _THEOS_OFF_SCHEMA := $(patsubst -%,%,$(filter -%,$(_THEOS_SCHEMA))) 59 | override THEOS_SCHEMA := $(strip $(filter-out $(_THEOS_OFF_SCHEMA),$(_THEOS_ON_SCHEMA))) 60 | override _THEOS_CLEANED_SCHEMA_SET := $(shell echo "$(filter-out DEFAULT,$(THEOS_SCHEMA))" | tr -Cd ' A-Z' | tr ' A-Z' '_a-z') 61 | export THEOS_SCHEMA _THEOS_CLEANED_SCHEMA_SET 62 | endif 63 | 64 | ### 65 | # __schema_defined_var_names bears explanation: 66 | # For each schema'd variable gathered from __schema_all_var_names, we generate a list of 67 | # "origin:name" pairs, and then filter out all pairs where the origin is "undefined". 68 | # We then substitute " " for ":" and take the last word, so we end up with only the entries from 69 | # __schema_all_var_names that are defined. 70 | __schema_all_var_names = $(foreach sch,$(THEOS_SCHEMA),$(subst DEFAULT.,,$(sch).)$(1)$(2)) 71 | __schema_defined_var_names = $(foreach tuple,$(filter-out undefined:%,$(foreach schvar,$(call __schema_all_var_names,$(1),$(2)),$(origin $(schvar)):$(schvar))),$(lastword $(subst :, ,$(tuple)))) 72 | __schema_var_all = $(strip $(foreach sch,$(call __schema_all_var_names,$(1),$(2)),$($(sch)))) 73 | __schema_var_name_last = $(strip $(lastword $(call __schema_defined_var_names,$(1),$(2)))) 74 | __schema_var_last = $(strip $($(lastword $(call __schema_defined_var_names,$(1),$(2))))) 75 | 76 | ifeq ($(_THEOS_HAS_STAGING_LAYOUT),) 77 | _THEOS_HAS_STAGING_LAYOUT := $(call __exists,$(THEOS_PROJECT_DIR)/layout) 78 | endif 79 | 80 | _THEOS_LOAD_MODULES := $(sort $(call __schema_var_all,,MODULES) $(THEOS_AUTOLOAD_MODULES)) 81 | __mod = -include $$(foreach mod,$$(_THEOS_LOAD_MODULES),$$(THEOS_MODULE_PATH)/$$(mod)/$(1)) 82 | 83 | include $(THEOS_MAKE_PATH)/legacy.mk 84 | 85 | ifneq ($(_THEOS_PLATFORM_CALCULATED),1) 86 | uname_s := $(shell uname -s) 87 | uname_p := $(shell uname -p) 88 | export _THEOS_PLATFORM_ARCH = $(uname_s)-$(uname_p) 89 | export _THEOS_PLATFORM = $(uname_s) 90 | export _THEOS_PLATFORM_CALCULATED := 1 91 | endif 92 | 93 | -include $(THEOS_MAKE_PATH)/platform/$(_THEOS_PLATFORM_ARCH).mk 94 | -include $(THEOS_MAKE_PATH)/platform/$(_THEOS_PLATFORM).mk 95 | $(eval $(call __mod,platform/$(_THEOS_PLATFORM_ARCH).mk)) 96 | $(eval $(call __mod,platform/$(_THEOS_PLATFORM).mk)) 97 | 98 | ifneq ($(_THEOS_TARGET_CALCULATED),1) 99 | __TARGET_MAKEFILE := $(shell $(THEOS_BIN_PATH)/target.pl "$(target)" "$(call __schema_var_last,,TARGET)" "$(_THEOS_PLATFORM_DEFAULT_TARGET)") 100 | -include $(__TARGET_MAKEFILE) 101 | $(shell rm -f $(__TARGET_MAKEFILE) > /dev/null 2>&1) 102 | export _THEOS_TARGET := $(__THEOS_TARGET_ARG_0) 103 | ifeq ($(_THEOS_TARGET),) 104 | $(error You did not specify a target, and the "$(THEOS_PLATFORM_NAME)" platform does not define a default target) 105 | endif 106 | export _THEOS_TARGET_CALCULATED := 1 107 | endif 108 | 109 | -include $(THEOS_MAKE_PATH)/targets/$(_THEOS_PLATFORM_ARCH)/$(_THEOS_TARGET).mk 110 | -include $(THEOS_MAKE_PATH)/targets/$(_THEOS_PLATFORM)/$(_THEOS_TARGET).mk 111 | -include $(THEOS_MAKE_PATH)/targets/$(_THEOS_TARGET).mk 112 | $(eval $(call __mod,targets/$(_THEOS_PLATFORM_ARCH)/$(_THEOS_TARGET).mk)) 113 | $(eval $(call __mod,targets/$(_THEOS_PLATFORM)/$(_THEOS_TARGET).mk)) 114 | $(eval $(call __mod,targets/$(_THEOS_TARGET).mk)) 115 | 116 | ifneq ($(_THEOS_TARGET_LOADED),1) 117 | $(error The "$(_THEOS_TARGET)" target is not supported on the "$(THEOS_PLATFORM_NAME)" platform) 118 | endif 119 | 120 | _THEOS_TARGET_NAME_DEFINE := $(shell echo "$(THEOS_TARGET_NAME)" | tr 'a-z' 'A-Z') 121 | 122 | export TARGET_CC TARGET_CXX TARGET_LD TARGET_STRIP TARGET_CODESIGN_ALLOCATE TARGET_CODESIGN TARGET_CODESIGN_FLAGS 123 | 124 | THEOS_TARGET_INCLUDE_PATH := $(THEOS_INCLUDE_PATH)/$(THEOS_TARGET_NAME) 125 | THEOS_TARGET_LIBRARY_PATH := $(THEOS_LIBRARY_PATH)/$(THEOS_TARGET_NAME) 126 | _THEOS_TARGET_HAS_INCLUDE_PATH := $(call __exists,$(THEOS_TARGET_INCLUDE_PATH)) 127 | _THEOS_TARGET_HAS_LIBRARY_PATH := $(call __exists,$(THEOS_TARGET_LIBRARY_PATH)) 128 | 129 | # Package Format requires Target default and falls back to `none'. 130 | _THEOS_PACKAGE_FORMAT := $(or $(call __schema_var_last,,$(_THEOS_TARGET_NAME_DEFINE)_PACKAGE_FORMAT),$(call __schema_var_last,,PACKAGE_FORMAT),$(_THEOS_TARGET_DEFAULT_PACKAGE_FORMAT),none) 131 | _THEOS_PACKAGE_LAST_FILENAME = $(call __simplify,_THEOS_PACKAGE_LAST_FILENAME,$(shell cat "$(_THEOS_LOCAL_DATA_DIR)/last_package" 2>/dev/null)) 132 | 133 | # ObjC/++ stuff is not here, it's in instance/rules.mk and only added if there are OBJC/OBJCC objects. 134 | _THEOS_INTERNAL_LDFLAGS = $(if $(_THEOS_TARGET_HAS_LIBRARY_PATH),-L$(THEOS_TARGET_LIBRARY_PATH) )-L$(THEOS_LIBRARY_PATH) 135 | 136 | SHOULD_STRIP := $(call __theos_bool,$(or $(strip),$(STRIP),1)) 137 | ifeq ($(SHOULD_STRIP),$(_THEOS_TRUE)) 138 | OPTFLAG ?= -O2 139 | else 140 | OPTFLAG ?= -ggdb -O2 141 | endif 142 | DEBUGFLAG ?= -ggdb 143 | DEBUG.CFLAGS = -DDEBUG $(DEBUGFLAG) -O0 144 | DEBUG.LDFLAGS = $(DEBUGFLAG) -O0 145 | ifneq ($(findstring DEBUG,$(THEOS_SCHEMA)),) 146 | TARGET_STRIP = : 147 | PACKAGE_BUILDNAME ?= debug 148 | endif 149 | 150 | CFLAGS += -I$(THEOS_FALLBACK_INCLUDE_PATH) 151 | _THEOS_INTERNAL_CFLAGS = -DTARGET_$(_THEOS_TARGET_NAME_DEFINE)=1 $(OPTFLAG) -Wall 152 | _THEOS_INTERNAL_IFLAGS = $(if $(_THEOS_TARGET_HAS_INCLUDE_PATH),-I$(THEOS_TARGET_INCLUDE_PATH) )-I$(THEOS_INCLUDE_PATH) -include $(THEOS)/Prefix.pch 153 | ifneq ($(GO_EASY_ON_ME),1) 154 | _THEOS_INTERNAL_LOGOSFLAGS += -c warnings=error 155 | _THEOS_INTERNAL_CFLAGS += -Werror 156 | endif 157 | _THEOS_INTERNAL_LOGOSFLAGS += -c generator=internal 158 | 159 | THEOS_BUILD_DIR ?= . 160 | 161 | ifneq ($(_THEOS_CLEANED_SCHEMA_SET),) 162 | _THEOS_OBJ_DIR_EXTENSION = /$(_THEOS_CLEANED_SCHEMA_SET) 163 | endif 164 | ifneq ($(THEOS_TARGET_NAME),$(_THEOS_PLATFORM_DEFAULT_TARGET)) 165 | THEOS_OBJ_DIR_NAME ?= .theos/obj/$(THEOS_TARGET_NAME)$(_THEOS_OBJ_DIR_EXTENSION) 166 | else 167 | THEOS_OBJ_DIR_NAME ?= .theos/obj$(_THEOS_OBJ_DIR_EXTENSION) 168 | endif 169 | ifeq ($(THEOS_CURRENT_ARCH),) 170 | THEOS_OBJ_DIR = $(THEOS_BUILD_DIR)/$(THEOS_OBJ_DIR_NAME) 171 | else 172 | THEOS_OBJ_DIR = $(THEOS_BUILD_DIR)/$(THEOS_OBJ_DIR_NAME)/$(THEOS_CURRENT_ARCH) 173 | endif 174 | 175 | THEOS_STAGING_DIR_NAME ?= .theos/_ 176 | THEOS_STAGING_DIR = $(THEOS_PROJECT_DIR)/$(THEOS_STAGING_DIR_NAME) 177 | _SPACE := 178 | _SPACE += 179 | _THEOS_ESCAPED_STAGING_DIR = $(subst $(_SPACE),\ ,$(THEOS_STAGING_DIR)) 180 | 181 | ifeq ($(THEOS_PACKAGE_DIR_NAME),) 182 | THEOS_PACKAGE_DIR = $(THEOS_BUILD_DIR) 183 | else 184 | THEOS_PACKAGE_DIR = $(THEOS_BUILD_DIR)/$(THEOS_PACKAGE_DIR_NAME) 185 | endif 186 | 187 | # $(warning ...) expands to the empty string, so the contents of THEOS_STAGING_DIR are not damaged in this copy. 188 | FW_PACKAGE_STAGING_DIR = $(THEOS_STAGING_DIR)$(warning FW_PACKAGE_STAGING_DIR is deprecated; please use THEOS_STAGING_DIR) 189 | 190 | THEOS_SUBPROJECT_PRODUCT = subproject.o 191 | 192 | include $(THEOS_MAKE_PATH)/messages.mk 193 | ifeq ($(_THEOS_VERBOSE),$(_THEOS_FALSE)) 194 | _THEOS_NO_PRINT_DIRECTORY_FLAG := --no-print-directory 195 | else 196 | _THEOS_NO_PRINT_DIRECTORY_FLAG := 197 | endif 198 | 199 | unexport THEOS_CURRENT_INSTANCE _THEOS_CURRENT_TYPE 200 | 201 | THEOS_RSYNC_EXCLUDES ?= _MTN .git .svn .DS_Store ._* 202 | _THEOS_RSYNC_EXCLUDE_COMMANDLINE := $(foreach exclude,$(THEOS_RSYNC_EXCLUDES),--exclude "$(exclude)") 203 | 204 | FAKEROOT := $(THEOS_BIN_PATH)/fakeroot.sh -p "$(_THEOS_LOCAL_DATA_DIR)/fakeroot" 205 | export FAKEROOT 206 | 207 | _THEOS_MAKE_PARALLEL_BUILDING ?= yes 208 | 209 | ifeq ($(THEOS_CURRENT_INSTANCE),) 210 | include $(THEOS_MAKE_PATH)/stage.mk 211 | include $(THEOS_MAKE_PATH)/package.mk 212 | endif 213 | THEOS_PACKAGE_VERSION = $(call __simplify,THEOS_PACKAGE_VERSION,$(THEOS_PACKAGE_BASE_VERSION)$(warning THEOS_PACKAGE_VERSION is deprecated. Please migrate to THEOS_PACKAGE_BASE_VERSION.)) 214 | 215 | $(eval $(call __mod,common.mk)) 216 | -------------------------------------------------------------------------------- /makefiles/framework.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/framework.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),framework) 5 | include $(THEOS_MAKE_PATH)/instance/framework.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/install/deb_local.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) dpkg -i \"$(_THEOS_PACKAGE_LAST_FILENAME)\""$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) dpkg -r \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/install/deb_remote.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "cat > /tmp/_theos_install.deb; $(THEOS_SUDO_COMMAND) dpkg -i /tmp/_theos_install.deb && rm /tmp/_theos_install.deb" < "$(_THEOS_PACKAGE_LAST_FILENAME)"$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) dpkg -r \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/install/none_local.mk: -------------------------------------------------------------------------------- 1 | internal-install:: stage 2 | install.mergeDir "$(THEOS_STAGING_DIR)" "/" 3 | 4 | internal-uninstall:: 5 | @echo "$(MAKE) uninstall is not supported when packaging is disabled" >&2 6 | @exit 1 7 | -------------------------------------------------------------------------------- /makefiles/install/none_remote.mk: -------------------------------------------------------------------------------- 1 | none_local.mk -------------------------------------------------------------------------------- /makefiles/install/pkg_local.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) sudo installer -pkg \"$(_THEOS_PACKAGE_LAST_FILENAME)\" -target /"$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "pkgutil --files \"$(THEOS_PACKAGE_NAME)\" | tail -r | sed 's/^/\//' | sudo xargs rm -d; $(THEOS_SUDO_COMMAND) pkgutil --forget \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/install/pkg_remote.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "cat > /tmp/_theos_install.pkg; $(THEOS_SUDO_COMMAND) sudo installer -pkg /tmp/_theos_install.pkg && rm /tmp/_theos_install.pkg" < "$(_THEOS_PACKAGE_LAST_FILENAME)"$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "pkgutil --files \"$(THEOS_PACKAGE_NAME)\" | tail -r | sed 's/^/\//' | sudo xargs rm -d; $(THEOS_SUDO_COMMAND) pkgutil --forget \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/install/rpm_local.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) rpm -U --replacepkgs --oldpackage \"$(_THEOS_PACKAGE_LAST_FILENAME)\""$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "rpm -e \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/install/rpm_remote.mk: -------------------------------------------------------------------------------- 1 | internal-install:: 2 | $(ECHO_INSTALLING)true$(ECHO_END) 3 | @if [ -z "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 4 | echo "$(MAKE) install requires that you build a package before you try to install it." >&2; \ 5 | exit 1; \ 6 | fi 7 | @if [ ! -f "$(_THEOS_PACKAGE_LAST_FILENAME)" ]; then \ 8 | echo "Could not find \"$(_THEOS_PACKAGE_LAST_FILENAME)\" to install. Aborting." >&2; \ 9 | exit 1; \ 10 | fi 11 | $(ECHO_NOTHING)install.exec "cat > /tmp/_theos_install.rpm; $(THEOS_SUDO_COMMAND) rpm -U --replacepkgs --oldpackage /tmp/_theos_install.rpm && rm /tmp/_theos_install.rpm" < "$(_THEOS_PACKAGE_LAST_FILENAME)"$(ECHO_END) 12 | 13 | internal-uninstall:: 14 | $(ECHO_NOTHING)install.exec "$(THEOS_SUDO_COMMAND) rpm -e \"$(THEOS_PACKAGE_NAME)\""$(ECHO_END) 15 | -------------------------------------------------------------------------------- /makefiles/instance/application.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-application-all_ internal-application-stage_ internal-application-compile 6 | 7 | ifeq ($(findstring UIKit,$($(THEOS_CURRENT_INSTANCE)_FRAMEWORKS))$(findstring AppKit,$($(THEOS_CURRENT_INSTANCE)_FRAMEWORKS)),) 8 | _THEOS_INTERNAL_LDFLAGS += -framework UIKit 9 | ifeq ($(_THEOS_APPLICATION_WARNED_IMPLICIT_UIKIT_$(THEOS_CURRENT_INSTANCE)),) 10 | internal-application-all_:: 11 | @echo "$(THEOS_CURRENT_INSTANCE): warning: Implicit UIKit linkage for application instances is deprecated. Please add \"UIKit\" to $(THEOS_CURRENT_INSTANCE)_FRAMEWORKS." >&2 12 | export _THEOS_APPLICATION_WARNED_IMPLICIT_UIKIT_$(THEOS_CURRENT_INSTANCE) = 1 13 | endif 14 | endif 15 | 16 | # Bundle Setup 17 | LOCAL_INSTALL_PATH ?= $(strip $($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)) 18 | ifeq ($(LOCAL_INSTALL_PATH),) 19 | LOCAL_INSTALL_PATH = /Applications 20 | endif 21 | 22 | ifeq ($($(THEOS_CURRENT_INSTANCE)_BUNDLE_NAME),) 23 | LOCAL_BUNDLE_NAME = $(THEOS_CURRENT_INSTANCE) 24 | else 25 | LOCAL_BUNDLE_NAME = $($(THEOS_CURRENT_INSTANCE)_BUNDLE_NAME) 26 | endif 27 | 28 | _LOCAL_BUNDLE_FULL_NAME = $(LOCAL_BUNDLE_NAME).app 29 | _THEOS_SHARED_BUNDLE_BUILD_PATH = $(THEOS_OBJ_DIR)/$(_LOCAL_BUNDLE_FULL_NAME) 30 | _THEOS_SHARED_BUNDLE_STAGE_PATH = $(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)/$(_LOCAL_BUNDLE_FULL_NAME) 31 | _LOCAL_INSTANCE_TARGET := $(_LOCAL_BUNDLE_FULL_NAME)$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY)/$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT) 32 | include $(THEOS_MAKE_PATH)/instance/shared/bundle.mk 33 | # End Bundle Setup 34 | 35 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 36 | internal-application-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 37 | else 38 | internal-application-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all 39 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 40 | internal-application-compile \ 41 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 42 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 43 | 44 | internal-application-compile: $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 45 | endif 46 | 47 | $(eval $(call _THEOS_TEMPLATE_DEFAULT_LINKING_RULE,$(_LOCAL_INSTANCE_TARGET))) 48 | 49 | internal-application-stage_:: shared-instance-bundle-stage 50 | 51 | $(eval $(call __mod,instance/application.mk)) 52 | -------------------------------------------------------------------------------- /makefiles/instance/bundle.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-bundle-all_ internal-bundle-stage_ internal-bundle-compile 6 | 7 | _THEOS_INTERNAL_LDFLAGS += -dynamiclib 8 | 9 | # Bundle Setup 10 | LOCAL_BUNDLE_NAME = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_NAME),$(THEOS_CURRENT_INSTANCE)) 11 | LOCAL_BUNDLE_EXTENSION = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_EXTENSION),bundle) 12 | 13 | _LOCAL_BUNDLE_FULL_NAME = $(LOCAL_BUNDLE_NAME).$(LOCAL_BUNDLE_EXTENSION) 14 | _THEOS_SHARED_BUNDLE_BUILD_PATH = $(THEOS_OBJ_DIR)/$(_LOCAL_BUNDLE_FULL_NAME) 15 | _THEOS_SHARED_BUNDLE_STAGE_PATH = $(THEOS_STAGING_DIR)$($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)/$(_LOCAL_BUNDLE_FULL_NAME) 16 | _LOCAL_INSTANCE_TARGET := $(_LOCAL_BUNDLE_FULL_NAME)$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY)/$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT) 17 | include $(THEOS_MAKE_PATH)/instance/shared/bundle.mk 18 | # End Bundle Setup 19 | 20 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 21 | internal-bundle-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 22 | else 23 | internal-bundle-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all 24 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 25 | internal-bundle-compile \ 26 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 27 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 28 | 29 | internal-bundle-compile: $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 30 | endif 31 | 32 | ifneq ($(OBJ_FILES_TO_LINK),) 33 | 34 | $(eval $(call _THEOS_TEMPLATE_DEFAULT_LINKING_RULE,$(_LOCAL_INSTANCE_TARGET),nowarn)) 35 | 36 | else # OBJ_FILES_TO_LINK == "" 37 | 38 | $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET): 39 | $(NOTICE_EMPTY_LINKING) 40 | 41 | endif # OBJ_FILES_TO_LINK 42 | 43 | internal-bundle-stage_:: shared-instance-bundle-stage 44 | 45 | $(eval $(call __mod,instance/bundle.mk)) 46 | -------------------------------------------------------------------------------- /makefiles/instance/framework.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-framework-all_ internal-framework-stage_ internal-framework-compile 6 | 7 | 8 | # Bundle Setup 9 | LOCAL_INSTALL_PATH ?= $(or $(strip $($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)),/Library/Frameworks) 10 | LOCAL_BUNDLE_NAME = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_NAME),$($(THEOS_CURRENT_INSTANCE)_FRAMEWORK_NAME),$(THEOS_CURRENT_INSTANCE)) 11 | 12 | _LOCAL_BUNDLE_FULL_NAME = $(LOCAL_BUNDLE_NAME).framework 13 | _THEOS_SHARED_BUNDLE_BUILD_PATH = $(THEOS_OBJ_DIR)/$(_LOCAL_BUNDLE_FULL_NAME) 14 | _THEOS_SHARED_BUNDLE_STAGE_PATH = $(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)/$(_LOCAL_BUNDLE_FULL_NAME) 15 | _LOCAL_INSTANCE_TARGET := $(_LOCAL_BUNDLE_FULL_NAME)$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY)/$(THEOS_CURRENT_INSTANCE) 16 | include $(THEOS_MAKE_PATH)/instance/shared/bundle.mk 17 | # End Bundle Setup 18 | 19 | _THEOS_INTERNAL_LDFLAGS += -dynamiclib -install_name "$(LOCAL_INSTALL_PATH)/$(_LOCAL_INSTANCE_TARGET)" 20 | 21 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 22 | internal-framework-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 23 | else 24 | internal-framework-all_:: $(_OBJ_DIR_STAMPS) shared-instance-bundle-all 25 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 26 | internal-framework-compile \ 27 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 28 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 29 | 30 | internal-framework-compile: $(THEOS_OBJ_DIR)/$(_LOCAL_INSTANCE_TARGET) 31 | endif 32 | 33 | $(eval $(call _THEOS_TEMPLATE_DEFAULT_LINKING_RULE,$(_LOCAL_INSTANCE_TARGET))) 34 | 35 | internal-framework-stage_:: shared-instance-bundle-stage 36 | 37 | $(eval $(call __mod,instance/framework.mk)) 38 | -------------------------------------------------------------------------------- /makefiles/instance/library.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-library-all_ internal-library-stage_ internal-library-compile 6 | 7 | LOCAL_INSTALL_PATH ?= $(strip $($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)) 8 | ifeq ($(LOCAL_INSTALL_PATH),) 9 | LOCAL_INSTALL_PATH = /usr/lib 10 | endif 11 | 12 | _THEOS_INTERNAL_LDFLAGS += $(call TARGET_LDFLAGS_DYNAMICLIB,$(THEOS_CURRENT_INSTANCE)$(TARGET_LIB_EXT)) 13 | _THEOS_INTERNAL_CFLAGS += $(TARGET_CFLAGS_DYNAMICLIB) 14 | 15 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 16 | internal-library-all_:: $(_OBJ_DIR_STAMPS) $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_LIB_EXT) 17 | else 18 | internal-library-all_:: $(_OBJ_DIR_STAMPS) 19 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 20 | internal-library-compile \ 21 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 22 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 23 | 24 | internal-library-compile: $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_LIB_EXT) 25 | endif 26 | 27 | $(eval $(call _THEOS_TEMPLATE_DEFAULT_LINKING_RULE,$(THEOS_CURRENT_INSTANCE)$(TARGET_LIB_EXT))) 28 | 29 | ifneq ($($(THEOS_CURRENT_INSTANCE)_INSTALL),0) 30 | internal-library-stage_:: 31 | $(ECHO_NOTHING)mkdir -p "$(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)/"$(ECHO_END) 32 | $(ECHO_NOTHING)cp $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_LIB_EXT) "$(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)/"$(ECHO_END) 33 | endif 34 | 35 | $(eval $(call __mod,instance/library.mk)) 36 | -------------------------------------------------------------------------------- /makefiles/instance/null.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-null-all_ internal-null-stage_ 6 | 7 | internal-null-all_:: 8 | 9 | internal-null-stage_:: 10 | 11 | $(eval $(call __mod,instance/null.mk)) 12 | -------------------------------------------------------------------------------- /makefiles/instance/shared/bundle.mk: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # THEOS_SHARED_BUNDLE_INSTALL_NAME: bundle name and extension 3 | # THEOS_SHARED_BUNDLE_INSTALL_PATH: bundle install path 4 | # _THEOS_SHARED_BUNDLE_STAGE_PATH: bundle resource path (typically just INSTALL_PATH/INSTALL_NAME) 5 | # 6 | # Instance Variables: 7 | # xxx_RESOURCE_FILES: list of resource files to install (why would you use this in favour of xxx_RESOURCE_DIRS? eh.) 8 | # xxx_RESOURCE_DIRS: folders to copy resources from 9 | # note a deviation from gnustep-make's xxx_RESOURCE_DIRS which simply specifies resource subdirectories to create 10 | # defaults to Resources/ if it exists. 11 | 12 | .PHONY: shared-instance-bundle-stage 13 | 14 | ifeq ($(_THEOS_CURRENT_OPERATION),stage) 15 | THEOS_SHARED_BUNDLE_BINARY_PATH = $(_THEOS_SHARED_BUNDLE_STAGE_PATH)/$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY) 16 | THEOS_SHARED_BUNDLE_RESOURCE_PATH = $(_THEOS_SHARED_BUNDLE_STAGE_PATH)/$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY) 17 | else 18 | THEOS_SHARED_BUNDLE_BINARY_PATH = $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY) 19 | THEOS_SHARED_BUNDLE_RESOURCE_PATH = $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY) 20 | endif 21 | 22 | $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY) $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY) $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY):: 23 | $(ECHO_NOTHING)mkdir -p "$@"$(ECHO_END) 24 | 25 | _RESOURCE_FILES := $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_RESOURCES),$($(THEOS_CURRENT_INSTANCE)_RESOURCE_FILES)) 26 | _RESOURCE_DIRS := $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_RESOURCE_DIRS),$($(THEOS_CURRENT_INSTANCE)_RESOURCE_DIRS)) 27 | ifeq ($(_RESOURCE_DIRS),) 28 | ifeq ($(call __exists,Resources),$(_THEOS_TRUE)) 29 | _RESOURCE_DIRS := Resources 30 | else 31 | _RESOURCE_DIRS := 32 | endif 33 | endif 34 | 35 | shared-instance-bundle-all:: $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY) $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY) $(_THEOS_SHARED_BUNDLE_BUILD_PATH)/$(_THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY) 36 | ifneq ($(_RESOURCE_FILES),) 37 | $(ECHO_COPYING_RESOURCE_FILES)for f in $(_RESOURCE_FILES); do \ 38 | if [ -f "$$f" -o -d "$$f" ]; then \ 39 | rsync -a "$$f" "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY)/" $(_THEOS_RSYNC_EXCLUDE_COMMANDLINE); \ 40 | else \ 41 | echo "Warning: ignoring missing bundle resource $$f."; \ 42 | fi; \ 43 | done$(ECHO_END) 44 | endif 45 | ifneq ($(_RESOURCE_DIRS),) 46 | $(ECHO_COPYING_RESOURCE_DIRS)for d in $(_RESOURCE_DIRS); do \ 47 | if [ -d "$$d" ]; then \ 48 | rsync -a "$$d/" "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY)/" $(_THEOS_RSYNC_EXCLUDE_COMMANDLINE); \ 49 | else \ 50 | echo "Warning: ignoring missing bundle resource directory $$d."; \ 51 | fi; \ 52 | done$(ECHO_END) 53 | endif 54 | ifneq ($(_THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY),$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY)) 55 | $(ECHO_NOTHING)if [ -f "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY)/Info.plist" ]; then\ 56 | mv "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)$(_THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY)/Info.plist" "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)$(_THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY)/Info.plist";\ 57 | fi$(ECHO_END) 58 | endif 59 | 60 | shared-instance-bundle-stage:: 61 | ifneq ($($(THEOS_CURRENT_INSTANCE)_INSTALL),0) 62 | $(ECHO_NOTHING)mkdir -p "$(_THEOS_SHARED_BUNDLE_STAGE_PATH)"$(ECHO_END) 63 | $(ECHO_NOTHING)rsync -a "$(_THEOS_SHARED_BUNDLE_BUILD_PATH)/" "$(_THEOS_SHARED_BUNDLE_STAGE_PATH)"$(ECHO_END) 64 | endif 65 | -------------------------------------------------------------------------------- /makefiles/instance/subproject.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-subproject-all_ internal-subproject-stage_ internal-subproject-compile 6 | 7 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 8 | internal-subproject-all_:: $(_OBJ_DIR_STAMPS) $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE).$(THEOS_SUBPROJECT_PRODUCT) 9 | else 10 | internal-subproject-all_:: $(_OBJ_DIR_STAMPS) 11 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 12 | internal-subproject-compile \ 13 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 14 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 15 | 16 | internal-subproject-compile: $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE).$(THEOS_SUBPROJECT_PRODUCT) 17 | endif 18 | 19 | $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE).$(THEOS_SUBPROJECT_PRODUCT): $(OBJ_FILES_TO_LINK) 20 | $(ECHO_LINKING)$(TARGET_LD) -nostdlib -r -d $(ADDITIONAL_LDFLAGS) $(_THEOS_TARGET_LDFLAGS) $(LDFLAGS) -o $@ $^$(ECHO_END) 21 | @echo "$(_THEOS_INTERNAL_LDFLAGS)" > $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE).ldflags 22 | 23 | $(eval $(call __mod,instance/subproject.mk)) 24 | -------------------------------------------------------------------------------- /makefiles/instance/tool.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-tool-all_ internal-tool-stage_ internal-tool-compile 6 | 7 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 8 | internal-tool-all_:: $(_OBJ_DIR_STAMPS) $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT) 9 | else 10 | internal-tool-all_:: $(_OBJ_DIR_STAMPS) 11 | $(ECHO_NOTHING)$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 12 | internal-tool-compile \ 13 | _THEOS_CURRENT_TYPE=$(_THEOS_CURRENT_TYPE) THEOS_CURRENT_INSTANCE=$(THEOS_CURRENT_INSTANCE) _THEOS_CURRENT_OPERATION=compile \ 14 | THEOS_BUILD_DIR="$(THEOS_BUILD_DIR)" _THEOS_MAKE_PARALLEL=yes$(ECHO_END) 15 | 16 | internal-tool-compile: $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT) 17 | endif 18 | 19 | $(eval $(call _THEOS_TEMPLATE_DEFAULT_LINKING_RULE,$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT))) 20 | 21 | LOCAL_INSTALL_PATH = $(strip $($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)) 22 | ifeq ($(LOCAL_INSTALL_PATH),) 23 | LOCAL_INSTALL_PATH = $($(THEOS_CURRENT_INSTANCE)_PACKAGE_TARGET_DIR) 24 | ifeq ($(LOCAL_INSTALL_PATH),) 25 | LOCAL_INSTALL_PATH = /usr/bin 26 | endif 27 | endif 28 | 29 | ifneq ($($(THEOS_CURRENT_INSTANCE)_INSTALL),0) 30 | internal-tool-stage_:: 31 | $(ECHO_NOTHING)mkdir -p "$(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)"$(ECHO_END) 32 | $(ECHO_NOTHING)cp $(THEOS_OBJ_DIR)/$(THEOS_CURRENT_INSTANCE)$(TARGET_EXE_EXT) "$(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)"$(ECHO_END) 33 | endif 34 | 35 | $(eval $(call __mod,instance/tool.mk)) 36 | -------------------------------------------------------------------------------- /makefiles/instance/tweak.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | .PHONY: internal-tweak-all_ internal-tweak-stage_ 6 | 7 | LOCAL_INSTALL_PATH ?= $(strip $($(THEOS_CURRENT_INSTANCE)_INSTALL_PATH)) 8 | ifeq ($(LOCAL_INSTALL_PATH),) 9 | LOCAL_INSTALL_PATH = /Library/MobileSubstrate/DynamicLibraries 10 | endif 11 | 12 | include $(THEOS_MAKE_PATH)/instance/library.mk 13 | 14 | internal-tweak-all_:: internal-library-all_ 15 | 16 | internal-tweak-compile: internal-library-compile 17 | 18 | ifneq ($(strip $($(THEOS_CURRENT_INSTANCE)_BUNDLE_RESOURCE_DIRS) $($(THEOS_CURRENT_INSTANCE)_BUNDLE_RESOURCE_FILES)),) 19 | _LOCAL_BUNDLE_INSTALL_PATH = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_INSTALL_PATH),/Library/Application Support/$(THEOS_CURRENT_INSTANCE)) 20 | _LOCAL_BUNDLE_NAME = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_NAME),$(THEOS_CURRENT_INSTANCE)) 21 | _LOCAL_BUNDLE_EXTENSION = $(or $($(THEOS_CURRENT_INSTANCE)_BUNDLE_EXTENSION),bundle) 22 | 23 | _THEOS_SHARED_BUNDLE_BUILD_PATH = $(THEOS_OBJ_DIR)/$(_LOCAL_BUNDLE_NAME).$(_LOCAL_BUNDLE_EXTENSION) 24 | _THEOS_SHARED_BUNDLE_STAGE_PATH = $(THEOS_STAGING_DIR)$(_LOCAL_BUNDLE_INSTALL_PATH)/$(_LOCAL_BUNDLE_NAME).$(_LOCAL_BUNDLE_EXTENSION) 25 | include $(THEOS_MAKE_PATH)/instance/shared/bundle.mk 26 | 27 | internal-tweak-all_:: shared-instance-bundle-all 28 | internal-tweak-stage_:: shared-instance-bundle-stage 29 | endif 30 | 31 | ifneq ($($(THEOS_CURRENT_INSTANCE)_INSTALL),0) 32 | internal-tweak-stage_:: $(_EXTRA_TARGET) internal-library-stage_ 33 | $(ECHO_NOTHING)if [ -f $(THEOS_CURRENT_INSTANCE).plist ]; then cp $(THEOS_CURRENT_INSTANCE).plist "$(THEOS_STAGING_DIR)$(LOCAL_INSTALL_PATH)/"; fi$(ECHO_END) 34 | endif 35 | 36 | $(eval $(call __mod,instance/tweak.mk)) 37 | -------------------------------------------------------------------------------- /makefiles/legacy.mk: -------------------------------------------------------------------------------- 1 | FRAMEWORKDIR = $(THEOS) 2 | FW_BINDIR = $(THEOS_BIN_PATH) 3 | FW_MAKEDIR = $(THEOS_MAKE_PATH) 4 | FW_INCDIR = $(THEOS_INCLUDE_PATH) 5 | FW_LIBDIR = $(THEOS_LIBRARY_PATH) 6 | FW_MODDIR = $(THEOS_MODULE_PATH) 7 | 8 | FW_PROJECT_DIR = $(THEOS_PROJECT_DIR) 9 | 10 | export FRAMEWORKDIR FW_BINDIR FW_MAKEDIR FW_INCDIR FW_LIBDIR FW_MODDIR 11 | export FW_PROJECT_DIR 12 | 13 | FW_PLATFORM_NAME = $(THEOS_PLATFORM_NAME) 14 | FW_TARGET_NAME = $(THEOS_TARGET_NAME) 15 | 16 | FW_STAGING_DIR = $(THEOS_STAGING_DIR) 17 | 18 | ifneq ($(FW_BUILD_DIR),) 19 | THEOS_BUILD_DIR ?= $(FW_BUILD_DIR) 20 | else 21 | FW_BUILD_DIR = $(THEOS_BUILD_DIR) 22 | endif 23 | 24 | ifneq ($(FW_OBJ_DIR_NAME),) 25 | THEOS_OBJ_DIR_NAME ?= $(FW_OBJ_DIR_NAME) 26 | endif 27 | 28 | FW_OBJ_DIR = $(THEOS_OBJ_DIR) 29 | 30 | ifneq ($(FW_SUBPROJECT_PRODUCT),) 31 | THEOS_SUBPROJECT_PRODUCT ?= $(FW_SUBPROJECT_PRODUCT) 32 | else 33 | FW_SUBPROJECT_PRODUCT = $(THEOS_SUBPROJECT_PRODUCT) 34 | endif 35 | 36 | FW_INSTANCE = $(THEOS_CURRENT_INSTANCE) 37 | 38 | FW_SHARED_BUNDLE_RESOURCE_PATH = $(THEOS_SHARED_BUNDLE_RESOURCE_PATH) 39 | FW_PACKAGE_NAME = $(THEOS_PACKAGE_NAME) 40 | FW_PACKAGE_ARCH = $(THEOS_PACKAGE_ARCH) 41 | FW_PACKAGE_VERSION = $(THEOS_PACKAGE_BASE_VERSION) 42 | FW_PACKAGE_DEBVERSION = $(THEOS_PACKAGE_VERSION) 43 | FW_PACKAGE_FILENAME = $(THEOS_PACKAGE_FILENAME) 44 | 45 | ifdef FW_DEVICE_TUNNEL 46 | FW_DEVICE_PORT = 2222 47 | FW_DEVICE_IP = 127.0.0.1 48 | endif 49 | 50 | ifneq ($(FW_DEVICE_IP),) 51 | THEOS_DEVICE_IP ?= $(FW_DEVICE_IP) 52 | endif 53 | 54 | ifneq ($(FW_DEVICE_PORT),) 55 | THEOS_DEVICE_PORT ?= $(FW_DEVICE_PORT) 56 | endif 57 | 58 | ifneq ($(FW_DEVICE_USER),) 59 | THEOS_DEVICE_USER ?= $(FW_DEVICE_USER) 60 | endif 61 | -------------------------------------------------------------------------------- /makefiles/library.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/library.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),library) 5 | include $(THEOS_MAKE_PATH)/instance/library.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/master/aggregate.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | include $(THEOS_MAKE_PATH)/rules.mk 3 | endif 4 | 5 | SUBPROJECTS := $(strip $(call __schema_var_all,,SUBPROJECTS)) 6 | ifneq ($(SUBPROJECTS),) 7 | internal-all internal-clean:: _OPERATION = $(subst internal-,,$@) 8 | internal-stage internal-after-install:: _OPERATION = $@ 9 | internal-all internal-clean internal-stage internal-after-install:: _OPERATION_NAME = $(subst internal-,,$@) 10 | 11 | internal-all internal-clean internal-stage internal-after-install:: 12 | @abs_build_dir=$(_THEOS_ABSOLUTE_BUILD_DIR); \ 13 | for d in $(SUBPROJECTS); do \ 14 | echo "Making $(_OPERATION_NAME) in $$d..."; \ 15 | if [ "$${abs_build_dir}" = "." ]; then \ 16 | lbuilddir="."; \ 17 | else \ 18 | lbuilddir="$${abs_build_dir}/$$d"; \ 19 | fi; \ 20 | if $(MAKE) -C $$d -f $(_THEOS_PROJECT_MAKEFILE_NAME) $(_THEOS_NO_PRINT_DIRECTORY_FLAG) --no-keep-going $(_OPERATION) \ 21 | THEOS_BUILD_DIR="$$lbuilddir" \ 22 | ; then\ 23 | :; \ 24 | else exit $$?; \ 25 | fi; \ 26 | done; 27 | endif 28 | 29 | $(eval $(call __mod,master/aggregate.mk)) 30 | -------------------------------------------------------------------------------- /makefiles/master/application.mk: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME := $(strip $(APPLICATION_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(APPLICATION_NAME:=.all.application.variables); 8 | 9 | internal-stage:: $(APPLICATION_NAME:=.stage.application.variables); 10 | 11 | # Maybe, disabled for further discussion 12 | # install.exec "uicache" 13 | internal-after-install:: 14 | 15 | APPLICATIONS_WITH_SUBPROJECTS = $(strip $(foreach application,$(APPLICATION_NAME),$(patsubst %,$(application),$(call __schema_var_all,$(application)_,SUBPROJECTS)))) 16 | ifneq ($(APPLICATIONS_WITH_SUBPROJECTS),) 17 | internal-clean:: $(APPLICATIONS_WITH_SUBPROJECTS:=.clean.application.subprojects) 18 | endif 19 | 20 | $(APPLICATION_NAME): 21 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.application.variables 22 | 23 | $(eval $(call __mod,master/application.mk)) 24 | -------------------------------------------------------------------------------- /makefiles/master/bundle.mk: -------------------------------------------------------------------------------- 1 | BUNDLE_NAME := $(strip $(BUNDLE_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(BUNDLE_NAME:=.all.bundle.variables); 8 | 9 | internal-stage:: $(BUNDLE_NAME:=.stage.bundle.variables); 10 | 11 | BUNDLES_WITH_SUBPROJECTS = $(strip $(foreach bundle,$(BUNDLE_NAME),$(patsubst %,$(bundle),$(call __schema_var_all,$(bundle)_,SUBPROJECTS)))) 12 | ifneq ($(BUNDLES_WITH_SUBPROJECTS),) 13 | internal-clean:: $(BUNDLES_WITH_SUBPROJECTS:=.clean.bundle.subprojects) 14 | endif 15 | 16 | $(BUNDLE_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.bundle.variables 18 | 19 | $(eval $(call __mod,master/bundle.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/framework.mk: -------------------------------------------------------------------------------- 1 | FRAMEWORK_NAME := $(strip $(FRAMEWORK_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(FRAMEWORK_NAME:=.all.framework.variables); 8 | 9 | internal-stage:: $(FRAMEWORK_NAME:=.stage.framework.variables); 10 | 11 | FRAMEWORKS_WITH_SUBPROJECTS = $(strip $(foreach framework,$(FRAMEWORK_NAME),$(patsubst %,$(framework),$(call __schema_var_all,$(framework)_,SUBPROJECTS)))) 12 | ifneq ($(FRAMEWORKS_WITH_SUBPROJECTS),) 13 | internal-clean:: $(FRAMEWORKS_WITH_SUBPROJECTS:=.clean.framework.subprojects) 14 | endif 15 | 16 | $(FRAMEWORK_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.framework.variables 18 | 19 | $(eval $(call __mod,master/framework.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/library.mk: -------------------------------------------------------------------------------- 1 | LIBRARY_NAME := $(strip $(LIBRARY_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(LIBRARY_NAME:=.all.library.variables); 8 | 9 | internal-stage:: $(LIBRARY_NAME:=.stage.library.variables); 10 | 11 | LIBRARYS_WITH_SUBPROJECTS = $(strip $(foreach library,$(LIBRARY_NAME),$(patsubst %,$(library),$(call __schema_var_all,$(library)_,SUBPROJECTS)))) 12 | ifneq ($(LIBRARYS_WITH_SUBPROJECTS),) 13 | internal-clean:: $(LIBRARYS_WITH_SUBPROJECTS:=.clean.library.subprojects) 14 | endif 15 | 16 | $(LIBRARY_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.library.variables 18 | 19 | $(eval $(call __mod,master/library.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/null.mk: -------------------------------------------------------------------------------- 1 | NULL_NAME := $(strip $(NULL_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(NULL_NAME:=.all.null.variables); 8 | 9 | internal-stage:: $(NULL_NAME:=.stage.null.variables); 10 | 11 | NULLS_WITH_SUBPROJECTS = $(strip $(foreach null,$(NULL_NAME),$(patsubst %,$(null),$(call __schema_var_all,$(null)_,SUBPROJECTS)))) 12 | ifneq ($(NULLS_WITH_SUBPROJECTS),) 13 | internal-clean:: $(NULLS_WITH_SUBPROJECTS:=.clean.null.subprojects) 14 | endif 15 | 16 | $(NULL_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.null.variables 18 | 19 | $(eval $(call __mod,master/null.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/rules.mk: -------------------------------------------------------------------------------- 1 | __THEOS_RULES_MK_VERSION := 1r 2 | ifneq ($(__THEOS_RULES_MK_VERSION),$(__THEOS_COMMON_MK_VERSION)) 3 | all:: 4 | @echo Theos version mismatch! common.mk [version $(or $(__THEOS_COMMON_MK_VERSION),0)] loaded in tandem with rules.mk [version $(or $(__THEOS_RULES_MK_VERSION),0)] Check that \$$\(THEOS\) is set properly! 5 | @exit 1 6 | endif 7 | 8 | .PHONY: all before-all internal-all after-all \ 9 | clean before-clean internal-clean after-clean update-theos 10 | ifeq ($(THEOS_BUILD_DIR),.) 11 | all:: before-all internal-all after-all 12 | else 13 | all:: $(THEOS_BUILD_DIR) before-all internal-all after-all 14 | endif 15 | 16 | clean:: before-clean internal-clean after-clean 17 | 18 | do:: package install 19 | respring 20 | 21 | before-all:: 22 | ifneq ($(SYSROOT),) 23 | @[ -d "$(SYSROOT)" ] || { echo "Your current SYSROOT, \"$(SYSROOT)\", appears to be missing."; exit 1; } 24 | endif 25 | 26 | internal-all:: 27 | 28 | after-all:: 29 | 30 | before-clean:: 31 | 32 | internal-clean:: 33 | ifeq ($(MAKELEVEL),0) 34 | $(ECHO_CLEANING)rm -rf $(THEOS_OBJ_DIR)$(ECHO_END) 35 | $(ECHO_NOTHING)rm -rf "$(THEOS_STAGING_DIR)"$(ECHO_END) 36 | $(ECHO_NOTHING)rm -rf $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)_*-*_$(THEOS_PACKAGE_ARCH).deb$(ECHO_END) 37 | $(ECHO_NOTHING)rm -rf $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)-*-*.$(THEOS_PACKAGE_ARCH).rpm$(ECHO_END) 38 | else 39 | $(ECHO_NOTHING)rm -rf $(THEOS_OBJ_DIR)$(ECHO_END) 40 | endif 41 | 42 | after-clean:: 43 | 44 | ifeq ($(MAKELEVEL),0) 45 | ifneq ($(THEOS_BUILD_DIR),.) 46 | _THEOS_ABSOLUTE_BUILD_DIR = $(call __clean_pwd,$(THEOS_BUILD_DIR)) 47 | else 48 | _THEOS_ABSOLUTE_BUILD_DIR = . 49 | endif 50 | else 51 | _THEOS_ABSOLUTE_BUILD_DIR = $(strip $(THEOS_BUILD_DIR)) 52 | endif 53 | 54 | .PRECIOUS: %.variables %.subprojects 55 | 56 | %.variables: _INSTANCE = $(basename $(basename $*)) 57 | %.variables: _OPERATION = $(subst .,,$(suffix $(basename $*))) 58 | %.variables: _TYPE = $(subst -,_,$(subst .,,$(suffix $*))) 59 | %.variables: __SUBPROJECTS = $(strip $(call __schema_var_all,$(_INSTANCE)_,SUBPROJECTS)) 60 | %.variables: 61 | @ \ 62 | abs_build_dir=$(_THEOS_ABSOLUTE_BUILD_DIR); \ 63 | if [ "$(__SUBPROJECTS)" != "" ]; then \ 64 | echo Making $(_OPERATION) in subprojects of $(_TYPE) $(_INSTANCE)...; \ 65 | for d in $(__SUBPROJECTS); do \ 66 | d="$${d%:*}"; \ 67 | if [ "$${abs_build_dir}" = "." ]; then \ 68 | lbuilddir="."; \ 69 | else \ 70 | lbuilddir="$${abs_build_dir}/$$d"; \ 71 | fi; \ 72 | if $(MAKE) -C $$d -f $(_THEOS_PROJECT_MAKEFILE_NAME) $(_THEOS_NO_PRINT_DIRECTORY_FLAG) --no-keep-going $(_OPERATION) \ 73 | THEOS_BUILD_DIR="$$lbuilddir" \ 74 | ; then\ 75 | :; \ 76 | else exit $$?; \ 77 | fi; \ 78 | done; \ 79 | fi; \ 80 | echo Making $(_OPERATION) for $(_TYPE) $(_INSTANCE)...; \ 81 | $(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going \ 82 | internal-$(_TYPE)-$(_OPERATION) \ 83 | _THEOS_CURRENT_TYPE="$(_TYPE)" \ 84 | THEOS_CURRENT_INSTANCE="$(_INSTANCE)" \ 85 | _THEOS_CURRENT_OPERATION="$(_OPERATION)" \ 86 | THEOS_BUILD_DIR="$(_THEOS_ABSOLUTE_BUILD_DIR)" 87 | 88 | %.subprojects: _INSTANCE = $(basename $(basename $*)) 89 | %.subprojects: _OPERATION = $(subst .,,$(suffix $(basename $*))) 90 | %.subprojects: _TYPE = $(subst -,_,$(subst .,,$(suffix $*))) 91 | %.subprojects: __SUBPROJECTS = $(strip $(call __schema_var_all,$(_INSTANCE)_,SUBPROJECTS)) 92 | %.subprojects: 93 | @ \ 94 | abs_build_dir=$(_THEOS_ABSOLUTE_BUILD_DIR); \ 95 | if [ "$(__SUBPROJECTS)" != "" ]; then \ 96 | echo Making $(_OPERATION) in subprojects of $(_TYPE) $(_INSTANCE)...; \ 97 | for d in $(__SUBPROJECTS); do \ 98 | d="$${d%:*}"; \ 99 | if [ "$${abs_build_dir}" = "." ]; then \ 100 | lbuilddir="."; \ 101 | else \ 102 | lbuilddir="$${abs_build_dir}/$$d"; \ 103 | fi; \ 104 | if $(MAKE) -C $$d -f $(_THEOS_PROJECT_MAKEFILE_NAME) $(_THEOS_NO_PRINT_DIRECTORY_FLAG) --no-keep-going $(_OPERATION) \ 105 | THEOS_BUILD_DIR="$$lbuilddir" \ 106 | ; then\ 107 | :; \ 108 | else exit $$?; \ 109 | fi; \ 110 | done; \ 111 | fi 112 | 113 | update-theos:: 114 | @cd $(THEOS) && git pull origin master && ./git-submodule-recur.sh init 115 | 116 | $(eval $(call __mod,master/rules.mk)) 117 | 118 | ifeq ($(_THEOS_TOP_INVOCATION_DONE),) 119 | export _THEOS_TOP_INVOCATION_DONE = 1 120 | endif 121 | -------------------------------------------------------------------------------- /makefiles/master/subproject.mk: -------------------------------------------------------------------------------- 1 | SUBPROJECT_NAME := $(strip $(SUBPROJECT_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(SUBPROJECT_NAME:=.all.subproject.variables); 8 | 9 | internal-stage:: $(SUBPROJECT_NAME:=.stage.subproject.variables); 10 | 11 | SUBPROJECTS_WITH_SUBPROJECTS = $(strip $(foreach subproject,$(SUBPROJECT_NAME),$(patsubst %,$(subproject),$(call __schema_var_all,$(subproject)_,SUBPROJECTS)))) 12 | ifneq ($(SUBPROJECTS_WITH_SUBPROJECTS),) 13 | internal-clean:: $(SUBPROJECTS_WITH_SUBPROJECTS:=.clean.subproject.subprojects) 14 | endif 15 | 16 | $(SUBPROJECT_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.subproject.variables 18 | 19 | $(eval $(call __mod,master/subproject.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/tool.mk: -------------------------------------------------------------------------------- 1 | TOOL_NAME := $(strip $(TOOL_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | internal-all:: $(TOOL_NAME:=.all.tool.variables); 8 | 9 | internal-stage:: $(TOOL_NAME:=.stage.tool.variables); 10 | 11 | TOOLS_WITH_SUBPROJECTS = $(strip $(foreach tool,$(TOOL_NAME),$(patsubst %,$(tool),$(call __schema_var_all,$(tool)_,SUBPROJECTS)))) 12 | ifneq ($(TOOLS_WITH_SUBPROJECTS),) 13 | internal-clean:: $(TOOLS_WITH_SUBPROJECTS:=.clean.tool.subprojects) 14 | endif 15 | 16 | $(TOOL_NAME): 17 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.tool.variables 18 | 19 | $(eval $(call __mod,master/tool.mk)) 20 | -------------------------------------------------------------------------------- /makefiles/master/tweak.mk: -------------------------------------------------------------------------------- 1 | TWEAK_NAME := $(strip $(TWEAK_NAME)) 2 | 3 | ifeq ($(_THEOS_RULES_LOADED),) 4 | include $(THEOS_MAKE_PATH)/rules.mk 5 | endif 6 | 7 | before-all:: 8 | @[ -f "$(THEOS_LIBRARY_PATH)/libsubstrate.dylib" ] || bootstrap.sh substrate 9 | 10 | internal-all:: $(TWEAK_NAME:=.all.tweak.variables); 11 | 12 | internal-stage:: $(TWEAK_NAME:=.stage.tweak.variables); 13 | 14 | ifneq ($(TWEAK_TARGET_PROCESS),) 15 | INSTALL_TARGET_PROCESSES += $(TWEAK_TARGET_PROCESS) 16 | endif 17 | 18 | TWEAKS_WITH_SUBPROJECTS = $(strip $(foreach tweak,$(TWEAK_NAME),$(patsubst %,$(tweak),$(call __schema_var_all,$(tweak)_,SUBPROJECTS)))) 19 | ifneq ($(TWEAKS_WITH_SUBPROJECTS),) 20 | internal-clean:: $(TWEAKS_WITH_SUBPROJECTS:=.clean.tweak.subprojects) 21 | endif 22 | 23 | $(TWEAK_NAME): 24 | @$(MAKE) -f $(_THEOS_PROJECT_MAKEFILE_NAME) --no-print-directory --no-keep-going $@.all.tweak.variables 25 | 26 | $(eval $(call __mod,master/tweak.mk)) 27 | -------------------------------------------------------------------------------- /makefiles/messages.mk: -------------------------------------------------------------------------------- 1 | NULLSTRING := 2 | ECHO_PIPEFAIL := set -o pipefail; 3 | 4 | ifneq ($(call __theos_bool,$(or $(messages),$(MESSAGES))),$(_THEOS_TRUE)) 5 | ifeq ($(call __executable,unbuffer),$(_THEOS_TRUE)) 6 | ECHO_UNBUFFERED = unbuffer $(NULLSTRING) 7 | ECHO_END = ) 2>&1 | sed "s/^/ /" ) 8 | else 9 | ECHO_UNBUFFERED = 10 | ECHO_END = ) ) 11 | endif 12 | 13 | ifneq ($(THEOS_CURRENT_ARCH),) 14 | ECHO_COMPILING = @(echo "Compiling $< ($(THEOS_CURRENT_ARCH))..."; $(ECHO_PIPEFAIL) ( 15 | ECHO_LINKING = @(echo "Linking $(_THEOS_CURRENT_TYPE) $(THEOS_CURRENT_INSTANCE) ($(THEOS_CURRENT_ARCH))..."; $(ECHO_PIPEFAIL) ( 16 | ECHO_LINKING_WITH_STRIP = @(echo "Linking $(_THEOS_CURRENT_TYPE) $(THEOS_CURRENT_INSTANCE) (with strip, $(THEOS_CURRENT_ARCH))..."; $(ECHO_PIPEFAIL) ( 17 | ECHO_STRIPPING = @(echo "Stripping $(THEOS_CURRENT_INSTANCE) ($(THEOS_CURRENT_ARCH))..."; $(ECHO_PIPEFAIL) ( 18 | else 19 | ECHO_COMPILING = @(echo "Compiling $<..."; $(ECHO_PIPEFAIL) ( 20 | ECHO_LINKING = @(echo "Linking $(_THEOS_CURRENT_TYPE) $(THEOS_CURRENT_INSTANCE)..."; $(ECHO_PIPEFAIL) ( 21 | ECHO_LINKING_WITH_STRIP = @(echo "Linking $(_THEOS_CURRENT_TYPE) $(THEOS_CURRENT_INSTANCE) (with strip)..."; $(ECHO_PIPEFAIL) ( 22 | ECHO_STRIPPING = @(echo "Stripping $(THEOS_CURRENT_INSTANCE)..."; $(ECHO_PIPEFAIL) ( 23 | endif 24 | ECHO_MERGING = @(echo "Merging $(_THEOS_CURRENT_TYPE) $(THEOS_CURRENT_INSTANCE)..."; $(ECHO_PIPEFAIL) ( 25 | ECHO_SIGNING = @(echo "Signing $(THEOS_CURRENT_INSTANCE)...";$(ECHO_PIPEFAIL)( 26 | ECHO_PREPROCESSING = @(echo "Preprocessing $<...";$(ECHO_PIPEFAIL)( 27 | ECHO_COPYING_RESOURCE_FILES = @(echo "Copying resource files into the $(_THEOS_CURRENT_TYPE) wrapper...";$(ECHO_PIPEFAIL) ( 28 | ECHO_COPYING_RESOURCE_DIRS = @(echo "Copying resource directories into the $(_THEOS_CURRENT_TYPE) wrapper..."; $(ECHO_PIPEFAIL) ( 29 | ECHO_PRE_UNLOADING = @(echo "Unloading $(PREINSTALL_TARGET_PROCESSES)..."; $(ECHO_PIPEFAIL) ( 30 | ECHO_INSTALLING = @(echo "Installing..."; $(ECHO_PIPEFAIL) ( 31 | ECHO_UNLOADING = @(echo "Unloading $(INSTALL_TARGET_PROCESSES)..."; $(ECHO_PIPEFAIL) ( 32 | ECHO_CLEANING = @(echo "Cleaning..."; $(ECHO_PIPEFAIL) ( 33 | ECHO_NOTHING = @($(ECHO_PIPEFAIL) ( 34 | 35 | STDERR_NULL_REDIRECT = 2> /dev/null 36 | STDOUT_NULL_REDIRECT = > /dev/null 37 | 38 | _THEOS_VERBOSE := $(_THEOS_FALSE) 39 | else 40 | ECHO_END = 41 | 42 | ECHO_COMPILING = 43 | ECHO_LINKING = 44 | ECHO_LINKING_WITH_STRIP = 45 | ECHO_STRIPPING = 46 | ECHO_MERGING = 47 | ECHO_SIGNING = 48 | ECHO_PREPROCESSING = 49 | ECHO_COPYING_RESOURCE_FILES = 50 | ECHO_COPYING_RESOURCE_DIRS = 51 | ECHO_INSTALLING = 52 | ECHO_UNLOADING = 53 | ECHO_CLEANING = 54 | ECHO_NOTHING = 55 | 56 | STDERR_NULL_REDIRECT = 57 | STDOUT_NULL_REDIRECT = 58 | 59 | _THEOS_VERBOSE := $(_THEOS_TRUE) 60 | endif 61 | 62 | WARNING_EMPTY_LINKING = @@(echo " Warning! No files to link. Please check your Makefile! Make sure you set $(THEOS_CURRENT_INSTANCE)_FILES (or similar variables)") 63 | 64 | # (bundle) 65 | NOTICE_EMPTY_LINKING = @@(echo " Notice: No files to link - creating a bundle containing only resources") 66 | 67 | $(eval $(call __mod,messages.mk)) 68 | -------------------------------------------------------------------------------- /makefiles/null.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/null.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),null) 5 | include $(THEOS_MAKE_PATH)/instance/null.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/package.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PACKAGE_RULES_LOADED),) 2 | _THEOS_PACKAGE_RULES_LOADED := 1 3 | 4 | ## Packaging Core Rules 5 | .PHONY: package internal-package-check before-package internal-package after-package 6 | 7 | package:: internal-package-check stage before-package internal-package after-package 8 | before-package:: $(THEOS_PACKAGE_DIR) 9 | internal-package internal-package-check:: 10 | @: 11 | 12 | # __THEOS_LAST_PACKAGE_FILENAME is to be set by a rule variable in the package format makefile. 13 | after-package:: 14 | @echo "$(__THEOS_LAST_PACKAGE_FILENAME)" > "$(_THEOS_LOCAL_DATA_DIR)/last_package" 15 | 16 | THEOS_PACKAGE_NAME := 17 | THEOS_PACKAGE_ARCH := 18 | THEOS_PACKAGE_BASE_VERSION := 19 | # THEOS_PACKAGE_VERSION is set in common.mk (to give its warning.) 20 | 21 | -include $(THEOS_MAKE_PATH)/package/$(_THEOS_PACKAGE_FORMAT).mk 22 | $(eval $(call __mod,package/$(_THEOS_PACKAGE_FORMAT).mk)) 23 | 24 | ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),) 25 | $(error I simply cannot figure out how to create $(_THEOS_PACKAGE_FORMAT)-format packages.) 26 | endif 27 | 28 | export THEOS_PACKAGE_NAME THEOS_PACKAGE_ARCH THEOS_PACKAGE_BASE_VERSION 29 | 30 | # These are here to be used by the package makefile included above. 31 | # We want them after the package makefile so that we can use variables set within it. 32 | 33 | # eval PACKAGE_VERSION *now* (to clear out references to VERSION.*: they have no bearing on 34 | # the 'base' version we calculate.) 35 | VERSION.INC_BUILD_NUMBER := X 36 | VERSION.EXTRAVERSION := X 37 | __USERVER_FOR_BUILDNUM := $(PACKAGE_VERSION) 38 | __BASEVER_FOR_BUILDNUM = $(or $(__USERVER_FOR_BUILDNUM),$(THEOS_PACKAGE_BASE_VERSION)) 39 | 40 | 41 | # We simplify the version vars so that they are evaluated only when completely necessary. 42 | # This is because they can include things like incrementing build numbers. 43 | 44 | # I am committing a willful departure from the THEOS_ naming convention, because I believe 45 | # that offering these via an easy-to-use interface makes more sense than hiding them behind 46 | # a really stupidly long name. 47 | # VERSION.* are meant to be used in user PACKAGE_VERSIONs. 48 | VERSION.INC_BUILD_NUMBER = $(shell THEOS_PROJECT_DIR="$(THEOS_PROJECT_DIR)" "$(THEOS_BIN_PATH)/package_version.sh" -N "$(THEOS_PACKAGE_NAME)" -V "$(__BASEVER_FOR_BUILDNUM)") 49 | VERSION.EXTRAVERSION = $(if $(PACKAGE_BUILDNAME),$(_THEOS_PACKAGE_EXTRA_VERSION_PREFIX)$(PACKAGE_BUILDNAME)) 50 | ifeq ($(FINALPACKAGE),1) 51 | _THEOS_PACKAGE_DEFAULT_VERSION_FORMAT = $(THEOS_PACKAGE_BASE_VERSION)$(VERSION.EXTRAVERSION) 52 | else 53 | _THEOS_PACKAGE_DEFAULT_VERSION_FORMAT = $(THEOS_PACKAGE_BASE_VERSION)$(_THEOS_PACKAGE_INC_VERSION_PREFIX)$(VERSION.INC_BUILD_NUMBER)$(VERSION.EXTRAVERSION) 54 | endif 55 | 56 | # Copy the actual value of PACKAGE_VERSION to __PACKAGE_VERSION and replace PACKAGE_VERSION with 57 | # a mere reference (to a simplified copy.) 58 | # We're doing this to clean up the user's PACKAGE_VERSION and make it safe for reuse. 59 | # (otherwise, they might trigger build number increases without meaning to.) 60 | # Defer the simplification until __PACKAGE_VERSION is used - do not do it before the eval 61 | # However, we want to do the schema calculation and value stuff before the eval, so that 62 | # __PACKAGE_VERSION becomes an exact copy of the PACKAGE_VERSION variable we chose. 63 | $(eval __PACKAGE_VERSION = $$(call __simplify,__PACKAGE_VERSION,$(value $(call __schema_var_name_last,,PACKAGE_VERSION)))) 64 | override PACKAGE_VERSION = $(__PACKAGE_VERSION) 65 | 66 | _THEOS_INTERNAL_PACKAGE_VERSION = $(call __simplify,_THEOS_INTERNAL_PACKAGE_VERSION,$(or $(__PACKAGE_VERSION),$(_THEOS_PACKAGE_DEFAULT_VERSION_FORMAT),1)) 67 | 68 | ## Installation Core Rules 69 | install:: before-install internal-install after-install 70 | 71 | export TARGET_INSTALL_REMOTE 72 | _THEOS_INSTALL_TYPE := local 73 | ifeq ($(TARGET_INSTALL_REMOTE),$(_THEOS_TRUE)) 74 | _THEOS_INSTALL_TYPE := remote 75 | ifeq ($(THEOS_DEVICE_IP),) 76 | internal-install:: 77 | $(info $(MAKE) install requires that you set THEOS_DEVICE_IP in your environment. It is also recommended that you have public-key authentication set up for root over SSH, or you will be entering your password a lot.) 78 | @exit 1 79 | endif # THEOS_DEVICE_IP == "" 80 | THEOS_DEVICE_PORT ?= 22 81 | THEOS_DEVICE_USER ?= root 82 | export THEOS_DEVICE_IP THEOS_DEVICE_PORT THEOS_DEVICE_USER 83 | endif # TARGET_INSTALL_REMOTE == true 84 | 85 | after-install:: internal-after-install 86 | INSTALL_TARGET_PROCESSES ?= 87 | before-install:: 88 | ifneq ($(PREINSTALL_TARGET_PROCESSES),) 89 | $(ECHO_PRE_UNLOADING)install.exec "killall -9 $(PREINSTALL_TARGET_PROCESSES) || true" $(STDERR_NULL_REDIRECT)$(ECHO_END) 90 | else 91 | @: 92 | endif 93 | 94 | internal-install:: 95 | @: 96 | 97 | INSTALL_TARGET_PROCESSES ?= 98 | internal-after-install:: 99 | ifneq ($(INSTALL_TARGET_PROCESSES),) 100 | $(ECHO_UNLOADING)install.exec "killall -9 $(INSTALL_TARGET_PROCESSES) || true" $(STDERR_NULL_REDIRECT)$(ECHO_END) 101 | else 102 | @: 103 | endif 104 | 105 | ## Uninstallation Core Rules 106 | uninstall:: before-uninstall internal-uninstall after-uninstall 107 | 108 | after-uninstall:: internal-after-uninstall 109 | before-uninstall:: 110 | 111 | internal-uninstall:: 112 | @: 113 | 114 | internal-after-uninstall:: 115 | 116 | -include $(THEOS_MAKE_PATH)/install/$(_THEOS_PACKAGE_FORMAT)_$(_THEOS_INSTALL_TYPE).mk 117 | $(eval $(call __mod,install/$(_THEOS_PACKAGE_FORMAT)_$(_THEOS_INSTALL_TYPE).mk)) 118 | 119 | endif # _THEOS_PACKAGE_RULES_LOADED 120 | -------------------------------------------------------------------------------- /makefiles/package/deb.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),) 2 | _THEOS_PACKAGE_FORMAT_LOADED := 1 3 | 4 | _THEOS_DEB_PACKAGE_CONTROL_PATH := $(or $(wildcard $(THEOS_PROJECT_DIR)/control),$(wildcard $(THEOS_PROJECT_DIR)/layout/DEBIAN/control)) 5 | _THEOS_DEB_CAN_PACKAGE := $(if $(_THEOS_DEB_PACKAGE_CONTROL_PATH),$(_THEOS_TRUE),$(_THEOS_FALSE)) 6 | _THEOS_PACKAGE_INC_VERSION_PREFIX := - 7 | _THEOS_PACKAGE_EXTRA_VERSION_PREFIX := + 8 | 9 | _THEOS_DEB_HAS_DPKG_DEB := $(call __executable,dpkg-deb) 10 | ifneq ($(_THEOS_DEB_HAS_DPKG_DEB),$(_THEOS_TRUE)) 11 | internal-package-check:: 12 | @echo "$(MAKE) package requires dpkg-deb."; exit 1 13 | endif 14 | 15 | ifeq ($(_THEOS_DEB_CAN_PACKAGE),$(_THEOS_TRUE)) # Control file found (or layout/ found.) 16 | THEOS_PACKAGE_NAME := $(shell grep -i "^Package:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) 17 | THEOS_PACKAGE_ARCH := $(shell grep -i "^Architecture:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) 18 | THEOS_PACKAGE_BASE_VERSION := $(shell grep -i "^Version:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) 19 | 20 | $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN: 21 | $(ECHO_NOTHING)mkdir -p "$(THEOS_STAGING_DIR)/DEBIAN"$(ECHO_END) 22 | ifeq ($(_THEOS_HAS_STAGING_LAYOUT),1) # If we have a layout/ directory, copy layout/DEBIAN to the staging directory. 23 | $(ECHO_NOTHING)[ -d "$(THEOS_PROJECT_DIR)/layout/DEBIAN" ] && rsync -a "$(THEOS_PROJECT_DIR)/layout/DEBIAN/" "$(THEOS_STAGING_DIR)/DEBIAN" $(_THEOS_RSYNC_EXCLUDE_COMMANDLINE) || true$(ECHO_END) 24 | endif # _THEOS_HAS_STAGING_LAYOUT 25 | 26 | $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN/control: $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN 27 | $(ECHO_NOTHING)sed -e '/^[Vv]ersion:/d' "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" > "$@"$(ECHO_END) 28 | $(ECHO_NOTHING)echo "Version: $(_THEOS_INTERNAL_PACKAGE_VERSION)" >> "$@"$(ECHO_END) 29 | $(ECHO_NOTHING)echo "Installed-Size: $(shell du $(_THEOS_PLATFORM_DU_EXCLUDE) DEBIAN -ks "$(THEOS_STAGING_DIR)" | cut -f 1)" >> "$@"$(ECHO_END) 30 | 31 | before-package:: $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN/control 32 | 33 | _THEOS_DEB_PACKAGE_FILENAME = $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)_$(_THEOS_INTERNAL_PACKAGE_VERSION)_$(THEOS_PACKAGE_ARCH).deb 34 | internal-package:: 35 | $(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r dpkg-deb -b "$(THEOS_STAGING_DIR)" "$(_THEOS_DEB_PACKAGE_FILENAME)" $(STDERR_NULL_REDIRECT)$(ECHO_END) 36 | 37 | # This variable is used in package.mk 38 | after-package:: __THEOS_LAST_PACKAGE_FILENAME = $(_THEOS_DEB_PACKAGE_FILENAME) 39 | 40 | else # _THEOS_DEB_CAN_PACKAGE == 0 41 | internal-package:: 42 | @echo "$(MAKE) package requires you to have a layout/ directory in the project root, containing the basic package structure, or a control file in the project root describing the package."; exit 1 43 | 44 | endif # _THEOS_DEB_CAN_PACKAGE 45 | endif # _THEOS_PACKAGE_FORMAT_LOADED 46 | -------------------------------------------------------------------------------- /makefiles/package/none.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),) 2 | _THEOS_PACKAGE_FORMAT_LOADED := 1 3 | 4 | # This package format does nothing - it simply relies upon the internal-package rule in package.mk to do nothing for it. 5 | endif # _THEOS_PACKAGE_FORMAT_LOADED 6 | -------------------------------------------------------------------------------- /makefiles/package/pkg.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),) 2 | _THEOS_PACKAGE_FORMAT_LOADED := 1 3 | 4 | _THEOS_PKG_PACKAGE_CONTROL_PATH := $(THEOS_PROJECT_DIR)/control 5 | _THEOS_PKG_CAN_PACKAGE := $(if $(_THEOS_PKG_PACKAGE_CONTROL_PATH),$(_THEOS_TRUE),$(_THEOS_FALSE)) 6 | _THEOS_PACKAGE_INC_VERSION_PREFIX := - 7 | _THEOS_PACKAGE_EXTRA_VERSION_PREFIX := + 8 | 9 | _THEOS_PKG_HAS_PKGBUILD := $(call __executable,pkgbuild) 10 | ifneq ($(_THEOS_PKG_HAS_PKGBUILD),$(_THEOS_TRUE)) 11 | internal-package-check:: 12 | @echo "$(MAKE) package requires pkgbuild."; exit 1 13 | endif 14 | 15 | ifeq ($(_THEOS_PKG_CAN_PACKAGE),$(_THEOS_TRUE)) # Control file found (or layout/ found.) 16 | THEOS_PACKAGE_NAME := $(shell grep -i "^Package:" "$(_THEOS_PKG_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) 17 | THEOS_PACKAGE_BASE_VERSION := $(shell grep -i "^Version:" "$(_THEOS_PKG_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) 18 | 19 | _THEOS_PKG_PACKAGE_FILENAME = $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)_$(_THEOS_INTERNAL_PACKAGE_VERSION).pkg 20 | internal-package:: 21 | $(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r pkgbuild --root "$(THEOS_STAGING_DIR)" --identifier "$(THEOS_PACKAGE_NAME)" --version "$(_THEOS_INTERNAL_PACKAGE_VERSION)" --ownership recommended "$(_THEOS_PKG_PACKAGE_FILENAME)" $(STDERR_NULL_REDIRECT)$(ECHO_END) 22 | 23 | # This variable is used in package.mk 24 | after-package:: __THEOS_LAST_PACKAGE_FILENAME = $(_THEOS_PKG_PACKAGE_FILENAME) 25 | 26 | else # _THEOS_PKG_CAN_PACKAGE == 0 27 | internal-package:: 28 | @echo "$(MAKE) package requires you to have a control file in the project root describing the package."; exit 1 29 | 30 | endif # _THEOS_PKG_CAN_PACKAGE 31 | endif # _THEOS_PACKAGE_FORMAT_LOADED 32 | -------------------------------------------------------------------------------- /makefiles/package/rpm.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),) 2 | _THEOS_PACKAGE_FORMAT_LOADED := 1 3 | 4 | _THEOS_RPM_PACKAGE_SPEC_PATH := $(wildcard $(THEOS_PROJECT_DIR)/package.spec) 5 | _THEOS_RPM_CAN_PACKAGE := $(if $(_THEOS_RPM_PACKAGE_SPEC_PATH),$(_THEOS_TRUE),$(_THEOS_FALSE)) 6 | _THEOS_PACKAGE_INC_VERSION_PREFIX := 7 | _THEOS_PACKAGE_EXTRA_VERSION_PREFIX := + 8 | 9 | _THEOS_RPM_HAS_RPMBUILD := $(call __executable,rpmbuild) 10 | ifneq ($(_THEOS_RPM_HAS_RPMBUILD),$(_THEOS_TRUE)) 11 | internal-package-check:: 12 | @echo "$(MAKE) package requires rpmbuild."; exit 1 13 | endif 14 | 15 | ifeq ($(_THEOS_RPM_CAN_PACKAGE),$(_THEOS_TRUE)) # Control file found (or layout/ found.) 16 | THEOS_PACKAGE_NAME := $(shell grep -i "^Name:" "$(_THEOS_RPM_PACKAGE_SPEC_PATH)" | cut -d':' -f2- | xargs) 17 | THEOS_PACKAGE_ARCH := $(shell grep -i "^BuildArch:" "$(_THEOS_RPM_PACKAGE_SPEC_PATH)" | cut -d':' -f2- | xargs) 18 | THEOS_PACKAGE_RPM_VERSION := $(shell grep -i "^Version:" "$(_THEOS_RPM_PACKAGE_SPEC_PATH)" | cut -d':' -f2- | xargs) 19 | ifeq ($(FINALPACKAGE),1) 20 | THEOS_PACKAGE_RELEASE_VERSION ?= $(shell grep -i "^Release:" "$(_THEOS_RPM_PACKAGE_SPEC_PATH)" | cut -d':' -f2- | xargs) 21 | else 22 | THEOS_PACKAGE_RELEASE_VERSION ?= 23 | endif 24 | THEOS_PACKAGE_BASE_VERSION := $(THEOS_PACKAGE_RELEASE_VERSION) 25 | 26 | before-package:: 27 | $(ECHO_NOTHING)sed -e 's/[Rr]elease:.*/Release: $(_THEOS_INTERNAL_PACKAGE_VERSION)/g' -e '/^[Ss]ource0:/d' "$(_THEOS_RPM_PACKAGE_SPEC_PATH)" > "$(THEOS_OBJ_DIR)/package.spec"$(ECHO_END) 28 | $(ECHO_NOTHING)echo '%files' >> "$(THEOS_OBJ_DIR)/package.spec"$(ECHO_END) 29 | $(ECHO_NOTHING)echo '/*' >> "$(THEOS_OBJ_DIR)/package.spec"$(ECHO_END) 30 | 31 | _THEOS_RPM_PACKAGE_FILENAME = $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)-$(THEOS_PACKAGE_RPM_VERSION)-$(_THEOS_INTERNAL_PACKAGE_VERSION).$(THEOS_PACKAGE_ARCH).rpm 32 | internal-package:: 33 | $(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r rpmbuild -bb "$(THEOS_OBJ_DIR)/package.spec" --buildroot "$(THEOS_STAGING_DIR)" --define "_rpmdir$(THEOS_OBJ_DIR)" $(STDERR_NULL_REDIRECT)$(STDOUT_NULL_REDIRECT)$(ECHO_END) 34 | $(ECHO_NOTHING)ln -f "$(THEOS_OBJ_DIR)/$(THEOS_PACKAGE_ARCH)/$(THEOS_PACKAGE_NAME)-$(THEOS_PACKAGE_RPM_VERSION)-$(_THEOS_INTERNAL_PACKAGE_VERSION).$(THEOS_PACKAGE_ARCH).rpm" "$(_THEOS_RPM_PACKAGE_FILENAME)"$(ECHO_END) 35 | $(ECHO_NOTHING)rm -r "$(THEOS_OBJ_DIR)/$(THEOS_PACKAGE_ARCH)"$(ECHO_END) 36 | 37 | # This variable is used in package.mk 38 | after-package:: __THEOS_LAST_PACKAGE_FILENAME = $(_THEOS_RPM_PACKAGE_FILENAME) 39 | 40 | else # _THEOS_RPM_CAN_PACKAGE == 0 41 | internal-package:: 42 | @echo "$(MAKE) package requires you to have a package.spec file in the project directory."; exit 1 43 | 44 | endif # _THEOS_RPM_CAN_PACKAGE 45 | endif # _THEOS_PACKAGE_FORMAT_LOADED 46 | -------------------------------------------------------------------------------- /makefiles/platform/Darwin-arm.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PLATFORM_LOADED),) 2 | _THEOS_PLATFORM_LOADED := 1 3 | THEOS_PLATFORM_NAME := iphone 4 | 5 | _THEOS_PLATFORM_DEFAULT_TARGET := iphone 6 | _THEOS_PLATFORM_DU_EXCLUDE := --exclude 7 | _THEOS_PLATFORM_MD5SUM := md5sum 8 | endif 9 | -------------------------------------------------------------------------------- /makefiles/platform/Darwin.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PLATFORM_LOADED),) 2 | _THEOS_PLATFORM_LOADED := 1 3 | THEOS_PLATFORM_NAME := macosx 4 | 5 | ifneq ($(THEOS_CURRENT_ARCH),) 6 | ifneq ($(THEOS_PLATFORM_SDK_ROOT_$(THEOS_CURRENT_ARCH)),) 7 | THEOS_PLATFORM_SDK_ROOT = $(THEOS_PLATFORM_SDK_ROOT_$(THEOS_CURRENT_ARCH)) 8 | endif 9 | endif 10 | THEOS_PLATFORM_SDK_ROOT ?= $(shell xcode-select -print-path) 11 | # To have xcrun use our customized THEOS_PLATFORM_SDK_ROOT 12 | export DEVELOPER_DIR = $(THEOS_PLATFORM_SDK_ROOT) 13 | 14 | _THEOS_PLATFORM_DEFAULT_TARGET := iphone 15 | _THEOS_PLATFORM_DU_EXCLUDE := -I 16 | _THEOS_PLATFORM_MD5SUM := md5 17 | _THEOS_PLATFORM_LIPO = xcrun lipo 18 | endif 19 | -------------------------------------------------------------------------------- /makefiles/platform/Linux.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_PLATFORM_LOADED),) 2 | _THEOS_PLATFORM_LOADED := 1 3 | THEOS_PLATFORM_NAME := linux 4 | 5 | _THEOS_PLATFORM_DEFAULT_TARGET := iphone 6 | _THEOS_PLATFORM_DU_EXCLUDE := --exclude 7 | _THEOS_PLATFORM_MD5SUM := md5sum 8 | endif 9 | -------------------------------------------------------------------------------- /makefiles/rules.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_RULES_LOADED),) 2 | _THEOS_RULES_LOADED := 1 3 | 4 | ifeq ($(THEOS_CURRENT_INSTANCE),) 5 | include $(THEOS_MAKE_PATH)/master/rules.mk 6 | else 7 | include $(THEOS_MAKE_PATH)/instance/rules.mk 8 | endif 9 | 10 | ifeq ($(_THEOS_MAKE_PARALLEL_BUILDING), no) 11 | .NOTPARALLEL: 12 | else 13 | ifneq ($(_THEOS_MAKE_PARALLEL), yes) 14 | .NOTPARALLEL: 15 | endif 16 | endif 17 | 18 | %.mm: %.l.mm 19 | $(THEOS_BIN_PATH)/logos.pl $< > $@ 20 | 21 | %.mm: %.xmm 22 | $(THEOS_BIN_PATH)/logos.pl $< > $@ 23 | 24 | %.mm: %.xm 25 | $(THEOS_BIN_PATH)/logos.pl $< > $@ 26 | 27 | %.m: %.xm 28 | $(THEOS_BIN_PATH)/logos.pl $< > $@ 29 | 30 | ifneq ($(THEOS_BUILD_DIR),.) 31 | $(THEOS_BUILD_DIR): 32 | @mkdir -p $(THEOS_BUILD_DIR) 33 | endif 34 | 35 | $(THEOS_OBJ_DIR): 36 | @cd $(THEOS_BUILD_DIR); mkdir -p $(THEOS_OBJ_DIR_NAME) 37 | 38 | $(THEOS_OBJ_DIR)/.stamp: $(THEOS_OBJ_DIR) 39 | @touch $@ 40 | 41 | $(THEOS_OBJ_DIR)/%/.stamp: $(THEOS_OBJ_DIR) 42 | @mkdir -p $(dir $@); touch $@ 43 | 44 | Makefile: ; 45 | $(_THEOS_RELATIVE_MAKE_PATH)%.mk: ; 46 | $(THEOS_MAKE_PATH)/%.mk: ; 47 | $(THEOS_MAKE_PATH)/master/%.mk: ; 48 | $(THEOS_MAKE_PATH)/instance/%.mk: ; 49 | $(THEOS_MAKE_PATH)/instance/shared/%.mk: ; 50 | $(THEOS_MAKE_PATH)/platform/%.mk: ; 51 | $(THEOS_MAKE_PATH)/targets/%.mk: ; 52 | $(THEOS_MAKE_PATH)/targets/%/%.mk: ; 53 | 54 | ifneq ($(THEOS_PACKAGE_DIR_NAME),) 55 | $(THEOS_PACKAGE_DIR): 56 | @cd $(THEOS_BUILD_DIR); mkdir -p $(THEOS_PACKAGE_DIR_NAME) 57 | endif 58 | 59 | endif 60 | 61 | # TODO MAKE A BUNCH OF THINGS PHONY 62 | $(eval $(call __mod,rules.mk)) 63 | -------------------------------------------------------------------------------- /makefiles/stage.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_STAGING_RULES_LOADED),) 2 | _THEOS_STAGING_RULES_LOADED := 1 3 | 4 | .PHONY: stage before-stage internal-stage after-stage 5 | 6 | # For the toplevel invocation of make, mark 'all' and the *-stage rules as prerequisites. 7 | # We do not do this for anything else, because otherwise, all the staging rules would run for every subproject. 8 | ifeq ($(_THEOS_TOP_INVOCATION_DONE),) 9 | stage:: all before-stage internal-stage after-stage 10 | else # _THEOS_TOP_INVOCATION_DONE 11 | stage:: internal-stage 12 | endif 13 | 14 | # Only do the master staging rules if we're the toplevel make invocation. 15 | ifeq ($(_THEOS_TOP_INVOCATION_DONE),) 16 | before-stage:: 17 | $(ECHO_NOTHING)rm -rf "$(THEOS_STAGING_DIR)"$(ECHO_END) 18 | $(ECHO_NOTHING)$(FAKEROOT) -c$(ECHO_END) 19 | $(ECHO_NOTHING)mkdir -p "$(THEOS_STAGING_DIR)"$(ECHO_END) 20 | else # _THEOS_TOP_INVOCATION_DONE 21 | before-stage:: 22 | @: 23 | endif # _THEOS_TOP_INVOCATION_DONE 24 | 25 | internal-stage:: 26 | $(ECHO_NOTHING)[ -d layout ] && rsync -a "layout/" "$(THEOS_STAGING_DIR)" --exclude "DEBIAN" $(_THEOS_RSYNC_EXCLUDE_COMMANDLINE) || true$(ECHO_END) 27 | 28 | after-stage:: 29 | @: 30 | 31 | endif # _THEOS_STAGING_RULES_LOADED 32 | -------------------------------------------------------------------------------- /makefiles/subproject.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/subproject.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),subproject) 5 | include $(THEOS_MAKE_PATH)/instance/subproject.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/targets/Darwin-arm/iphone.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := iphone 4 | 5 | SDKTARGET ?= arm-apple-darwin9 6 | SDKBINPATH ?= /usr/bin 7 | SYSROOT ?= /var/sdk 8 | ISYSROOT ?= $(SYSROOT) 9 | 10 | PREFIX := $(SDKBINPATH)/$(SDKTARGET)- 11 | 12 | TARGET_CC ?= $(PREFIX)gcc 13 | TARGET_CXX ?= $(PREFIX)g++ 14 | TARGET_LD ?= $(PREFIX)g++ 15 | TARGET_STRIP ?= strip 16 | TARGET_STRIP_FLAGS ?= -x 17 | TARGET_CODESIGN_ALLOCATE ?= codesign_allocate 18 | TARGET_CODESIGN ?= ldid 19 | TARGET_CODESIGN_FLAGS ?= -S 20 | 21 | TARGET_PRIVATE_FRAMEWORK_PATH = $(SYSROOT)/System/Library/PrivateFrameworks 22 | TARGET_PRIVATE_FRAMEWORK_INCLUDE_PATH = $(ISYSROOT)/System/Library/PrivateFrameworks 23 | 24 | include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk 25 | include $(THEOS_MAKE_PATH)/targets/_common/darwin_flat_bundle.mk 26 | 27 | SDKFLAGS := 28 | _THEOS_TARGET_CFLAGS := -isysroot $(ISYSROOT) $(SDKFLAGS) 29 | _THEOS_TARGET_LDFLAGS := -isysroot $(SYSROOT) $(SDKFLAGS) -multiply_defined suppress 30 | 31 | TARGET_INSTALL_REMOTE := $(_THEOS_FALSE) 32 | _THEOS_TARGET_DEFAULT_PACKAGE_FORMAT := deb 33 | endif 34 | -------------------------------------------------------------------------------- /makefiles/targets/Darwin-arm/native.mk: -------------------------------------------------------------------------------- 1 | iphone.mk -------------------------------------------------------------------------------- /makefiles/targets/Darwin/iphone.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := iphone 4 | 5 | ifeq ($(__THEOS_TARGET_ARG_1),clang) 6 | _THEOS_TARGET_CC := clang 7 | _THEOS_TARGET_CXX := clang++ 8 | _THEOS_TARGET_ARG_ORDER := 2 3 9 | else 10 | _THEOS_TARGET_CC := gcc 11 | _THEOS_TARGET_CXX := g++ 12 | _THEOS_TARGET_ARG_ORDER := 1 2 13 | endif 14 | 15 | # A version specified as a target argument overrides all previous definitions. 16 | _SDKVERSION := $(or $(__THEOS_TARGET_ARG_$(word 1,$(_THEOS_TARGET_ARG_ORDER))),$(SDKVERSION_$(THEOS_CURRENT_ARCH)),$(SDKVERSION)) 17 | _THEOS_TARGET_SDK_VERSION := $(or $(_SDKVERSION),latest) 18 | _THEOS_TARGET_INCLUDE_SDK_VERSION := $(or $(INCLUDE_SDKVERSION),$(INCLUDE_SDKVERSION_$(THEOS_CURRENT_ARCH)),latest) 19 | 20 | _SDK_DIR := $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/SDKs 21 | _IOS_SDKS := $(sort $(patsubst $(_SDK_DIR)/iPhoneOS%.sdk,%,$(wildcard $(_SDK_DIR)/iPhoneOS*.sdk))) 22 | _LATEST_SDK := $(word $(words $(_IOS_SDKS)),$(_IOS_SDKS)) 23 | 24 | ifeq ($(_THEOS_TARGET_SDK_VERSION),latest) 25 | override _THEOS_TARGET_SDK_VERSION := $(_LATEST_SDK) 26 | endif 27 | 28 | ifeq ($(_THEOS_TARGET_INCLUDE_SDK_VERSION),latest) 29 | override _THEOS_TARGET_INCLUDE_SDK_VERSION := $(_LATEST_SDK) 30 | endif 31 | 32 | # We have to figure out the target version here, as we need it in the calculation of the deployment version. 33 | _TARGET_VERSION_GE_7_0 = $(call __simplify,_TARGET_VERSION_GE_7_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 7.0)) 34 | _TARGET_VERSION_GE_6_0 = $(call __simplify,_TARGET_VERSION_GE_6_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 6.0)) 35 | _TARGET_VERSION_GE_3_0 = $(call __simplify,_TARGET_VERSION_GE_3_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 3.0)) 36 | _THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(or $(__THEOS_TARGET_ARG_$(word 2,$(_THEOS_TARGET_ARG_ORDER))),$(TARGET_IPHONEOS_DEPLOYMENT_VERSION_$(THEOS_CURRENT_ARCH)),$(TARGET_IPHONEOS_DEPLOYMENT_VERSION),$(_SDKVERSION),3.0) 37 | 38 | ifeq ($(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION),latest) 39 | override _THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(_LATEST_SDK) 40 | endif 41 | 42 | _DEPLOY_VERSION_GE_3_0 = $(call __simplify,_DEPLOY_VERSION_GE_3_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION) ge 3.0)) 43 | _DEPLOY_VERSION_LT_4_3 = $(call __simplify,_DEPLOY_VERSION_LT_4_3,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION) lt 4.3)) 44 | 45 | ifeq ($(_TARGET_VERSION_GE_6_0)$(_DEPLOY_VERSION_GE_3_0)$(_DEPLOY_VERSION_LT_4_3),111) 46 | ifeq ($(ARCHS)$(IPHONE_ARCHS)$(_THEOS_TARGET_WARNED_DEPLOY),) 47 | $(warning Deploying to iOS 3.0 while building for 6.0 will generate armv7-only binaries.) 48 | export _THEOS_TARGET_WARNED_DEPLOY := 1 49 | endif 50 | endif 51 | 52 | ifeq ($(SYSROOT),) 53 | SYSROOT ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(_THEOS_TARGET_SDK_VERSION).sdk 54 | ISYSROOT ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(_THEOS_TARGET_INCLUDE_SDK_VERSION).sdk 55 | else 56 | ISYSROOT ?= $(SYSROOT) 57 | endif 58 | 59 | ifeq ($(THEOS_CURRENT_ARCH),armv6) 60 | TARGET_LEGACY_TOOL_PATH ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/usr/bin/ 61 | TARGET_CC = $(TARGET_LEGACY_TOOL_PATH)$(_THEOS_TARGET_CC) 62 | TARGET_CXX = $(TARGET_LEGACY_TOOL_PATH)$(_THEOS_TARGET_CXX) 63 | TARGET_LD = $(TARGET_LEGACY_TOOL_PATH)$(_THEOS_TARGET_CXX) 64 | else 65 | TARGET_CC ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CC) 66 | TARGET_CXX ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CXX) 67 | TARGET_LD ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CXX) 68 | endif 69 | TARGET_STRIP ?= xcrun -sdk iphoneos strip 70 | TARGET_STRIP_FLAGS ?= -x 71 | TARGET_CODESIGN_ALLOCATE ?= "$(shell xcrun -sdk iphoneos -find codesign_allocate)" 72 | TARGET_CODESIGN ?= ldid 73 | TARGET_CODESIGN_FLAGS ?= -S 74 | 75 | TARGET_PRIVATE_FRAMEWORK_PATH = $(SYSROOT)/System/Library/PrivateFrameworks 76 | TARGET_PRIVATE_FRAMEWORK_INCLUDE_PATH = $(ISYSROOT)/System/Library/PrivateFrameworks 77 | TARGET_PRIVATE_FRAMEWORK_FALLBACK_SOURCE_PATH = $(shell xcrun --sdk iphonesimulator --show-sdk-path)/System/Library/PrivateFrameworks 78 | 79 | include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk 80 | include $(THEOS_MAKE_PATH)/targets/_common/darwin_flat_bundle.mk 81 | 82 | ifeq ($(_TARGET_VERSION_GE_7_0),1) # >= 7.0 { 83 | ARCHS ?= armv7 armv7s arm64 84 | else # } < 7.0 { 85 | ifeq ($(_TARGET_VERSION_GE_6_0),1) # >= 6.0 { 86 | ifeq ($(_DEPLOY_VERSION_GE_3_0)$(_DEPLOY_VERSION_LT_4_3),11) # 3.0 <= Deploy < 4.3 { 87 | ARCHS ?= armv7 88 | else # } else { 89 | ARCHS ?= armv7 armv7s 90 | endif # } 91 | else # } < 6.0 { 92 | ifeq ($(_TARGET_VERSION_GE_3_0),1) # >= 3.0 { 93 | ARCHS ?= armv6 armv7 94 | else # } < 3.0 { 95 | ARCHS ?= armv6 96 | endif # } 97 | endif # } 98 | endif # } 99 | NEUTRAL_ARCH = armv7 100 | 101 | SDKFLAGS := -D__IPHONE_OS_VERSION_MIN_REQUIRED=__IPHONE_$(subst .,_,$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION)) -miphoneos-version-min=$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION) 102 | _THEOS_TARGET_CFLAGS := -isysroot "$(ISYSROOT)" $(SDKFLAGS) 103 | _THEOS_TARGET_LDFLAGS := -isysroot "$(SYSROOT)" $(SDKFLAGS) -multiply_defined suppress -Wl,-segalign,4000 104 | 105 | TARGET_INSTALL_REMOTE := $(_THEOS_TRUE) 106 | _THEOS_TARGET_DEFAULT_PACKAGE_FORMAT := deb 107 | endif 108 | -------------------------------------------------------------------------------- /makefiles/targets/Darwin/macosx.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := macosx 4 | 5 | ifeq ($(__THEOS_TARGET_ARG_1),clang) 6 | _THEOS_TARGET_CC := clang 7 | _THEOS_TARGET_CXX := clang++ 8 | _THEOS_TARGET_ARG_ORDER := 2 9 | else 10 | _THEOS_TARGET_CC := gcc 11 | _THEOS_TARGET_CXX := g++ 12 | _THEOS_TARGET_ARG_ORDER := 1 13 | endif 14 | 15 | _THEOS_TARGET_MACOSX_DEPLOYMENT_VERSION := $(__THEOS_TARGET_ARG_$(_THEOS_TARGET_ARG_ORDER)) 16 | TARGET_CC ?= xcrun -sdk macosx $(_THEOS_TARGET_CC) 17 | TARGET_CXX ?= xcrun -sdk macosx $(_THEOS_TARGET_CXX) 18 | TARGET_LD ?= xcrun -sdk macosx $(_THEOS_TARGET_CXX) 19 | TARGET_STRIP ?= xcrun -sdk macosx strip 20 | TARGET_STRIP_FLAGS ?= -x 21 | TARGET_CODESIGN_ALLOCATE ?= "$(shell xcrun -sdk macosx -find codesign_allocate)" 22 | TARGET_CODESIGN ?= 23 | TARGET_CODESIGN_FLAGS ?= 24 | 25 | TARGET_PRIVATE_FRAMEWORK_PATH = /System/Library/PrivateFrameworks 26 | TARGET_PRIVATE_FRAMEWORK_INCLUDE_PATH = /System/Library/PrivateFrameworks 27 | 28 | include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk 29 | include $(THEOS_MAKE_PATH)/targets/_common/darwin_hierarchial_bundle.mk 30 | 31 | ARCHS ?= i386 x86_64 32 | NEUTRAL_ARCH = i386 33 | 34 | SDKFLAGS := $(if $(_THEOS_TARGET_MACOSX_DEPLOYMENT_VERSION),-mmacosx-version-min=$(_THEOS_TARGET_MACOSX_DEPLOYMENT_VERSION)) 35 | _THEOS_TARGET_CFLAGS := $(SDKFLAGS) 36 | _THEOS_TARGET_LDFLAGS := $(SDKFLAGS) -multiply_defined suppress 37 | 38 | export TARGET_INSTALL_REMOTE := $(_THEOS_FALSE) 39 | export _THEOS_TARGET_DEFAULT_PACKAGE_FORMAT := deb 40 | endif 41 | -------------------------------------------------------------------------------- /makefiles/targets/Darwin/native.mk: -------------------------------------------------------------------------------- 1 | macosx.mk -------------------------------------------------------------------------------- /makefiles/targets/Darwin/simulator.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := iphone_simulator 4 | 5 | ifeq ($(__THEOS_TARGET_ARG_1),clang) 6 | _THEOS_TARGET_CC := clang 7 | _THEOS_TARGET_CXX := clang++ 8 | _THEOS_TARGET_ARG_ORDER := 2 3 9 | else 10 | _THEOS_TARGET_CC := gcc 11 | _THEOS_TARGET_CXX := g++ 12 | _THEOS_TARGET_ARG_ORDER := 1 2 13 | endif 14 | 15 | # A version specified as a target argument overrides all previous definitions. 16 | _SDKVERSION := $(or $(__THEOS_TARGET_ARG_$(word 1,$(_THEOS_TARGET_ARG_ORDER))),$(SDKVERSION)) 17 | _THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(or $(__THEOS_TARGET_ARG_$(word 2,$(_THEOS_TARGET_ARG_ORDER))),$(TARGET_IPHONEOS_DEPLOYMENT_VERSION),$(_SDKVERSION),3.0) 18 | _THEOS_TARGET_SDK_VERSION := $(or $(_SDKVERSION),latest) 19 | _THEOS_TARGET_INCLUDE_SDK_VERSION := $(or $(INCLUDE_SDKVERSION),latest) 20 | 21 | _SDK_DIR := $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneSimulator.platform/Developer/SDKs 22 | _IOS_SDKS := $(sort $(patsubst $(_SDK_DIR)/iPhoneSimulator%.sdk,%,$(wildcard $(_SDK_DIR)/iPhoneSimulator*.sdk))) 23 | _LATEST_SDK := $(word $(words $(_IOS_SDKS)),$(_IOS_SDKS)) 24 | 25 | ifeq ($(_THEOS_TARGET_SDK_VERSION),latest) 26 | override _THEOS_TARGET_SDK_VERSION := $(_LATEST_SDK) 27 | endif 28 | 29 | ifeq ($(_THEOS_TARGET_INCLUDE_SDK_VERSION),latest) 30 | override _THEOS_TARGET_INCLUDE_SDK_VERSION := $(_LATEST_SDK) 31 | endif 32 | 33 | ifeq ($(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION),latest) 34 | override _THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(_LATEST_SDK) 35 | endif 36 | 37 | _TARGET_VERSION_GE_3_2 = $(call __simplify,_TARGET_VERSION_GE_3_2,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 3.2)) 38 | _TARGET_VERSION_GE_4_0 = $(call __simplify,_TARGET_VERSION_GE_4_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 4.0)) 39 | _TARGET_VERSION_GE_7_0 = $(call __simplify,_TARGET_VERSION_GE_7_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 7.0)) 40 | 41 | ifeq ($(SYSROOT),) 42 | SYSROOT ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(_THEOS_TARGET_SDK_VERSION).sdk 43 | ISYSROOT ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(_THEOS_TARGET_INCLUDE_SDK_VERSION).sdk 44 | else 45 | ISYSROOT ?= $(SYSROOT) 46 | endif 47 | 48 | TARGET_CC ?= xcrun -sdk iphonesimulator $(_THEOS_TARGET_CC) 49 | TARGET_CXX ?= xcrun -sdk iphonesimulator $(_THEOS_TARGET_CXX) 50 | TARGET_LD ?= xcrun -sdk iphonesimulator $(_THEOS_TARGET_CXX) 51 | TARGET_STRIP ?= xcrun -sdk iphonesimulator strip 52 | TARGET_STRIP_FLAGS ?= -x 53 | TARGET_CODESIGN_ALLOCATE ?= "$(shell xcrun -sdk iphonesimulator -find codesign_allocate)" 54 | TARGET_CODESIGN ?= $(if $(_TARGET_VERSION_GE_7_0),ldid) 55 | TARGET_CODESIGN_FLAGS ?= $(if $(_TARGET_VERSION_GE_7_0),-S) 56 | 57 | TARGET_PRIVATE_FRAMEWORK_PATH = $(SYSROOT)/System/Library/PrivateFrameworks 58 | TARGET_PRIVATE_FRAMEWORK_INCLUDE_PATH = $(ISYSROOT)/System/Library/PrivateFrameworks 59 | 60 | include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk 61 | include $(THEOS_MAKE_PATH)/targets/_common/darwin_flat_bundle.mk 62 | 63 | ifeq ($(IPHONE_SIMULATOR_ROOT),) 64 | internal-install:: 65 | $(info $(MAKE) install for the simulator requires that you set IPHONE_SIMULATOR_ROOT to the root directory of the simulated OS.) 66 | @exit 1 67 | else 68 | internal-install:: stage 69 | install.mergeDir "$(THEOS_STAGING_DIR)" "$(IPHONE_SIMULATOR_ROOT)" 70 | endif 71 | 72 | ARCHS ?= i386 $(if $(_TARGET_VERSION_GE_7_0),x86_64) 73 | NEUTRAL_ARCH = i386 74 | 75 | _TARGET_VERSION_FLAG = $(if $(_TARGET_VERSION_GE_7_0),-mios-simulator-version-min=$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION),-mmacosx-version-min=$(if $(_TARGET_VERSION_GE_4_0),10.6,10.5)) 76 | _TARGET_OBJC_ABI_CFLAGS = $(if $(_TARGET_VERSION_GE_3_2),-fobjc-abi-version=2 -fobjc-legacy-dispatch) 77 | _TARGET_OBJC_ABI_LDFLAGS = $(if $(_TARGET_VERSION_GE_3_2),-Xlinker -objc_abi_version -Xlinker 2) 78 | 79 | SDKFLAGS := -D__IPHONE_OS_VERSION_MIN_REQUIRED=__IPHONE_$(subst .,_,$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION)) $(_TARGET_VERSION_FLAG) 80 | 81 | _THEOS_TARGET_CFLAGS := -isysroot $(ISYSROOT) $(SDKFLAGS) $(_TARGET_OBJC_ABI_CFLAGS) 82 | _THEOS_TARGET_LDFLAGS := -isysroot $(SYSROOT) $(SDKFLAGS) -multiply_defined suppress $(_TARGET_OBJC_ABI_LDFLAGS) 83 | endif 84 | -------------------------------------------------------------------------------- /makefiles/targets/Linux/iphone.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := iphone 4 | 5 | SDKTARGET ?= arm-apple-darwin9 6 | SDKBINPATH ?= /opt/iphone-sdk-3.0/prefix/bin 7 | SYSROOT ?= /opt/iphone-sdk-3.0/sysroot 8 | ISYSROOT ?= $(SYSROOT) 9 | 10 | PREFIX := $(SDKBINPATH)/$(SDKTARGET)- 11 | 12 | TARGET_CC ?= $(PREFIX)gcc 13 | TARGET_CXX ?= $(PREFIX)g++ 14 | TARGET_LD ?= $(PREFIX)g++ 15 | TARGET_STRIP ?= $(PREFIX)strip 16 | TARGET_STRIP_FLAGS ?= -x 17 | TARGET_CODESIGN_ALLOCATE ?= $(PREFIX)codesign_allocate 18 | TARGET_CODESIGN ?= ldid 19 | TARGET_CODESIGN_FLAGS ?= -S 20 | 21 | include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk 22 | include $(THEOS_MAKE_PATH)/targets/_common/darwin_flat_bundle.mk 23 | 24 | TARGET_PRIVATE_FRAMEWORK_PATH = $(SYSROOT)/System/Library/PrivateFrameworks 25 | TARGET_PRIVATE_FRAMEWORK_INCLUDE_PATH = $(ISYSROOT)/System/Library/PrivateFrameworks 26 | 27 | SDKFLAGS := 28 | _THEOS_TARGET_CFLAGS := -isysroot $(ISYSROOT) $(SDKFLAGS) 29 | _THEOS_TARGET_LDFLAGS := -isysroot $(SYSROOT) $(SDKFLAGS) -multiply_defined suppress 30 | 31 | TARGET_INSTALL_REMOTE := $(_THEOS_TRUE) 32 | _THEOS_TARGET_DEFAULT_PACKAGE_FORMAT := deb 33 | endif 34 | -------------------------------------------------------------------------------- /makefiles/targets/Linux/linux.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(_THEOS_TARGET_LOADED),) 2 | _THEOS_TARGET_LOADED := 1 3 | THEOS_TARGET_NAME := linux 4 | 5 | ifneq ($(__THEOS_TARGET_ARG_1),) 6 | CROSS_COMPILE := $(__THEOS_TARGET_ARG_1)- 7 | endif 8 | 9 | TARGET_CC ?= $(CROSS_COMPILE)gcc 10 | TARGET_CXX ?= $(CROSS_COMPILE)g++ 11 | TARGET_LD ?= $(CROSS_COMPILE)g++ 12 | TARGET_STRIP ?= $(CROSS_COMPILE)strip 13 | TARGET_STRIP_FLAGS ?= 14 | TARGET_CODESIGN_ALLOCATE ?= 15 | TARGET_CODESIGN ?= 16 | TARGET_CODESIGN_FLAGS ?= 17 | 18 | include $(THEOS_MAKE_PATH)/targets/_common/linux.mk 19 | 20 | endif 21 | -------------------------------------------------------------------------------- /makefiles/targets/Linux/native.mk: -------------------------------------------------------------------------------- 1 | linux.mk -------------------------------------------------------------------------------- /makefiles/targets/_common/darwin.mk: -------------------------------------------------------------------------------- 1 | # Variables that are common to all Darwin-based targets. 2 | TARGET_EXE_EXT := 3 | TARGET_LIB_EXT := .dylib 4 | 5 | TARGET_LDFLAGS_DYNAMICLIB = -dynamiclib -install_name "$(LOCAL_INSTALL_PATH)/$(1)" 6 | TARGET_CFLAGS_DYNAMICLIB = 7 | 8 | _THEOS_TARGET_ONLY_OBJCFLAGS := -std=c99 9 | 10 | _THEOS_TARGET_SUPPORTS_BUNDLES := 1 11 | -------------------------------------------------------------------------------- /makefiles/targets/_common/darwin_flat_bundle.mk: -------------------------------------------------------------------------------- 1 | _THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY := 2 | _THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY := 3 | _THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY := 4 | -------------------------------------------------------------------------------- /makefiles/targets/_common/darwin_hierarchial_bundle.mk: -------------------------------------------------------------------------------- 1 | _THEOS_TARGET_BUNDLE_INFO_PLIST_SUBDIRECTORY := /Contents 2 | _THEOS_TARGET_BUNDLE_RESOURCE_SUBDIRECTORY := /Contents/Resources 3 | _THEOS_TARGET_BUNDLE_BINARY_SUBDIRECTORY := /Contents/MacOS 4 | -------------------------------------------------------------------------------- /makefiles/targets/_common/linux.mk: -------------------------------------------------------------------------------- 1 | # Variables that are common to all Linux-based targets. 2 | TARGET_EXE_EXT := 3 | TARGET_LIB_EXT := .so 4 | 5 | TARGET_LDFLAGS_DYNAMICLIB = -shared -Wl,-soname,$(1) 6 | TARGET_CFLAGS_DYNAMICLIB = -fPIC 7 | -------------------------------------------------------------------------------- /makefiles/tool.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/tool.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),tool) 5 | include $(THEOS_MAKE_PATH)/instance/tool.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /makefiles/tweak.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(THEOS_CURRENT_INSTANCE),) 2 | include $(THEOS_MAKE_PATH)/master/tweak.mk 3 | else 4 | ifeq ($(_THEOS_CURRENT_TYPE),tweak) 5 | include $(THEOS_MAKE_PATH)/instance/tweak.mk 6 | endif 7 | endif 8 | -------------------------------------------------------------------------------- /mod/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpetrich/theos/6b05eac5169242b99a599a94e692d0d9e8baa855/mod/.keep -------------------------------------------------------------------------------- /templates/iphone/library.nic.tar: -------------------------------------------------------------------------------- 1 | .000755000000000000 012022775273 10764 5ustar00dustinstaff000000000000NIC000777000000000000 012022775273 11322 5ustar00dustinstaff000000000000.control000644000765000024 13212022773542 13061 0ustar00dustinstaff000000000000./NICname "iphone/library" 2 | constrain file "control" to package 3 | constrain "theos" to link_theos 4 | @@PROJECTNAME@@.mm100644000000000000 11412016326345 13516 0ustar00dustinstaff000000000000.int main(int argc, char **argv, char **envp) { 5 | return 0; 6 | } 7 | 8 | // vim:ft=objc 9 | Makefile100644000000000000 23012022772543 12455 0ustar00dustinstaff000000000000.include @@THEOS@@/makefiles/common.mk 10 | 11 | LIBRARY_NAME = @@PROJECTNAME@@ 12 | @@PROJECTNAME@@_FILES = @@PROJECTNAME@@.mm 13 | 14 | include $(THEOS_MAKE_PATH)/library.mk 15 | control100644000000000000 34112016326345 12421 0ustar00dustinstaff000000000000.Package: @@PACKAGENAME@@ 16 | Name: @@FULLPROJECTNAME@@ 17 | Depends: 18 | Version: 0.0.1 19 | Architecture: iphoneos-arm 20 | Description: An awesome library of some sort!! 21 | Maintainer: @@USER@@ 22 | Author: @@USER@@ 23 | Section: System 24 | Tag: role::developer 25 | theos000644000000000000 012022775273 14040 2@@THEOS_PATH@@ustar00dustinstaff000000000000. -------------------------------------------------------------------------------- /templates/iphone/tool.nic.tar: -------------------------------------------------------------------------------- 1 | .000755000000000000 012022775274 10765 5ustar00dustinstaff000000000000NIC000777000000000000 012022775274 11323 5ustar00dustinstaff000000000000.control000644000765000024 12712022773542 13065 0ustar00dustinstaff000000000000./NICname "iphone/tool" 2 | constrain file "control" to package 3 | constrain "theos" to link_theos 4 | Makefile100644000000000000 20712022772543 12461 0ustar00dustinstaff000000000000.include @@THEOS@@/makefiles/common.mk 5 | 6 | TOOL_NAME = @@PROJECTNAME@@ 7 | @@PROJECTNAME@@_FILES = main.mm 8 | 9 | include $(THEOS_MAKE_PATH)/tool.mk 10 | control100644000000000000 33312016326345 12422 0ustar00dustinstaff000000000000.Package: @@PACKAGENAME@@ 11 | Name: @@FULLPROJECTNAME@@ 12 | Depends: 13 | Version: 0.0.1 14 | Architecture: iphoneos-arm 15 | Description: An awesome tool of some sort!! 16 | Maintainer: @@USER@@ 17 | Author: @@USER@@ 18 | Section: System 19 | Tag: role::hacker 20 | main.mm100644000000000000 11412016326345 12273 0ustar00dustinstaff000000000000.int main(int argc, char **argv, char **envp) { 21 | return 0; 22 | } 23 | 24 | // vim:ft=objc 25 | theos000644000000000000 012022775274 14041 2@@THEOS_PATH@@ustar00dustinstaff000000000000. -------------------------------------------------------------------------------- /templates/iphone/tweak.nic.tar: -------------------------------------------------------------------------------- 1 | .000755000000000000 012215500435 10752 5ustar00dustinstaff000000000000NIC000777000000000000 012215500435 11310 5ustar00dustinstaff000000000000.control000644000765000000 23612061733026 13055 0ustar00dustinwheel000000000000./NICname "iphone/tweak" 2 | prompt FILTER "MobileSubstrate Bundle filter" "com.apple.springboard" 3 | constrain file "control" to package 4 | constrain "theos" to link_theos 5 | @@PROJECTNAME@@.plist100644000000000000 5612016326345 14226 0ustar00dustinwheel000000000000.{ Filter = { Bundles = ( "@@FILTER@@" ); }; } 6 | control100644000000000000 33312016326345 12423 0ustar00dustinwheel000000000000.Package: @@PACKAGENAME@@ 7 | Name: @@FULLPROJECTNAME@@ 8 | Depends: mobilesubstrate 9 | Version: 0.0.1 10 | Architecture: iphoneos-arm 11 | Description: An awesome MobileSubstrate tweak! 12 | Maintainer: @@USER@@ 13 | Author: @@USER@@ 14 | Section: Tweaks 15 | Makefile100644000000000000 23112073632155 12457 0ustar00dustinwheel000000000000.include @@THEOS@@/makefiles/common.mk 16 | 17 | TWEAK_NAME = @@PROJECTNAME@@ 18 | @@PROJECTNAME@@_FILES = Tweak.xm 19 | 20 | include $(THEOS_MAKE_PATH)/tweak.mk 21 | 22 | @@KILL_RULE@@ 23 | theos000644000000000000 012215500435 14026 2@@THEOS_PATH@@ustar00dustinstaff000000000000.Tweak.xm100644000000000000 202512016326345 12461 0ustar00dustinwheel000000000000./* How to Hook with Logos 24 | Hooks are written with syntax similar to that of an Objective-C @implementation. 25 | You don't need to #include , it will be done automatically, as will 26 | the generation of a class list and an automatic constructor. 27 | 28 | %hook ClassName 29 | 30 | // Hooking a class method 31 | + (id)sharedInstance { 32 | return %orig; 33 | } 34 | 35 | // Hooking an instance method with an argument. 36 | - (void)messageName:(int)argument { 37 | %log; // Write a message about this call, including its class, name and arguments, to the system log. 38 | 39 | %orig; // Call through to the original function with its original arguments. 40 | %orig(nil); // Call through to the original function with a custom argument. 41 | 42 | // If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.) 43 | } 44 | 45 | // Hooking an instance method with no arguments. 46 | - (id)noArguments { 47 | %log; 48 | id awesome = %orig; 49 | [awesome doSomethingElse]; 50 | 51 | return awesome; 52 | } 53 | 54 | // Always make sure you clean up after yourself; Not doing so could have grave consequences! 55 | %end 56 | */ 57 | control.pl100644000000000000 65612215500422 13445 0ustar00dustinwheel000000000000./NICmy $default_kill = "SpringBoard"; 58 | 59 | NIC->variable("KILL_RULE") = ""; 60 | 61 | my $kill_apps = NIC->prompt("KILL_APPS", "List of applications to terminate upon installation (space-separated, '-' for none)", {default => $default_kill}); 62 | if($kill_apps ne "-") { 63 | my @apps = split(/\s+/, $kill_apps); 64 | my @commands = map {"killall -9 $_"} @apps; 65 | NIC->variable("KILL_RULE") = "after-install::\n\tinstall.exec \"".join("; ", @commands)."\""; 66 | } 67 | --------------------------------------------------------------------------------