Compile linphone for Android

Compiling linphone has always been a challenge for me. Even after following the README down to each letter, I always get errors. Compiling linphone for Android is no difference.

So I followed the README, got everything installed, and did make.

And I ended up with numerous such errors:

Fatal error: invalid -march= option: `armv5te'

After a while, I figured out that it was caused by failure in cross compilation. So linphone uses a lot of libraries written for intel (desktop) processors. Those libraries need to be cross compiled for ARM. I failed at this stage.

So to summarize, the following are the steps needed to compile linphone for Android. These steps are taken from the README, with my comments inside the parentheses.
(My OS is Ubuntu 12).

0) download the Android sdk with platform-tools and tools updated to latest revision (at least API 16 is needed), then add both 'tools' and 'platform-tools' folders in your path.
1) download the Android ndk (>=r8b) from google and add it to your path.
2) install the autotools: autoconf, automake, aclocal, libtoolize pkgconfig (On my Ubuntu, aclocal is part of automake. pkgconfig is in a package called pkg-config and already installed. libtoolize is in a package called libtool. So actually I had to: sudo apt-get install automake autoconf libtool)
3) install the code sourcery toolchain. This step is crucial as the toolchain is needed for succesful cross compilation. This step is not mentioned in the README!!!!

So to install the sourcery toolchain, do these steps:
1. Get the binary from sourcery.mentor.com. Get the binary for Linux, not the source, to save you from compilation headache. The filename is: arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2. You have to register, agree to some formalities, and then download it.
2. Unzip it. Preferable to a subdir inside the /opt dir to make it look pro.
3. Add path to the bin directory inside the unzipped directory to your path.

And then, done. Follow the readme to make and make install and you'll compile with success.

Installing Java on Ubuntu

I still remember how *gruesome* it was to install or update Java on Ubuntu. I wrote it somewhere in earlier post. Fortunately now with Ubuntu 12.10, an easier method (a ready to execute script) is available:

First you need to remove openjdk for this run the following command from your terminal
sudo apt-get purge openjdk*
If you installed java 7 from any other PPA and you are having problem with java then you have to do following steps before installing the PPA menctioned here
sudo rm /var/lib/dpkg/info/oracle-java7-installer*
sudo apt-get purge oracle-java7-installer*
sudo rm /etc/apt/sources.list.d/*java*
sudo apt-get update
Install oracle java 7 in ubuntu 12.04
Open the terminal and run the following commands
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

http://www.ubuntugeek.com/how-to-install-oracle-java-7-in-ubuntu-12-04.html

ADB not recognized on newly installed Ubuntu 12.10

I just installed latest Ubuntu (12.10) on my office computer running Win 7. Problems soon appear.

The first is that from time to time the desktop became totally unresponsive. Paralyzed. I had to wait for a few minutes until my mouse clicks did anything at all.
After looking at top, I found out that the process mount.ntfs occupied 100% of CPU. So I got windows partition mounted and Ubuntu was doing something to it that hogged the resources. I don't know how to solve this... I installed this Ubuntu from Windows initially.

And then I needed to put Eclipse to the Unity launcher. Unity launcher is a vertical container of icons on the left side of the desktop, as in following picture:

How: 
1. Create a file with .desktop extension, containing info like this:

[Desktop Entry]
Version=
Name=Eclipse
Comment=
Exec=/home/switchlab/Documents/bin/eclipse/eclipse
Icon=/home/switchlab/Documents/bin/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=Application;

2. Put it in /usr/share/applications
3. In Dash Home, search for Eclipse and then drag and drop it to launcher.

I installed Android SDK, but then I failed to run adb eventhough I got it on my PATH. The error message said: No such file or directory. This is very weird. I checked that the adb did exist in platform-tools. So why this message? 

It turned out that this is caused by a glitch on my Ubuntu 64 bit installation. I had to do:
sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install ia32-libs

and everything worked fine again. I still haven't got a clue what that command does. Anyway, thanks goes to Scotty Delicious who wrote it here: http://askubuntu.com/questions/219465/cannot-install-ia32-lib-package

Objective C memory management

After a while finally (I think) I grasp how this memory management thing works in Objective C.

First about assign and retain.

When you declare properties using (retain) then the retain count will be incremented by one when you assign value to it.

@interface LayerA : CCLayer{

   CCSprite *sprite;
}

@property (retain) CCSprite *sprite;
@end

Now if in other classes you call:

LayerA.sprite = [CCSprite node];

The retain count of sprite in LayerA will be incremented by one and as such, it won't be released until you call:

LayerA.sprite = nil;

which will decrease the retain count by one. So everytime you assign a value to a retain property, you must have a matching nil assignment to it.

This can complicate manual memory management and I usually prefer to have assign instead of property.


@interface LayerA : CCLayer{

   CCSprite *sprite;
}

@property (assign) CCSprite *sprite;
@end

Now when you assign a value to the sprite property, the retain count will not be incremented.

Another case about memory management that I learnt the hard way was when passing argument to the class constructor.

When class A calls the constructor of class B and passes parameters, the parameters will be released when class A is released. So if class B caches those parameters, it is good only as long as class A lives. The constructor in class B needs to make deep copy of the parameter if class B wants to use the parameters in methods other than constructor.

Box2D weld joint

So one might think this is the simplest joint, but it turns out there are so much subtlety into it. After a gruesome few days of trying to figure out what went wrong with my weld joint, finally I (think I) get a good grasp of it.

Let's start with the basic:

There are 3 major components with joints.
1. The reference body. This is the body that goes first in the b2JointDef.Initialize method. The reference is the body to which the joint is attached.
2. The target body. This is the body that goes second in the b2JointDef.Initialize method. The target body is the attached body. So the movement of the target body follows that of the reference body.
3. Anchor. Where to attach the target body to the reference body. This is a b2Vec2 coordinate relative to the reference body.

i.e:

b2WeldJointDef.Initialize(refBody, targetBody, b2Vec2(-5, 10));

The target body will be glued to the reference body at -5, 10 from the ref body position.

As for the weld joint, one must define the following for it to work:


    bodyDef.fixedRotation = FALSE;
    fixDef.density = 2.0f;


Basically one must define the density and set fixedRotation to false. Otherwise, the weld joint will fall off. The bodies glued together using weld joint must also be large enough. There will be an area check somewhere inside the Box2D engine to make sure that areas joined exceed a certain delta value!

Apple Code Signing

I was just released from being mired in litany of predicaments due to code signing procedures and here's my story...

So I work on a new macbook, someone else's, and i fail to code sign my app before deploying it to my device.

After two days I finally figured it out. (or better put: people sharing their knowledge on internet got it figured out).

Basically, code signing process is following:

You need to have the following in your computer when code sign:
- public and private key pair.
- certificate issued by you (if you are administrator of your Apple developer program)
- Apple intermediate certificate.

You got to have public and private key for code signing. This pair is created on your computer when you created certificates and provisioning profile FOR THE FIRST TIME. If you move development to other machine, you will have to do something to move this pair to the new machine.... The easiest way would be to re-create everything from scratch: delete your certificate in developer.apple.com and recreate it by submitting new certificate request from keychain.

If you develop on a new machine, the private key is usually missing. You can tell by going to the keychain. Your certificate should have a little triangle next to it, that you can click and it will show you the public and private key pair. If you don't have that triangle, you have the certificate but not the key pair and your code signing won't work.

The intermediate certificate can be downloaded from the the usual place in developer site without having to submit certificate request first. If you don't install this, you'll get this error from XCode: /usr/bin/codesign fail or something similar.

Code signing is one part. Then there's this thing called provisioning profile which basically says which certificate to sign which app and which app can be deployed on which device...

Er... I'm unsure. But that's my impression of two days fixing code signing error.

One more thing, I deleted all passwords in keychain because I used my own apple credential in XCode automatic refresh and now I wanted to use someone else's. I couldn't find the right password for XCode in keychain so I deleted them all. .-))
It worked. I was asked to enter new credential when I clicked refresh in XCode organizer. But another problem arose: When I created certificate request it gave me errors like incorrect passphrase or something. I could not create certificate request because I deleted all of my passwords! Solution is simple: restart the computer!

InnoDB status, altering table by dropping foreign key column

So if you have a table, say Kinerja, that has a foreign key column, say NIP. And you need to alter that table by dropping the column, you can't just do:

alter table Kinerja drop column NIP;

It will spit errno 150 at ya.

You need to first drop the foreign key constraint pertinent to the said column, such as:

alter table Kinerja drop foreign key the_constraint_of_NIP_column_here;

After that is done, you can do:

alter table Kinerja drop column NIP;

But how to get the constraint? Well, just do:

alter table Kinerja drop column NIP;

first to get error. And then, look up the innoDB log by issuing:

show engine innoDB status;

In the log, find this paragraph:


------------------------
LATEST FOREIGN KEY ERROR
------------------------
121211  0:16:23 Error in foreign key constraint of table penilaian/kinerja:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT "kinerja_ibfk_2" FOREIGN KEY ("NIP") REFERENCES "dosen" ("NIP")


There, you have the constraint! :p

Then, do delete the constraint and then the column.