What is applauncherd? ============================== Applauncherd is a daemon and it helps to launch applications faster by preloading MeeGo Touch and Qt dynamically linked libraries and making some initializations before loading the application binary and executing the main function. The applauncherd daemon is started by UpStart as part of XSession, that is, at the same level as the desktop (MeeGo Touch homescreen). Applauncherd forks the will-be-application process a.k.a booster before knowing which application is going to be launched next. Users use the launcher always through a special invoker program. The invoker (/usr/bin/invoker) tells booster process to load an application binary. Before loading, booster process changes its security credentials so that the code in the application binary will be executed with the correct credentials. Loading the binary is done with dlopen(), and therefore the application needs to be compiled and linked as a shared library or a position independent executable. The booster process also sets the environment variables. Finally, it finds the main function in the application binary with dlsym() and calls the main() with the command line arguments given by the invoker. Aegis platform security is used to protect the socket connection between invoker and launcher. Currently this works only on the target device. It is automatically disabled by the build scripts when compiling on x86. Each application type (currently Qt and MeeGo Touch) has its own booster process. When booster launches the application by calling the "main()" function, applauncherd will create new booster process of that type. This document focuses on using MeeGo Touch booster, but other boosters briefly introduced in Section 7. Booster processes do some initializations that cannot be shared among other processes and therefore have to be done after the fork. This allows, for instance, instantiating a MeeGo Touch application before knowing the name of the application. Then the booster process waits for a connection from the invoker with the information about which application should be launched. With MeeGo Touch booster it's possible to fetch certain objects from a cache. This will significantly reduce the startup time of an application. Using applauncherd ============================== 1. COMPILING YOUR APPLICATION TO BE LAUNCHABLE Binaries intended to be run with applauncherd should be compiled with -fPIC option to produce position independent code. In order to produce a position independent executable, -pie option and -rdynamic options can be used in linking. This allows the result to be executed traditionally AND with the launcher. To improve linking and load times of shared object libraries the size of dynamic export table it is encouraged to hide the unnecessary symbols from the resulting binary by using -fvisibility=hidden and -fvisibility-inlines-hidden flags as well. 1.1 Build configuration for MeeGo Touch applications Use these instructions if you are building a MeeGo Touch / WRT application. In this case your application must build-depend on libmeegotouch-dev. It will install the .pc file for pkg-config and the feature file for QMake. Using QMake ----------- If you are using QMake, making your application boostable is just a matter of installing libmeegotouch-dev package and adding the following line to your .pro file: CONFIG += meegotouch-boostable The meegotouch-boostable configuration option includes the meegotouch option (so you don't have to specify it explicitly) and ultimately uses pkg-config to get the correct flags. Using QMake with pkg-config --------------------------- If you want to use pkg-config directly for some reason, you can do it by adding the following lines to your .pro file: QMAKE_CXXFLAGS += `pkg-config --cflags meegotouch-boostable` QMAKE_LFLAGS += `pkg-config --libs meegotouch-boostable` Manual settings for QMake ------------------------- You can manually set the options in your .pro file like this: QMAKE_CXXFLAGS += -fPIC -fvisibility=hidden -fvisibility-inlines-hidden QMAKE_LFLAGS += -pie -rdynamic Note that you have to update the flags manually if there are any changes in the required flags. Using CMake with pkg-config --------------------------- You can utilize pkg-config in CMake by including FindPkgConfig in CMakeLists.txt: include(FindPkgConfig) To obtain the compiler and linker flags, add the following lines: pkg_check_modules(MEEGOTOUCH_BOOSTABLE REQUIRED meegotouch-boostable) add_definitions(${MEEGOTOUCH_BOOSTABLE_CFLAGS}) link_libraries(${MEEGOTOUCH_BOOSTABLE_LDFLAGS}) In order to install the application binary with a .launch filename extension, use the following line: install(PROGRAMS myapplication DESTINATION /usr/bin RENAME myapplication.launch) If you do not want to use pkg-config for some reason, you can manually add the compiler and linker flags like this: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden -fvisibility-inlines-hidden") set(CMAKE_EXE_LINKER_FLAGS "-pie -rdynamic") Again, this requires you to update the flags if something changes. Automatic settings with pkg-config (any build system) ----------------------------------------------------- The correct flags can be automatically obtained with: pkg-config --cflags --libs meegotouch-boostable 1.2 Build configuration for plain Qt / generic applications Use these instructions if you are building a plain Qt / generic application that is not depending on libmeegotouch. In this case, your application must build-depend on applauncherd-dev, not libmeegotouch-dev. It will install the .pc file for pkg-config and the feature file for QMake. Using QMake ----------- If you are using QMake, making your application boostable is just a matter of installing applauncherd-dev package and adding the following line to your .pro file: CONFIG += qt-boostable The qt-boostable configuration option uses pkg-config to get the correct flags. Using QMake with pkg-config --------------------------- If you want to use pkg-config directly for some reason, you can do it by adding the following lines to your .pro file: QMAKE_CXXFLAGS += `pkg-config --cflags qt-boostable` QMAKE_LFLAGS += `pkg-config --libs qt-boostable` Manual settings for QMake ------------------------- You can manually set the options in your .pro file like this: QMAKE_CXXFLAGS += -fPIC -fvisibility=hidden -fvisibility-inlines-hidden QMAKE_LFLAGS += -pie -rdynamic Note that you have to update the flags manually if there are any changes in the required flags. Using CMake with pkg-config --------------------------- You can utilize pkg-config in CMake by including FindPkgConfig in CMakeLists.txt: include(FindPkgConfig) To obtain the compiler and linker flags, add the following lines: pkg_check_modules(QT_BOOSTABLE REQUIRED qt-boostable) add_definitions(${QT_BOOSTABLE_CFLAGS}) link_libraries(${QT_BOOSTABLE_LDFLAGS}) In order to install the application binary with a .launch filename extension, use the following line: install(PROGRAMS myapplication DESTINATION /usr/bin RENAME myapplication.launch) If you do not want to use pkg-config for some reason, you can manually add the compiler and linker flags like this: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden -fvisibility-inlines-hidden") set(CMAKE_EXE_LINKER_FLAGS "-pie -rdynamic") Again, this requires you to update the flags if something changes. Automatic settings with pkg-config (any build system) ----------------------------------------------------- The correct flags can be automatically obtained with: pkg-config --cflags --libs qt-boostable When using these, your application must build-depend on applauncherd-dev, which will install the needed qt-boostable.pc file for pkg-config. 1.3 Changes to the code With -fvisibility=hidden you must make sure that the symbol for main() is exported, because otherwise the launcher is not able to find the entry point for your application. This can be done like this (MeeGo Touch): #include M_EXPORT int main(int argc, char **argv) { ... } or like this (Qt): #include Q_DECL_EXPORT int main(int argc, char **argv) { ... } or like this (generic way with gcc): extern "C" __attribute__ ((__visibility__("default"))) int main(int argc, char **argv) { ... } Note: Please refer to the MeeGo Touch documentation for instructions on MComponentCache and how to enable it in your application. This README file describes only the idea behind the launcher and the basic usage, it's not the user documentation for MeeGo Touch. 2. LAUNCHING YOUR APPLICATION Rename appication binary to .launch and replace the original binary by a wrapper script that executes invoker with correct application type and the name of the application binary as a parameter. Use --type=m parameter for MeeGo Touch applications, --type=wrt for Web Runtime applications and --type=qt for plain Qt applications and everything else (see section 7). In these examples --type=m is used. Here is a launch script example for a typical application: #!/bin/sh echo "/usr/bin/invoker --type=m" $0.launch $@ exec /usr/bin/invoker --type=m $0.launch $@ If you are using D-Bus to launch your application, then this can be done straightly in the .service-file without any wrapper scripts: [D-BUS Service] Name=com.nokia. Exec=/usr/bin/invoker --delay --type=m /usr/bin/.launch Note: when launching through D-Bus, it is important to add enough delay to invoker so that it won't exit before the launched application gets its D-Bus service registered. Otherwise D-Bus daemon may think that the application just died. Another option is to use --wait-term which makes invoker wait until the launched application exits. 3. STARTING Applauncherd Applauncherd is started by UpStart during the boot time, but it can be also started manually in scratchbox or on the device by the /usr/bin/applauncherd script. 4. PLATFORM SECURITY (Aegis) Altough the connection between invoker and launcher is protected by Aegis, Application developer doesn't need to request for any additional security tokens to make things work. 5. PACKAGING Applications using the launcher must depend on applauncherd package. 6. CURRENT KNOWN ISSUES Forking and MComponentCache --------------------------- It's not possible to use MComponentCache if you fork() in your application before trying to fetch components from the cache. This is just due to the fact that X11 connections get messed up after fork(). Issues with scripts, D-Bus, and process monitoring -------------------------------------------------- By default, invoker processes terminate before or right after booster processes have called main(). This may confuse shell scripts and process monitoring in D-Bus daemon and Upstart, for instance. To help solving these issues invoker accepts parameters: --delay 10 invoker waits for 10 seconds before terminating --wait-term invoker will not terminate until the launched application process terminates. Invoker will return the same return value as the application did, or it will be terminated by the same signal as the launched application. Signals received by the invoker process will be forwarded to the launched application. Crashes after application's main() ---------------------------------- If an application is launched with invoker, there may be some destructors of MeeGo Touch classes executed after application's main(). This can cause crashes, if the application has installed a custom debug message handler and not uninstalled it before exit. 7. OTHER BOOSTERS Warning: behavior of these boosters is subject to change. Qt booster is a no-operation booster. It can be used by calling invoker --type=qt. Qt booster requires only the M_EXPORT source modification. Any MeeGo Touch boostable application can be launched with this booster type as well, but it will result in a slower start up because of empty cache in libmeegotouch. Wrt booster, used with invoker --type=wrt, populates MComponentCache with MApplication and MApplicationWindow, just like the MeeGo Touch booster. However, in this case MApplication uses a graphics system which suits better for rendering web content. 8. FURTHER READING MeeGo Touch documentation for fast application startup.