I'm currently making an OpenGL ES 2.0 drawing app for the iPad and I keep getting the following warnings regarding the shaders:
Check dependencies
[WARN]warning: no rule to process file '$(PROJECT_DIR)/IdeaStorm/Drawing Engine/Shaders/Shader.fsh' of type sourcecode.glsl for architecture i386
[WARN]warning: no rule to process file '$(PROJECT_DIR)/IdeaStorm/Drawing Engine/Shaders/Shader.vsh' of type sourcecode.glsl for architecture i386
My drawing app currently runs fine on my 2nd gen iPad with iOS 5, with exception of this error and runs in the simulator fine as well.
However, the other day I tried running it on my friends 1st gen iPad with iOS 4.3 and the shaders failed to compile.
Can anyone point my in the right direction regarding both this warning and the failure for the shaders to compile for the 1st gen iPad?
By default, when you add a vertex and fragment shader to your project, Xcode mistakenly thinks of them as source files to be compiled instead of resources to be bundled. This causes the above errors you're seeing.
Remove your Shader.fsh and Shader.vsh files from your project target's Compile Sources build phase and make sure they're present within your Copy Bundle Resources phase.
It's a little odd that your shaders compile (at runtime, I assume) successfully on an iPad 2, but not on an original iPad. While the iPad 2 has significantly more shader horsepower than an iPad 1, there shouldn't be much that would cause a shader to fail on one when it works on the other. You could try logging out any shader compilation failures using code like the following (during your shader compilation process):
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
{
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
NSLog(#"Shader compile log:\n%s", log);
free(log);
}
}
Related
I'm working with the Vuforia library for iOS (augmented reality). The library framework is only compiled for armv7 and v7s arch - thus it won't run in the simulator (i386 arch). In order to test the rest of my app in the simulator I've wrapped parts of my code that reference the vuforia functions in compiler macros as such:
#if TARGET_IPHONE_SIMULATOR
//do simulator stuff
#else
//do vuforia stuff
#endif
This has taken my error count down to just one left - which I can't seem to get rid of:
Undefined symbols for architecture i386:
"QCAR::Renderer::getInstance()", referenced from:
SampleMath::projectScreenPointToPlane...
I have found SampleMath.cpp and have found the one and only call to reference to renderer.getInstance and have wrapped that in the macros. I've tried wrapping the entire .h and .cpp file in the macros; I've searched my entire xcode project for other places where the code might be referenced. Still after multiple cleans, and a OS X + xcode restart; still getting the same compiler error. Any Ideas? If so - many thanks.
It seems that Xcode doesn't define automatically TARGET_IPHONE_SIMULATOR in .cpp files.
The solution is to insert at the begining of your .cpp file :
#include "TargetConditionals.h"
Then all tests on TARGET_IPHONE_SIMULATOR will work.
I've been using SpriteKit for a while in iOS; now I'm developing an app for the Mac.
I've setup a texture atlas as usual:
Enable texture atlas generation for both the Project and the Target (I started from the "Document Based Application" template, not "SpriteKit Game". It has different build settings).
Drag all the individual texture image files into a folder,
Rename the folder to "Something.atlas",
Add the folder to the project,
At runtime, create the atlas by name (i.e., [SKTextureAtlas atlasNamed:#"Something"];).
Obtain individual "textures" by name (i.e., [_atlas textureNamed:#"MyTexture"];) and create SKSpriteNode instances with them.
I am preloading the atlas asynchronously, but the completion handler never gets called (see comments):
_atlas = [SKTextureAtlas atlasNamed:#"Something"];
if (!_atlas) {
NSLog(#"Error: Failed to create atlas!");
// This line doesn't execute, so atlas is not nil.
}
[_atlas preloadWithCompletionHandler:^(void){
// This block doesn't get executed either,
// so atlas loading somehow fails...
NSLog(#"Atlas Loaded!");
[self createSprites];
}];
When I check the package contents of the build product (e.g., MyApp.app), in the resources subdirectory I can see the atlas folder ("Something.atlasc"), but it only contains a .plist file with no entries, and the image resources are nowhere to be found... So what gives?
Actually, it wasn't the workspace after all. The same workspace/project, when copied to the Desktop, builds fine.
The cause seems to be that, one of the intermediate directories in the path to the project folder had a name in japanese characters. I tested as follows:
Change folder name to english -> clean build folder -> build -> OK
Change folder name back to japanese -> clean build folder -> build -> Atlas broken
Change folder name back to english -> clean build folder -> build -> OK
...(you see the pattern)...
I wonder why and how this only affects the export of texture atlases, and nothing else.
Hope this experience helps someone else in the future...
I will update the bug report at Apple as well.
UPDATE: According to Apple, the issue has been solved as of iOS 8 beta 2 (Build 12A4297e). I haven't had an opportunity to check (the project I was working at was a prototype that didn't take off, and I settled for the name change solution). In any case, iOS 8 is final now.
I'm using Xcode 5. I have a OS X Framework / iOS static library project with mixed ObjC/C++ code and language dialects set to C11/C++11.
I added a Cocoa Unit Testing Bundle target which uses XCTest, I created one for both the iOS static library and the OS X framework.
This is the code I have and the error I get in both:
-(void) testExample
{
NSObject* world = [NSObject new];
world = nil; <--- Ambiguous expansion of macro 'NULL'
}
Running the iOS test the compiler tells me it is using the definition of NULL from stddef.h (line 74, ((void*)0)) and the other definition being in usr/include/stdlib.h (line 115, __DARWIN_NULL).
The OS X test fails points to usr/include/MacTypes.h (line 90, __DARWIN_NULL) with this time the alternative being in stddef.h (line 74, ((void*)0)).
Google has nothing on this issue. I'm just like "Well, I guess it's just one of these days...".
Any clues as to what may be going on here, and how to fix it?
UPDATE:
The iOS tests not running were due to creating the iOS unit test bundle with the OS X "Cocoa Unit Testing Bundle". /me slap
The OS X testing issue persists though. But I have a hunch that being on OS X 10.9 (Mavericks) this may be related to a missing 10.9 SDK (Base SDK is set to 10.8).
In your Build Settings for your test target, try setting "Enable Modules" to NO.
I've been having various kinds of trouble with test targets, all around preprocessor expansion. Doing this fixed things for me.
Try this: Add -Wno-ambiguous-macro to Xcode -> Build Settings -> Other C Flags
This code snippet is from a iPad app the is currently in the app store and is written using ARC. The code has developed using xCode 4.4.1 (4F1003) and runs properly in the IOS Simulator 5.1 (272.21). I recently installed xCode 4.5 and IOS Simulator 6.0 and I now get EXC_BAD_ACCESS (code=2, address=0x200) when the sqlite3_open returns to my objective C code.
sqlite3 *tempDatabase;
const char *sqlStatement = [s_DBEngineDBName UTF8String];
commandReturn = sqlite3_open(sqlStatement, &tempDatabase); // open main db
if(commandReturn == SQLITE_OK) {
// ...
}
I have previously used the following command to open the database but it also fails in the new environment.
commandReturn = sqlite3_open([s_DBEngineDBName cStringUsingEncoding:NSStringEncodingConversionAllowLossy], &tempDatabase); // open main db
As I stated above stepping thru the SQLite code it all works as expected until the final return statement executes. I am confused as to why objc_storeStrong is even involved.
I tracked the issue down to a forward declaration in an include file:
#class sqlite3;
which is obviously wrong as sqlite3 is a struct. This was causing the ARC to try and reference count it which is what was raising the exception.
Removing the line caused compile errors which were easily resolved by prefixing the use of sqlite3 with the key word "struct".
Thanks for your suggestions as they got me to dig deeper and realize that the compiler was considering sqlite3 to be a class when in reality it is not.
Here is the situation:
I have a client's java project open in eclipse. It uses a JNI library created by an Xcode Objective C project. Is there any good way for me to debug the C code from eclipse when I execute the Java code? Obviously eclipse's default debugger cannot step into the jni library file and we lose the thread (thread meaning investigative thread here, not programming thread).
Any advice or input is appreciated as the code base is large enough that following the client's code will be radically faster than other options.
Thanks.
EDIT:
It should be noted that the reason that the jni library is written in Objective-C is because it is integrating with Mac OSX. It is using the Cocoa framework to integrate with the Apple speech api.
I am not sure that I have fully understood your setup and if you require this to be done from eclipse or not. Anyhow I was interested in doing a little test program using JNI and a Cocoa library doing nothing just to try the debugging of the obj-c/c code.
I succeeded to do this setup and also to debug the code. I use IntelliJ for Java and Xcode for the objc/c part but doing the java part in eclipse is a no-brainer.
So you should be able to set up exactly my project structure and get going with the debugging. And from there you should be able to apply this knowledge to your own more complex code.
This is how I started off:
Create a new project in Xcode by choosing Cocoa Library.
Name the project libnative and make it of Type Dynamic.
Choose a place for your new project. I use ~/Development/ and skip the Create local git... part.
This will create a new project called lib native.xcodeproj in your selected folder. Two files have been automatically created: libnative.h and libnative.m.
First you must change the Project Settings.
Executable Extension in the Packaging section must be changed from dynlib to jnilib.
Framework Search Paths in the Search Paths section must be updated to point to the JNI framework: /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/
Now its time to add some code. Be aware that with this setup you will have to use <JavaVM/jni.h>. Update the libnative.m to look like the following code:
//
// libnative.m
// libnative
//
// Created by maba on 2012-10-09.
// Copyright (c) 2012 maba. All rights reserved.
//
#import "libnative.h"
#include <JavaVM/jni.h>
#implementation libnative
#end
#ifdef __cplusplus
extern "C" {
#endif
#ifndef VEC_LEN
#define VEC_LEN(v) (sizeof(v)/sizeof(v[0]))
#endif/*VEC_LEN*/
static JavaVM *javaVM;
static void print();
static JNINativeMethod Main_methods[] =
{
{ "print", "()V", (void*)print },
};
static struct {
const char *class_name;
JNINativeMethod *methods;
int num_methods;
} native_methods[] = {
{ "com/stackoverflow/Main", Main_methods, VEC_LEN(Main_methods) },
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv *env = 0;
jclass cls = 0;
jint rs = 0;
if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)) {
return JNI_ERR;
}
javaVM = jvm;
for (unsigned int i = 0; i < VEC_LEN(native_methods); i++) {
cls = (*env)->FindClass(env, native_methods[i].class_name);
if (cls == NULL) {
return JNI_ERR;
}
rs = (*env)->RegisterNatives(env, cls, native_methods[i].methods, native_methods[i].num_methods);
assert(rs == JNI_OK);
}
return JNI_VERSION_1_4;
}
static void print(JNIEnv *env, jclass cls) {
printf("Hello from C");
}
#ifdef __cplusplus
}
#endif
Build the code by pressing ⌘+B.
And now it is time to create the Java code. I simply created a class called Main in package com.stackoverflow.
com.stackoverflow.Main.java
package com.stackoverflow;
/**
* #author maba, 2012-10-09
*/
public class Main {
static native void print();
static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("native");
}
public static void main(String[] args) {
System.out.println("Loading native");
Main.print();
}
}
Set a breakpoint on the line before Main.print();. Start the debugger with the following JVM option:
-Djava.library.path="/Users/maba/Library/Developer/Xcode/DerivedData/libnative-cquleqohzyhghnercyqdwpnznjdf/Build/Products/Debug/"
This line is a little long and also user specific. You will have to look for yourself what the directory names are but they will be more or less the same as mine except for the generated libnative-cquleqohzyhghnercyqdwpnznjdf path.
The program should be running and waiting at the breakpoint. Time to attach the Xcode debugger to the running application.
Choose menu Product -> Attach to Process > and point to the running java process in the System part of the drop down. If there are several java processes then it is most likely the one with the highest PID but not always. You'll have to try.
Create a breakpoint in the c code on the line printf("Hello from C");.
Go back to the Java IDE and continue the execution from where it was halting.
Go back to Xcode and see that it is waiting at the breakpoint!
As I stated earlier this is a very simple approach to the obj-c/JNI and your project is probably quite large but with this small test project you can at least see how it works and then continue to your own project setup.
You might be able to attach with gdb (or lldb) from the Terminal. If the launching of the process w/the native code is the result of a fork()/exec() -- i.e. if you can't type gdb /some/command/line -- then you can likely use the --waitfor option (see the man page) to wait for the launch of the inferior.
Loading symbols will be tricky.
This is a Mac OS X project using the cocoa framework. Does that affect
this?
It shouldn't. If anything, it'll make it easier in that, hopefully, the symbol files are of a usable format. The key is typically finding the right spot to break at the boundary between java and native code.
Is the native code in a dylib that is loaded into the JVM or do you have a custom executable that fires up the JVM internally?
In any case, you need to attach the native debugger to whatever process is running that native code. Probably after you've set up the java based debugging session appropriately.
In the past when doing JNI I have built a test-harness to facilitate the development of the native part of the application - and JNI code - which is notorious easy to screw up, avoiding the need to debug simultaneously from both sides.
This was written as a native application that invokes the JVM programmatically rather than starting with a Java application and then attempting to attach to JVM.
You can of course, start this and debug it in Xcode - which is an infinitely preferable experience to Eclipse with CDT.
The Java side of this arrangement is usually pretty simple and non-contriverial - basically a method which is called from the native part of the app that then makes one or more calls back into the native portion through JNI.
Here are the steps I follow to debug JNI (C/C++) under Windows, I presume ObjectiveC need the same. For Linux it's very similar (replace ; by :, %XXX% by ${XXX}...).
Create a file named MyDebug.gdbinit
Add these 4 lines into it:
set args -classpath .;xxxx.jar;yyy.jar path.to.your.Main
show args
run
bt
launch gdb and Java: gdb "%JAVA_HOME%\bin\java"
Use the GUI of the Java layer to reproduce the error
If you want to execute step by step your JNI code, gdb allows you to put some breakpoints