Command Line Rocks! Part 2 – Adding Multiple Source Files and Libraries

How-to

The previous Command Line Rocks! article focused on creating an app with the smallest possible amount of code. This article will show you how to:

  1. Compile multiple source files into a single executable binary
  2. Leverage the power of external libraries
  3. Create an easy-to-manage project structure

A quick recap

We have an app called GoodBye IDE that prints “Goodbye IDE!” to the stdout.

To create our app we have 2 files in a single folder (called $PROJECT_DIR):

  • main.c – A C source file
  • bar-descriptor.xml – A descriptor file which contains information about our app

And to compile, package and deploy our app to the simulator we have to run the following commands:

Compile: qcc -Vgcc_ntox86 main.c -o main

Package: blackberry-nativepackager -package GoodbyeIDE.bar bar-descriptor.xml

Deploy: blackberry-deploy -installApp 192.168.2.128 GoodbyeIDE.bar

Note that 192.168.2.128 is the simulator IP address, yours will be shown in the bottom left of the simulator window.

TITLE_IMAGE

Improve our app

Our current app isn’t very realistic. How many projects do you know which have a single source file?

Let’s make our app do something more interesting, like fooling our friends into thinking they’ve got a new message! We’ll introduce multiple source files, a library dependency and a build process that is closer to a real-world project.

Add source files

Add these two files to your project:

prank_notifier.h

#ifndef PRANK_NOTIFIER_H
#define PRANK_NOTIFIER_H
#include <bps/soundplayer.h>
void notify();
#endif

 

prank_notifier.c

#include "prank_notifier.h"
void notify()
{
     soundplayer_play_sound("notification_general");
}

Let’s also update main.c to call our new function:

#include <stdio.h>
#include "prank_notifier.h"    
int main()
{
     printf("Goodbye IDE!\n");
     bps_initialize();   
     notify();
     bps_shutdown();
     return 0;
}

So, what do these files do?

  • prank_notifier.h
    • Uses preprocessor directives to avoid multiple includes of the same code
    • Includes soundplayer.h which provides functions for playing system sounds
    • Declares the notify() function which is defined in prank_notifier.c
    • prank_notifier.c
      • Includes prank_notifier.h
      • Defines notify() which plays the default notification sound
      • main.c

Update folder structure

We could keep all our files in the same folder, however, things are going to get messy when we start generating temporary files during the build process. To keep things tidy create the src, include and build folders and move our existing files into them. Here’s what each folder should contain:

cmd2-2

Building our app

The build process now requires more steps as we have multiple source files. It can be summarised as:

  1. Convert the source files (prank_notifier.c and main.c) into object files (.o). This process actually comprises three steps, all handled by qcc:
  • Preprocessing – Processing the preprocessor directives (e.g. #include and #define) to create preprocessed source code
  • Compiling – Converting preprocessed source code into assembly language for our target architecture
  • Assembling – Converting assembler code into machine code which can be executed by the target CPU
  1. Link the object files and the dependent BPS library to create an executable binary
  2. Package the binary into a BAR file using our executable binary and bar-descriptor.xml

Compile the source files

Use the following commands to compile our source files into object files:

qcc -Vgcc_ntox86 -Iinclude -c src/prank_notifier.c -o build/prank_notifier.o
qcc -Vgcc_ntox86 -Iinclude -c src/main.c -o build/main.o

These commands are the same as those we used in the first article but we have some new command flags:

-I<folder> - Adds a folder to the search path for include files. This is so that when preprocessing prank_notifier.c and main.c, the preprocessor can find the required header file prank_notifier.h.

-c - Do not link, just create an object file. This stops the linker from running and producing errors. We need this because we’re not ready to link yet, we’ll do that in the next step.

Link the object files

Linking is achieved by specifying all the object files and any dependent libraries:

qcc -Vgcc_ntox86 -lbps build/prank_notifier.o build/main.o -o build/main

New command flags:

-I<library_name> - Tells the linker to link against the named lib<library_name> in this case it’s libbps. Note that you don’t have to specify lib before the library name.BlackBerry 10 built in libraries can be found in $QNX_TARGET/<platform_architecture>/lib and $QNX_TARGET/<platform_architecture>/usr/lib.

More information about the built in libraries can be found here.

We should now have an executable binary main, so now let’s package it into an app.

Package and run the app

Update the <asset> tag in bar-descriptor.xml to point to the new binary path:

<asset path="build/main" entry="true">main</asset>

Create the BAR package:

blackberry-nativepackager -package build/GoodbyeIDE.bar bar-descriptor.xml

Upload the BAR file to the simulator:

blackberry-deploy -installApp 192.168.2.128 build/GoodbyeIDE.bar

The app icon should appear on the simulator:

cmd2-3

Now, if you tap the icon you should hear the default notification sound. Perfect for sneaking up behind people and fooling them into thinking they have a new message!

Summary

OK, so our new app might not make us many friends but our project does now have a logical structure that we can easily add more source files to. Plus, we’ve been able to leverage an external library. This opens a world of opportunity because we can now use the built in BlackBerry APIs as well as many open source libraries available for BlackBerry 10.

In the next article we’ll look at how the build process can be managed and improved by using Makefiles. Say goodbye to all these long compiler commands and hello to super-fast build and deployment!

About Don Turner

I work for the BlackBerry Developer Relations team helping developers bring their apps to the awesome BlackBerry 10 platform. I specialise in gaming technologies, native development and Cascades.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus