As we have an initial set of source files ready we can give it a try and build it. We are using the tool make for building our project or rather orchestrating our build because make actually knows nothing about how to build an RPG program or any other kind of program. It knows how to handle dependencies. It can use variables and it can execute targets/build steps and shell commands.

So how does make know how to build a program?

Everything the tool executes is defined in the build script called Makefile. I won’t go into any details here. As with any other tool used here make has been around for ages and you will find plenty of information on the internet on how to use make.

Now take a look at the README.md in the champions folder. It describes the project and folder structure and explains how to build the project.

First Build

At this time you can already build the demo project. You can tell make where to place the objects by passing the library name on the command line and thus overriding the variable used in the script, variable BIN_LIB.

make BIN_LIB=CHAMPIONS

This by default will execute the target (build step) all as we have not specified any target (and the target all is the first target specified in the Makfile) and will create a simple database table, service program and web service program.

But ohh … it failed. Remember that already this simple web service program depends on ILEastic. So it needs the copybooks from ILEastic to compile the web service program. We need to pass the directory for the copybooks to the make command.

make INCDIR=/home/mihael/champions_include

The target purge removes all created objects from the library. Just pass the target as the last parameter to the make command and we will have a clean library after executing the command.

make BIN_LIB=CHAMPIONS purge

Don’t forget to always pass the build library as a parameter to the build command. If you don’t want to always pass the parameter to the build command you can also change the default value for BIN_LIB in the Makefile which holds the build instructions. The variable BIN_LIB can be found at the top of the script. Just assign your library name to it.

BIN_LIB=CHAMPIONS

In our case the default value for BIN_LIB is already CHAMPIONS so we can skip this parameter on the command call.

Handling Output

In most cases building the project will output all the content of the spooled files created by the create command. This can be pretty much and mostly not needed. If you are pretty sure that your build is compiling fine and you are only interested in the end result than you can just drop the output by using standard shell tools. We will redirect the standard output to nirvana and just keep the error output.

make > /dev/null

Note: If you have any errors in the build you will get a message from make that the execution of a command resulted in an error.

Nested Makefiles

As you probably already noticed our Makefile in the top level of our project folder doesn’t have much content and definitely doesn’t describe how our programs are built. It has some targets and executes make on a Makefile in the folder src like this:

$(MAKE) -C src/ all $*

If we take a look at the Makefile in the folder src we notice that it also just refers to another nested Makefile deeper down the folder hierarchy. Here we see that the project is split up into different domains or parts of the application.

The nice thing about make is that we can enter the src folder and execute the target web for example and just build the web service like this

make web

Build Single Program

And if we want to just recompile the web service program we can enter the web folder and use the base name of the source file as a target like this

make greetingws

But as we need to also bind the just created ILE module to a program we need to call the bind target. You can execute multiple targets in one go by adding them to the make command as a parameter.

make greetingws bind

Now just drop the output and we have a nice development build cycle.

make greetingws bind > /dev/null

Dependencies

But how can the target all build everything in one go? We didn’t specify the other build targets!

That is because of dependencies! You can specify that before a target gets executed it needs to execute one or more other targets. The dependency tree for all looks like this

make dependency tree for target all


Hopefully we all have a working greeting service by now.

This is not part of building the project but every developer wants to see their code working in action so let’s start this web service.

You can either just call it with the following command

SBMJOB CMD(CALL PGM(CHAMPIONS/GREETINGWS)) JOB(GREETING) JOBQ(QUSRNOMAX) CURLIB(CHAMPIONS) ALWMLTTHD(*YES)

or execute the make target start in the top level folder of the project (which also does execute SBMJOB).

You can now call your web service on the following URL:

http://<your_server>:44044/api/greeting/de_DE

This will probably return a HTTP Status 404 with the response Unknown locale because there is no greeting in the database for this locale but none the less it means that your web service is working.

Congratulations!