Thursday, January 24, 2013
Moving...
My life has changed upside down recently: I have been accepted to Saarland University Graduate School and I will move to Germany soon. I will try to keep this updated as possible.
Thursday, November 29, 2012
LLVM - ARM cross-compilation using Raspberry!!
Well, a short break on continuous integration posts!
I bought my Raspberry Pi (http://www.raspberrypi.org/) board some weeks ago mainly to use it as a developer board (pretty affordable and efficient). So, I decided to use it to cross-compile LLVM (http://www.llvm.org).
So, here you go.
Building
First of all, download LLVM (from either SVN or GIT repositories). I got the following information from LLVM documentation. For more details, check this out!
To cross-compile it to ARM platform, you need a toolchain. I use Sourcery G++ Lite 2011.03-41 (MentorGraphics Sourcery CodeBench Lite Edition) - it is free and contains everything we need. Install it and also remember to set the PATH variable so that you can use your toolchain.
Now, you just need to wait for a couple of minutes :-) Next step is NFS-mounting the LLVM dir in your Raspberry Pi.
NFS-Mounting
Now, LLVM is cross-compiled and we are able to use it and perform some tests on Raspberry Pi. I prefer NFS as partition mounting solution. An important information is that you have to have the same path on both environments (desktop and remote). It means that if you are building LLVM on /home/user/llvm desktop folder, you have to mount it on /home/user/llvm remote folder (in most of cases, you have to create the user on your Raspberry environment - just use the command). Firstly, set up your desktop machine:
Configuration on Raspberry Pi is also straightforward:
Testing
I bought my Raspberry Pi (http://www.raspberrypi.org/) board some weeks ago mainly to use it as a developer board (pretty affordable and efficient). So, I decided to use it to cross-compile LLVM (http://www.llvm.org).
So, here you go.
Building
First of all, download LLVM (from either SVN or GIT repositories). I got the following information from LLVM documentation. For more details, check this out!
- Checkout LLVM:
$ cd where-you-want-llvm-to-live
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
- Checkout Clang:
$ cd where-you-want-llvm-to-live
$ cd llvm/tools
$ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang - Checkout Compiler-RT:
$ cd where-you-want-llvm-to-live
$ cd llvm/projects
$ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt - Get the Test Suite Source Code [Optional]
$ cd where-you-want-llvm-to-live
$ cd llvm/projects
$ svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite
To cross-compile it to ARM platform, you need a toolchain. I use Sourcery G++ Lite 2011.03-41 (MentorGraphics Sourcery CodeBench Lite Edition) - it is free and contains everything we need. Install it and also remember to set the PATH variable so that you can use your toolchain.
$ export $PATH=$PATH:/home/user/CodeSourcery/Sourcery_G++_Lite/binNow, it´s time to build the application (and remember: for further details, check this out!)
$ cd where-you-want-to-build-llvm
$ mkdir build (for building without polluting the source dir)
$ cd build
$ ../configure --target=arm-none-linux-gnueabi --host=arm-none-linux-gnueabi --enable-optimized (the target/host value may change depending on the toolchain that you have chosen.)
$ make
Now, you just need to wait for a couple of minutes :-) Next step is NFS-mounting the LLVM dir in your Raspberry Pi.
NFS-Mounting
Now, LLVM is cross-compiled and we are able to use it and perform some tests on Raspberry Pi. I prefer NFS as partition mounting solution. An important information is that you have to have the same path on both environments (desktop and remote). It means that if you are building LLVM on /home/user/llvm desktop folder, you have to mount it on /home/user/llvm remote folder (in most of cases, you have to create the user
- Install NFS packages
@desktop$ sudo apt-get install portmap nfs-kernel-server nfs-common - Edit /etc/exports and add the following line
/home/user/llvm 192.168.1.0/24(rw,sync,no_subtree_check) - Restart NFS system
@desktop$ sudo service nfs-kernel-server restart - Change access permission of your shared folder (in this case, I use the same folder)
@desktop$ chmod -R 777 /home/user/llvm
Configuration on Raspberry Pi is also straightforward:
- Install NFS packages (most of Raspberry distributions contain NFS installed, so maybe this step is not necessary)
@remote$ sudo apt-get install portmap nfs-kernel-server nfs-common - Create the host folder
@remote$ mkdir llvm
@remote$ chmod 777 llvm - Mount the NFS-shared folder
@remote$ sudo mount 192.168.1.4:/home/user/llvm /home/user/llvm
Now it is done and you can use your cross-compiled LLVM on your Raspberry.
Testing
Let´s now focus on LLVM tests and how we can run them on ARM platforms. In this case, I am running tests under /home/user/llvm/tests folder.
After some minutes, LLVM test suite runs all integration tests and provides a report with results.
the ARM target platform for LLVM project at this moment. If you want to contribute to LLVM project by supporting ARM features, check a PandaBoard development kit.
- CD to test dir
@remote$ cd llvm/build/test - Run tests
@remote:/home/user/llvm/build/test$ make
After some minutes, LLVM test suite runs all integration tests and provides a report with results.
@remote:/home/user/llvm/build/test$ makeUPDATE: Raspberry Pi
...
PASS: LLVM :: ExecutionEngine/MCJIT/test-shift.ll (59 of 59)
Testing Time: 11.65s
********************
Unexpected Passing Tests (1):
LLVM :: ExecutionEngine/MCJIT/test-data-align-remote.ll
********************
Failing Tests (7):
LLVM :: ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll
LLVM :: ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll
LLVM :: ExecutionEngine/MCJIT/fpbitcast.ll
LLVM :: ExecutionEngine/MCJIT/pr13727.ll
LLVM :: ExecutionEngine/MCJIT/test-call.ll
LLVM :: ExecutionEngine/MCJIT/test-common-symbols.ll
LLVM :: ExecutionEngine/MCJIT/test-ret.ll
Expected Passes : 45
Expected Failures : 6
Unexpected Passes : 1
Unexpected Failures: 7
Wednesday, November 28, 2012
Setting up your Continuous Integration environment - Part I
Continuous Integration is such a great idea: it works as a trainee that constantly downloads/builds/tests/deploys you application and notifies you whether something goes wrong or nice. I really do believe that (of course, besides several other advantages) it improves the project overall quality and also helps you to keep the application ready to be reviewed by a stakeholder.
If you are still skeptical about it, please take a look that this marvelous post here [Martin Fowler] .
Let´s discuss how you can set up a environment for a more complex project. So, unfortunately, this is tutorial for beginners (for basic/how-to-install-and-run instructions, check it on internet).
Introduction
The system consists of one server located in a external environment (for example, AWS services) and several mobile clients (iOS, Android and QT clients). Basically, the mobile applications fetch content/data from the server.
We need to constantly build/deploy the server and build all mobile clients. One very interesting point in this scenario is the amount of platforms: iOS (to build iOS client), Linux (to build Android/QT client - I´d rather use Linux for Android projects) and Windows (to build the server).
Besides svn checking-out + building + testing + deployment, we will also use QA solutions, such as Sonar and some static analysis tools for different platforms.
We will use Jenkins as CI server.
Proposed design
As I said, the system consists of several components: mobile clients (iOS, Qt and Android) and also servers. In this case, I´d rather use master-slave approach. You can create one slave for each mobile platform and also another one for for servers. To the given example, the solution is defined as it follows:
You might ask me why this is too complicated! But believe on me. If you have complex systems to build, this approach works a lot better: it´s easier to organize and to maintain, and each component on its own environment. In my next post, I describe how we set up all of this :-)
If you are still skeptical about it, please take a look that this marvelous post here [Martin Fowler] .
Let´s discuss how you can set up a environment for a more complex project. So, unfortunately, this is tutorial for beginners (for basic/how-to-install-and-run instructions, check it on internet).
Introduction
The system consists of one server located in a external environment (for example, AWS services) and several mobile clients (iOS, Android and QT clients). Basically, the mobile applications fetch content/data from the server.
We need to constantly build/deploy the server and build all mobile clients. One very interesting point in this scenario is the amount of platforms: iOS (to build iOS client), Linux (to build Android/QT client - I´d rather use Linux for Android projects) and Windows (to build the server).
Besides svn checking-out + building + testing + deployment, we will also use QA solutions, such as Sonar and some static analysis tools for different platforms.
We will use Jenkins as CI server.
Proposed design
As I said, the system consists of several components: mobile clients (iOS, Qt and Android) and also servers. In this case, I´d rather use master-slave approach. You can create one slave for each mobile platform and also another one for for servers. To the given example, the solution is defined as it follows:
You might ask me why this is too complicated! But believe on me. If you have complex systems to build, this approach works a lot better: it´s easier to organize and to maintain, and each component on its own environment. In my next post, I describe how we set up all of this :-)
Friday, October 26, 2012
Back!!!
After a loooong break, I am back to this. I have to confess that I had had several new/cool stuff during this pause: new projects, mind-blowing findings, exciting/stressful experiences, lovely/irritating people. And all of this had consumed a lot of my free time. I am not saying that I hadn´t had time at all: I had done some new/different things with such slots of time than only writing about technical stuff.
Well, but anyway, let´s keep track of new stuff. The main reason to start blogging again was the simply fact that I am not used to describe all solutions for tricky problems in general: how to cross-compile certain applications for ARM devices, how to set up a smart CI environment, and so forth. I swear I have tried it really hard, but my evil side always tells to myself: "if you need it some other day, you will remember it". So, this is also a kind of "Raul´s Recipes Book".
I am really convinced that it will work :-)
As part of my next posts, I will describe a bit more about how lovely is a CI environment for a relative huge project (of course, how you can set up all of this and put the pieces together). Specially, when it has such different clients, such as iOS, Android and QT applications.
Thursday, November 18, 2010
DBus - How to pass dict as parameter
This tutorial is designed for those ones that need DBus but suffer a lot to find documentation even about simple things, such as how to pass a dictionary as parameter.
Initially, I had to invoke a Bluez method that needs a dictionary as parameter. But how could I do it? It not easy at all to find a detailed documentation about it and I had to look for a solution at BlueZ source code.
In this case, I'm using the newest BlueZ Health API (support for HDP/MCAP). The following piece of code shows
A DBus dict type needs a message iterator, which is properly initialised before it is used.
Once the message iterator is properly created, let's open it and add tuples to it.
At first, you have to open the container and specify the data type of each tuple. In this case, the dictionary consists of tuples <"DataType",uint16>, <"Role",string>, <"Description",string>, and <"ChannelType",string>. Once the value data type for each tuple varies (uint16 or string), we declare it as a variant. Therefore, the dictionary data type definition is:
Finally, you simply add the basic data type to message iterator (the dictionary itself).
Initially, I had to invoke a Bluez method that needs a dictionary as parameter. But how could I do it? It not easy at all to find a detailed documentation about it and I had to look for a solution at BlueZ source code.
In this case, I'm using the newest BlueZ Health API (support for HDP/MCAP). The following piece of code shows
static char *start_health_session(DBusConnection *conn)
{
DBusMessage *msg, *reply;
DBusMessageIter args;
DBusError err;
const char *reply_path;
char *path;
msg = dbus_message_new_method_call("org.bluez",
"/org/bluez",
"org.bluez.HealthManager",
"CreateApplication");
if (!msg) {
printf(" network:dbus Can't allocate new method call\n");
return NULL;
}
// append arguments
dbus_message_iter_init_append(msg, &args);
if ( !iter_append_dictionary(&args, DATA_TYPE_VALUE,
ROLE_VALUE,
DESCRIPTION_VALUE,
CHANNEL_TYPE_VALUE) ) {
printf(" network:dbus Can't append parameters\n");
dbus_message_unref(msg);
return NULL;
}
dbus_error_init(&err);
....
}
A DBus dict type needs a message iterator, which is properly initialised before it is used.
Once the message iterator is properly created, let's open it and add tuples
static int iter_append_dictionary(DBusMessageIter *iter,
dbus_uint16_t dataType,
const char *role,
const char *description,
const char *channelType)
{
DBusMessageIter dict;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
dict_append_entry(&dict, "DataType", DBUS_TYPE_UINT16, &dataType);
dict_append_entry(&dict, "Role", DBUS_TYPE_STRING, &role);
dict_append_entry(&dict, "Description", DBUS_TYPE_STRING, &description);
dict_append_entry(&dict, "ChannelType", DBUS_TYPE_STRING, &channelType);
dbus_message_iter_close_container(iter, &dict);
}
At first, you have to open the container and specify the data type of each tuple. In this case, the dictionary consists of tuples <"DataType",uint16>, <"Role",string>, <"Description",string>, and <"ChannelType",string>. Once the value data type for each tuple varies (uint16 or string), we declare it as a variant. Therefore, the dictionary data type definition is:
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
Finally, you simply add the basic data type to message iterator (the dictionary itself).
static void append_variant(DBusMessageIter *iter, int type, void *val)
{
DBusMessageIter value;
char sig[2] = { type, '\0' };
dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
dbus_message_iter_append_basic(&value, type, val);
dbus_message_iter_close_container(iter, &value);
}
static void dict_append_entry(DBusMessageIter *dict,
const char *key, int type, void *val)
{
DBusMessageIter entry;
if (type == DBUS_TYPE_STRING) {
const char *str = *((const char **) val);
if (str == NULL)
return;
}
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
append_variant(&entry, type, val);
dbus_message_iter_close_container(dict, &entry);
}
Monday, August 16, 2010
CUnit on ARM platforms.
Let's use this stuff :P Anyway, it's a good tool and I need to put some ideas anywhere.
So, today's tip is how to compile your CUnit tests on Embedded platforms - in this case, on a N900 (ARM) with MeeGo installed on it.
You should download the CUnit source code from http://sourceforge.net/projects/cunit/ (I only tested versions 2.0.X and 2.1.X). The process is very simple: download the code, copy to your development environment, and build it (./bootstrap && make). However, things are not soooo easy as it seems :P
Probably, you'll face problems at initial steps.
If you have any problems on , execute the following command to change modification time/time:
It seems to work.
So, today's tip is how to compile your CUnit tests on Embedded platforms - in this case, on a N900 (ARM) with MeeGo installed on it.
You should download the CUnit source code from http://sourceforge.net/projects/cunit/ (I only tested versions 2.0.X and 2.1.X). The process is very simple: download the code, copy to your development environment, and build it (./bootstrap && make). However, things are not soooo easy as it seems :P
Probably, you'll face problems at initial steps.
If you have any problems on , execute the following command to change modification time/time:
find /path/to/files -exec touch {} \;
It seems to work.
Tuesday, August 11, 2009
Give us your opinion!
IDE Integration 2nd edition is comming soon, including new PluThon Eclipse product. It comes with new and interesting features, such as ltrace integration. However, we know that Maemo community has a lot of valuable feedback and ideas that certainly improves PluThon and any other IDE Integration components (ESbox, PC Connectivity, etc.)
Please, visit PluThon 2nd edition web site, check how features you´d see implemented on PluThon and provide a feedback to eclipse-integration AT maemo DOT org. Your comments are welcomed!
Please, visit PluThon 2nd edition web site, check how features you´d see implemented on PluThon and provide a feedback to eclipse-integration AT maemo DOT org. Your comments are welcomed!
Subscribe to:
Posts (Atom)
