Wednesday, July 18, 2012

Fixing dyld image not found on Mac OS

If you've every used command line process and wanted to relocate it you may have run into the error:

dylib: Library not found:
....
Reason: image not found

You can fix this by doing the following:

  1. Figure out what libraries are dynamically linked to the process using:
    • otool -L process_name
    • Note: You may have to do this for each dynamic library as well and change the paths for the libraries in the dynamic libraries you are linking into your process.  As you can tell this can result in a lot of changes but if you want to move stuff to a new location, it's your best option, as compared to building from source all the required libraries and process.
  2. Change the path of those dynamic libraries using:
    • install_name_tool -change old new process_name
UPDATE:

While relocating the library paths for the library I was working with I came up with a pattern of steps to fix this:

Run: otool -L .dylid For example:

otool -L libintl.8.dylib
libintl.8.dylib:
/opt/local/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.1.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 635.19.0)
 Then notice that we want to change /opt/local/lib/ to /mypath/lib/.  To do that you need to run:
install_name_tool -change /opt/local/lib/libintl.8.dylib /mypath/lib/libintl.8.dylib /path/to/libintl.8.dylib

This works great until you run into this error:

install_name_tool: changing install names can't be redone for: /mypath/lib/libintl.8.dylib (for architecture i386) because larger updated load commands do not fit (the program must be relinked)
[Reference: http://annoyingtechnicaldetails.wordpress.com/2007/04/18/install_name_tool-changing-install-names-cant-be-redone-for-for-architecture-ppc-because-larger-updated-load-commands-do-not-fit-the-program-must-be-relinked/]
To fix this you need to recompile the library with options to enable the relocation of the library paths.  If the library uses configure then chances are you can add these options to the configure to make it build such that the path for the libraries are relocatable:

  1. Add this to your LDFLAGS=-headerpad_max_install_names
  2. And if available use the configure options: --disable-rpath --enable-relocatable Reference[http://www.manpagez.com/info/relocatable/]
  1. So for example here is an example for libiconv:
./configure --prefix=/mypath/ --disable-rpath --enable-relocatable LDFLAGS=-headerpad_max_install_names


Sunday, July 8, 2012

Change Apple Logo on your Mac in Lion

On Mac OS X Lion, you can change the Apple logo to your own logo.  Let's do that now.  Here's a BB logo we want to use:

Grab the file and copy it to your system (let's say /Users/YOUR_USER_NAME/Downloads/BBRocks_256x256.png).

Then open Terminal and type the following to backup the original file:

sudo cp /System/Library/PrivateFrameworks/LoginUIKit.framework/Versions/A/Frameworks/LoginUICore.framework/Versions/A/Resources/appleLinen.png ~/Desktop/

And then this to copy over the Apple logo with your new logo:

sudo cp /Users/YOUR_USER_NAME/Downloads/BBRocks_256x256.png /System/Library/PrivateFrameworks/LoginUIKit.framework/Versions/A/Frameworks/LoginUICore.framework/Versions/A/Resources/appleLinen.png

Since you are running sudo, you will have to enter your password.  This is due to the fact you are copying over the original file which is owned by root.

Now your login window should look like something like this:

Friday, June 22, 2012

Xcode 4, I love you but why do you treat me this way?

When you work on legacy systems (ya, I am calling 10.5 and 10.6 legacy, get over it) you have to work with older dev tools.  So, using Xcode 4 has been something I have only done occasionally in my spare time and when writing prototype code.

Production has been Xcode 3.x until recently.

Sweet, I get to go to the new (ok old) hotness.  So Xcode 4.3.3 we meet.

As first, there were some early courtship fumbles as we got to know each other.  But now I feel like we've been together for a few months, I know where you like to store your derived data, and you know I a fanatic about build clean, build.

But why do you have to keep springing these crazy fits on me.  I mean I try simple things and you just disappear.  Sometimes a simple, sorry, I'll try again is not enough.

Sometimes I have to say, ok, let's start over baby.  I'll just reboot and then it will be like we just met again for the first time.

E...
x...
c...
e...
p...
t...

it's not the first time.

You have a memory like an elephant.

Why just tonight when I opened a project in the wrong folder (it's my Perforce workspace I am using as the backing store for my git-p4 repo, don't ask) you just wouldn't let it go?  I mean, I know, I am sorry.  I said p4 instead of git.  WRONG FOLDER!  My fault!  Let it go!

Then to mess with me, after I restart again, you open the wrong project again without my noticing.  I know, the name was git not p4.  So you get even by launching the git version underneath the p4 version; with the windows aligned perfectly.

What's a guy have to go to get you to forget my mistake?

It's ok, I didn't mean it.

Let me restart you again.

Sunday, February 12, 2012

Making the Leap to Music on BlackBerry

Disclaimer

So you bought a PlayBook on a screaming deal.  Excellent, and thanks, I work at BlackBerry and appreciate your faith in us.  Like you I am a user of BlackBerry products as well and I work with Media (specifically Media syncing).  I write this blog post from the point of view of a BlackBerry user, not an employee, so don't take this as official from Research In Motion (the makers of BlackBerry).

Purchased Music and Your PlayBook

Perhaps like me you have been using iTunes for years to purchase music.  iTunes has been a great source of content as I have moved from physical media to digital content.  I won't talk about the BlackBerry options for syncing your iTunes library to your PlayBook but take a look at the BlackBerry Desktop Software if you'd like to do this.

What I want to talk about today is making the leap to purchasing music on your BlackBerry PlayBook and show you how easy it is to do.

First, swipe up your PlayBook and go to the Music Store app.

Next register a new account (and your credit card with 7 Digital) if you need to, or login to your account.  To get to your account swipe down to get to the "Options".

Purchase some music and you are done for purchasing music.

ReDownloading My Music Later (ie. Do I lose my music if my PlayBook gets wiped?)

Ok, easy, but let's talk about losing your music.  Like what if you had to reset your PlayBook.  Losing Music is not Cool!  (Note, I have never had to reset my PlayBook, I am just using it as an example, I could also say what if it was stolen, lost, you bought a 2nd BlackBerry, etc.)

No problem.  When you are your PlayBook setup after wiping it, or maybe after setting up your 2nd PlayBook, let's get your Music back onto your PlayBook.

Open the Music Store again.


Now choose the "My Purchases" tab to see your past purchases:

Cool, there's your Music.  Let's select my Flash Gordon soundtrack...

"Flash Ah AH...Savior Of The Universe!"....ah, sorry, where were we.  Right, downloading my previously purchased music.

This being Flash let's download the entire album by selecting the Download button under the artwork.

Sweet, here comes Flash.

What if I have a 2nd Device like another PlayBook or a BlackBerry Bold?

No problem.  On the 2nd PlayBook:
  • Do the above.
On the BlackBerry Bold (or Curve or any BlackBerry that has the 7 Digital Music Store App):
  • If the 7 Digital App is not installed on your phone, go to the App World app and search for 7 Digital.
  • Download the app.
  • Setup your 7 Digital account.
  • Download you music.
Purchasing and using music on your BlackBerrys is easy and you can rest assured that you can get your music later when you want it on a new device.


Read More About

Friday, December 30, 2011

Setting the Serial Port of a OSEPP Uno On Mac OS X Lion

I am new to Arduino hacking and as such I installed the latest Arduino software that comes without the need to install separate USB drivers, ie. the FTDIUSBSerialDriver_10_4_10_5_10_6.mpkg file with older Arduino software installs for Mac.

I am on Mac OS X 10.7 (Lion) as well.

So, when I hooked up a second Arduino board I bought yesterday, an OSEPP Uno Rev 1.1, I could not load sketches onto it.

I went to the getting started website for the OSEPP Uno, which suggested setting the board to an “Arduino Duemilanove or Nano w/ ATmega328″ to get it to work. Still nothing.

I looked at the Serial Ports but there were no usbserial ports listed. So, start debugging. I opened the Console and tried unplugging/plugging in the board, sure enough there was an error:

kernel: 0 0 AppleUSBCDC: start - initDevice failed


So, rereading the getting started site, I released that since this board was a little older I might just need to the older drivers.

I downloaded the Arduino 0023 drivers from the Arduino Software page for Mac OS X. I installed just the FTDIUSBSerialDriver_10_4_10_5_10_6.mpkg file.

Restart the Arduino IDE and voila, there should not be a /dev/tty.usbserial-* device that will be the OSEPP Uno board. You can then load your programs.

Hope that helps.

Friday, November 18, 2011

Configuring the liboauth C Library for PlayBook

Overview



You've decided to write a PlayBook App with the NDK (Native Development Kit). That's awesome, let's learn how to port an OSS library you want to use in your new app.

For those of you who are ./configure experts, please point out anything I have wrong or maybe could do differently which might make this easier.

Ok so first off, I am not a ./configure expert but I am perfectly willing to beat my head against the compiling and linking wall until I get something that works.

Some prerequisites:
  • I am on a Mac, switching between a Snow Leopard and a Lion box. So this should work for either. If you are on Windows, please feel free to fork my post and write up how you did this on Windows. If you do, then please refer back here for the Mac Devs who find your site.
  • I expect that you have installed the BlackBerry Tablet OS NDK in the default locations.
  • I am using 2 PlayBooks for testing. One running 1.0.7 and one running 2.0. You can expect this to work for either, if not let me know and I will verify that it is working no the latest OS.
  • You know what the Terminal.app is and aren't afraid to use it.
Let's get started.

Porting liboauth (http://liboauth.sourceforge.net/)

I choose liboauth since it involved the least amount of work for the library's I have been working with. I built liboath-0.9.4 for PlayBook. I only built the device (arm) version since I am not using the simulator; I like to test on the metal; but with some minor variations to the options it should not be hard to get a simulator compatible version built.

First: Set the environment for building

To do this source the NDK included environment script:
source /Developer/SDKs/bbndk-1.0/bbndk-env.sh
This should setup your environment for the QNX compiler so we can build for the PlayBook. Here is what that looks like (at time of writing):
QNX_TARGET="/Developer/SDKs/bbndk-1.0/target/qnx6"
QNX_HOST="/Developer/SDKs/bbndk-1.0/host/macosx/x86"
QNX_CONFIGURATION="/Users/YOUR_USERNAME_HERE/Applications/Library/Research In Motion/BlackBerry Native SDK"
MAKEFLAGS="-I$QNX_TARGET/usr/include"
DYLD_LIBRARY_PATH="/Developer/SDKs/bbndk-1.0/host/macosx/x86/usr/lib:$DYLD_LIBRARY_PATH"
PATH="$QNX_HOST/usr/bin:$QNX_HOST/usr/qde/eclipse/jre/bin:$PATH"
export QNX_TARGET QNX_HOST QNX_CONFIGURATION MAKEFLAGS DYLD_LIBRARY_PATH PATH

Second: Modify the config.sub to include the CPU instruction set for ARMv7

When we set the target and host in the ./configure command we will be using the PlayBook CPU type of armv7, we will need to add that to the config.sub since it is missing from liboauth's config.sub. I did this by searching for armv, where you will find and switch out the line shown in the following diff, notice I just added 7 into the armv[2345] statement:
diff --git a/config.sub b/config.sub
index c2d1257..dd4ef08 100755
--- a/config.sub
+++ b/config.sub
@@ -249,7 +249,7 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[23457] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
Sidetrack: If you want to look at some more details on the CPU, check out http://en.wikipedia.org/wiki/Texas_Instruments_OMAP

Third: Run ./configure with some options

Here is the ./configure I used. I included the OpenSSL and the Curl libraries.
./configure CXX="QCC -V4.4.2,gcc_ntoarmv7le_cpp" CC="qcc -V4.4.2,gcc_ntoarmv7le" --prefix=$PWD/playbook NM=ntoarmv7-nm RANLIB=ntoarmv7-ranlib STRIP=ntoarmv7-strip AR=ntoarmv7-ar LD=ntoarmv7-ld LDFLAGS="-L/Developer/SDKs/bbndk-1.0/target/qnx6/armle-v7/usr/lib/" CURL_CFLAGS="-DFD_SETSIZE=64 -g -O2" CURL_LIBS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" --build=i386-apple-darwin11.2.0 INCLUDES="/Developer/SDKs/bbndk-1.0/target/qnx6/armle-v7/usr/include" --target=armv7-nto --host=armv7-nto
If the above worked then great, you can now run make, else, you will need to try to debug the problem with your environment/configuration.

Fourth: Run make

Run make and then make install to install into the path we chose in our configure statement which was set with the --prefix=$PWD/playbook. What is $PWD, it is the environment variable for the directory you are building the library within. Basically, the make install will make a new directory called playbook and place all the built artifacts into that directory.

Lastly: Pull liboauth into your project

I'll leave that for the user to work out but here is a sample liboauth on BlackBerry PlayBook qde project on github that has the built library and the test/selftest_wiki.c file renamed to main.c included to verify that the library is working.

Finishing



With a little tweaking of the ./configure, porting an OSS project to the PlayBook is not to hard. When you run into compiler issues the story can be a little different (read, lots of hair pulling) but is not insurmountable.

Good luck with your app!

Friday, August 19, 2011

OCMock observerMock and unrecognized selector


I've been writing lots of unit tests for some new classes that use process wide NSNotifications.  I wanted to test these since I have not written NSNotification code often and this is a base class that a lot of future code is going to be built upon.

A handy way to test these are to use OCUnit with OCMock to create mock observers to verify that your notifications are being called.  Many others have talked about how to setup OCUnit, OCMock, and do Unit Testing in Xcode so I won't go there.

One article that did help me out with the OCMock observerMock usage was Alex Vollmer's Making Fun of Things with OCMock.  I used his example to build upon to write my mock observer tests.

I did run into a problem though while testing.  A test for a notification, let's call it MyCoolNotification, would pass and then a second test that tested this notification would fail.  The weird thing if I would see failures like:
  • [NSCFString handleNotification:]: unrecognized selector ...
  • [NSCFNumber handleNotification:]: unrecognized selector ...
These failures would be for the same call, same line of the test, but on different runs I would get different classes throwing exceptions due to the unrecognized selector.  What to do?

I put it together when I noticed the pattern, that the first test of usage of MyCoolNotification would pass but the second and remaining would fail.

The examples of the usage of [OCMockObject observerMock] left out one important NSNotification item.  Once you finish your test, don't forget to remove your mock from observing the notification.

Here is a more complete example of that I am talking about:
- (void)test_MyCoolNotification {
  id mock = [OCMockObject observerMock];
  [[NSNotificationCenter defaultCenter] addMockObserver:mock
                                                   name:MyCoolNotification
                                                 object:nil];
                                               
  [[mock expect] notificationWithName:MyCoolNotification object:[OCMArg any] userInfo:[OCMArg any]];

  MyCoolClass *coolio = [MyCoolClass create];
  [coolio someMethodThatFiresMyCoolNotification];

  [[NSNotificationCenter defaultCenter] removeObserver:mock];
  [mock verify];
}

By adding the removal of the object from the NSNotificationCenter you can now test the notification multiple times in multiple tests.