A library and an application

What if we want to distribute shared libraries (again for all the CPUs we can) and a development package as well?

Let's use the bzip2 distribution as our example. The bzip2 binary already comes with QNX Neutrino, but the library doesn't. You can download the source code from http://www.bzip.org.

This is a good example, because it contains both a library (libbz2) and an application (bzip2). Once we've downloaded it, we can extract and build it with:

tar -zxvf bzip2-1.0.3.tar.gz
cd bzip2-1.0.3
make

We notice that a typical compile looks like:

gcc -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce 
    -D_FILE_OFFSET_BITS=64 -c decompress.c

Let's remember those options for later.

The problem with using the QNX Neutrino makefile system in this case, is that we want to make two projects: the libbz2 library and the bzip2 application. With the QNX Neutrino Makefile system, we usually have a single project.

The best solution is to separate them into different directories. Instead of moving the source code around, we'll just create two subdirectories, one called lib, and the other called app, in which we'll create the appropriate Makefile and common.mk files:

mkdir app
cd app
addvariant -i OS
addvariant nto arm o.le
addvariant nto x86_64 o
cd ..
mkdir lib
cd lib
addvariant -i OS
addvariant nto arm so.le
addvariant nto arm a.le
addvariant nto x86_64 so
addvariant nto x86_64 a

If we try to build either of these projects now, not much happens. This is because we haven't told the Makefile system where our source files are.

Let's start with the library. Its common.mk file already contains the default lines:

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

include $(MKFILES_ROOT)/qtargets.mk

Let's add a few more lines just before the line that includes qtargets.mk. First, we'll add the compile options it used originally:

CCFLAGS+=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce
  -D_FILE_OFFSET_BITS=64

In QNX Neutrino 7.0 or earlier, flags defined in CCFLAGS got passed to both the C compiler, qcc, and the C++ compiler, q++. In QNX Neutrino 7.1 or later, the CCFLAGS settings are passed to the C compiler only; to pass flags to the C++ compiler, you must set them in CXXFLAGS instead.

Next, let's tell it where to find the source files. The PRODUCT_ROOT directory is the parent directory of the PROJECT_ROOT directory, which is where our source code is located. Let's use that to specify where our source code is:

EXTRA_SRCVPATH=$(PRODUCT_ROOT)

Since the parent directory also contains the source code for the bzip2 application, and we want only the object files for the libbz library, let's weed out the object files we don't need:

EXCLUDE_OBJS=bzip2recover.o bzip2.o dlltest.o spewG.o unzcrash.o

We should add some PINFO definitions and specify where to install the files (usr/lib in this case):

define PINFO
PINFO DESCRIPTION=bzip2 data compressions library
endef
INSTALLDIR=usr/lib

Finally, let's make sure the library has the correct name. By default, it uses the directory name of the PROJECT_ROOT directory. Since we don't want to call our library lib, let's change it:

NAME=bz2

If we now run make at the terminal, we can watch all of our libraries being built.

Note: You may notice that there are libbz2S.a libraries being built in the so directories. You can use these libraries if you want to create other shared libraries that require code from this library.

What about our application, bzip2? Let's change into the app directory we built before and set up our common.mk file. This time, though, we exclude everything but the bzip2.o from our objects and add a new line:

LIBS+=bz2

Here's our complete common.mk file:

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

CCFLAGS+=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce
  -D_FILE_OFFSET_BITS=64
EXTRA_SRCVPATH=$(PRODUCT_ROOT)
EXCLUDE_OBJS= blocksort.o bzip2recover.o bzlib.o compress.o crctable.o
   decompress.o dlltest.o huffman.o randtable.o spewG.o unzcrash.o
LIBS+=bz2
define PINFO
PINFO DESCRIPTION=bzip2 file compressor/decompressor
endef
INSTALLDIR=usr/bin
NAME=bzip2

include $(MKFILES_ROOT)/qtargets.mk   

We can easily create our bzip2.use file by getting help from our previously created bzip2 executable:

../bzip2 --help 2> bzip2.use

Now we can build our binaries, and make sure they exist:

make
ls -l nto/*/*/bzip2