Build
August 21, 2022 at 1:53 PMAs 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 theMakefile
which holds the build instructions. The variableBIN_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
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!