Theos/Troubleshooting: Difference between revisions

From iPhone Development Wiki
m (Added a small note)
m (→‎Undefined symbols: Adapted note into examples.)
 
Line 151: Line 151:


<source lang="objc">
<source lang="objc">
[SomeClass someMethod];
[SomeClass methodOrProperty]
</source>
</source>


Line 157: Line 157:


<source lang="objc">
<source lang="objc">
[%c(SomeClass) someMethod];
[%c(SomeClass) methodOrProperty]
[objc_getClass("SomeClass") someMethod];
[objc_getClass("SomeClass") methodOrProperty]
[NSClassFromString(@"SomeClass") someMethod];
[NSClassFromString(@"SomeClass") methodOrProperty]
</source>
</source>
Note: someMethod can also be an instance variable.


If, however, the class in question exists in a public or private framework from the SDK you are missing said framework in your <code>XXX_FRAMEWORKS</code> or <code>XXX_PRIVATE_FRAMEWORKS</code> list.
If, however, the class in question exists in a public or private framework from the SDK you are missing said framework in your <code>XXX_FRAMEWORKS</code> or <code>XXX_PRIVATE_FRAMEWORKS</code> list.

Latest revision as of 03:17, 30 October 2018

Before jumping to popular forums (StackOverflow, Reddit, IRC channels) to ask your questions, first give your error a good read, try looking for generic errors that might cover the one you are experiencing problems with. Use said forums but to find if your question has been asked before; chances are, it was! If you have exhausted your options, looked beyond the tenth page of a specific google query, think your question twice and ask it to yourself; would you understand what it is you are asking? If so, ask away.

Consider reading these articles too: What have you tried? and Solving your skillset problems.

Empty $THEOS or corrupt symlink

Makefile:N: theos/makefiles/common.mk: Not a directory
Makefile:N: /tweak.mk: No such file or directory

N is a linenumber.

Either $THEOS is empty or the theos symlink in your project(s) points to a wrong path (not $THEOS).

To fix the former, run:

export THEOS=platform_dependent_path

Remember to have this exported on every session, method depends on the terminal you use.

To fix the latter, run in each directory the symlink is "broken":

rm theos; ln -s $THEOS

Missing SDK

If you get this message:

".../theos/makefiles/targets/PPP/iphone.mk:21: *** first argument to 'word' function must be greater than 0. stop."

PPP is the platform of the working machine.

It means that you don't have SDKs in $THEOS/sdks. See this section.

Small SDK

If you get this message:

ld: file too small (length=LLL) file. '.../theos/sdks/iPhoneOSX.Y.sdk/usr/ZZZ' for architecture armAAA.

LLL is a size, potentially 0 on most cases, X & Y are sdk version, ZZZ is a file path, AAA is architecture suffix (v6, v7, v7s, 64).

It probably means that you have a faulty SDK in some way. One common mistake, while using Theos on an iOS device, is to extract the SDK on a PC and then copy over the files. This usually results in various errors in the extraction that translate in not being able to compile. Instead, copy the SDK in the compressed form and extract it on the device. Do not worry if this takes time, it will preserve all file attributes.

Default settings

If you get this message:

.../theos/makefiles/targets/Darwin-arm64/iphone.mk:43: Targeting iOS 4.0 and higher is not supported with iphone-gcc. Forcing clang.

It means that you haven't set up your TARGET environment variable correctly. See Theos#Theos variables.

Missing Substrate header

If you get this message:

FFF:LLL:10: fatal error: 'substrate.h' file not found
#include <substrate.h>
         ^
1 error generated.

FFF is a file path, LLL is a line number.

This means that you are missing the Substrate header (see step #6 in setting up Theos for OS X or Linux). To fix this you need to copy /Library/Frameworks/CydiaSubstrate.framework/Headers/CydiaSubstrate.h to your local $THEOS/include folder and rename it to substrate.h.

Missing Substrate symbols

If you get this message:

 FFF:LLL:CCC: error: implicit declaration of function 'MSFindSymbol' is invalid in C99 [-Werror,-Wimplicit-function-declaration]

FFF is a file path, LLL is a line number, CCC is a column number.

It probably means that you have an old Substrate header (see step #6 in setting up Theos for OS X or Linux). To fix this you need to copy /Library/Frameworks/CydiaSubstrate.framework/Headers/CydiaSubstrate.h to your local $THEOS/include folder and rename it to substrate.h.

Missing Substrate library

If you get either of these messages:

Bootstrapping CydiaSubstrate...
Compiling iPhoneOS CydiaSubstrate stub... default target? failed, what?
cp: cannot stat ‘_out/*’: No such file or directory
cp: cannot stat ‘libsubstrate.dylib’: No such file or directory

Or

ld: warning: ignoring file .../theos/lib/libsubstrate.dylib, file was built for armXXX which is not the architecture being linked (armYYY): .../theos/lib/libsubstrate.dylib

XXX and YYY are architecture suffixes (v6, v7, v7s, 64).

This means that you are missing the Substrate library to link with (see step #6 in setting up Theos for OS X or Linux) or you have an old version of the library. Either way, get an up-to-date version of the file from the device at /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate, copy it to your local $THEOS/lib folder, and rename it to libsubstrate.dylib.

More detail about how to fix this:

OS X and Linux users can use the following command to copy the file (using the scp program), where DEVICE_IP should be replaced with the IP address of your device where you have Substrate installed:

scp -P PORT root@[DEVICE_IP]:/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate $THEOS/lib/libsubstrate.dylib

Windows users can use WinSCP to connect to the device's IP address to locate the file and copy it over to their Theos installation.

iOS users usually don't have this problem because they usually already have Substrate installed. However, they can have an outdated version of Substrate and need to update it.

Architecture (partial) incompatibility

If you get this error while attempting to run the Theos New Instance Creator (NIC):

Illegal instruction: 4

It probably means you are using versions of tools that work on older devices but not on new ones. Read more on the issue here.

It usually affects perl and rsync (installed from the default sources), so to fix this, run these commands as root on the device using SSH or MobileTerminal:

sed -i'' 's/\x00\x30\x93\xe4/\x00\x30\x93\xe5/g;s/\x00\x30\xd3\xe4/\x00\x30\xd3\xe5/g;' /usr/bin/perl; ldid -s /usr/bin/perl
sed -i'' 's/\x00\x30\x93\xe4/\x00\x30\x93\xe5/g;s/\x00\x30\xd3\xe4/\x00\x30\xd3\xe5/g;' /usr/bin/rsync; ldid -s /usr/bin/rsync

Spaces in Path

While building a project mostly works even if the path to the project contains spaces, make package will fail. Make sure you don't have spaces in the project path.

Undefined platform

If you get this message:

theos/makefiles/common.mk:103: *** You did not specify a target, and the "" platform does not define a default target. Stop.

or this one:

theos/makefiles/common.mk:115: *** The "iphone" target is not supported on the "" platform. Stop.

It probably means you are using a platform unsupported by Theos. If you are using iOS as a platform and on a 64bit device, you are probably getting this error. To fix this, you can do the following:

sudo ln -s $THEOS/makefiles/platform/Darwin-arm{,64}.mk
sudo ln -s $THEOS/makefiles/targets/Darwin-arm{,64}

Undefined symbols

If you get this message:

Undefined symbols for architecture armXXX:
  "_OBJC_CLASS_$_SomeClass", referenced from:
...
ld: symbol(s) not found for architecture armXXX
...

It probably means that you are trying to use the SomeClass class directly. This usually happens when using private classes that exist in binaries and cannot be linked in the compilation of your tweak. To work around this one must get the class at runtime. There are at least three ways to do it:

  • %c(SomeClass)
  • objc_getClass("SomeClass")
  • NSClassFromString(@"SomeClass")

So replace usages like:

	[SomeClass methodOrProperty]

With one of these:

	[%c(SomeClass) methodOrProperty]
	[objc_getClass("SomeClass") methodOrProperty]
	[NSClassFromString(@"SomeClass") methodOrProperty]

If, however, the class in question exists in a public or private framework from the SDK you are missing said framework in your XXX_FRAMEWORKS or XXX_PRIVATE_FRAMEWORKS list.

Or if you get a message that looks like this:

ld: warning: ignoring file /.../theos/lib/libsubstrate.dylib, missing required architecture armXXX in file /.../theos/lib/libsubstrate.dylib (2 slices)
Undefined symbols for architecture armXXX:
...
ld: symbol(s) not found for architecture armXXX

That means the Substrate dylib you are using doesn't contain the architecture you are linking. To fix this, get an up-to-date version of Substrate from the device at /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate, copy it to your local $THEOS/lib folder, and rename it to libsubstrate.dylib For more detail about how to fix this, see the suggested command at #Missing Substrate library.

Incompatible package compression

While installing a package created with Theos, you may get the following error:

dpkg-deb: file `package.deb' contains ununderstood data member data.tar.xz, giving up
dpkg: error processing package.deb (--install):
 subprocess dpkg-deb --fsys-tarfile returned error exit status 2
Errors were encountered while processing:
 package.deb

This is because dpkg-deb now uses xz to compress the package, but Telesphoreo's old version of dpkg doesn't support it. You can force it to use dpkg-deb with a command line argument. Open $THEOS/makefiles/package/deb.mk. Find $(FAKEROOT) -r dpkg-deb, and after dpkg-deb, add -Zlzma. It should look similar this:

$(FAKEROOT) -r dpkg-deb -Zlzma -b ...