26
Fri, Apr
1 New Articles

Programming with Make on the AS/400, Part 2

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

There are many features in TMKMAKE to help you automate and extend the capabilities of your software build process. Learn how Make variables allow you to create multiple configurations of software from one Makefile. Use and extend TMKMAKE’s built-in rules for multiple projects. Tighten up your Makefiles with implicit targets. An example RPG project detailed in this article can be modified and used for your first TMKMAKE-enabled project.

Last month, I introduced TMKMAKE, a recompilation tool that simplifies the chore of rebuilding objects (makefile targets) when the objects upon which they depend (dependents) change. I promised you that I would tell you about some of Make’s more esoteric features this month. I’ll begin with a discussion of Make variables.

Variables

A very powerful feature of Make is its ability to recognize and evaluate Makefile variables, sometimes called macros. A variable can be defined and used in a Makefile in much the same way you would use variables in a procedural programming language. One difference is that Make variables can be assigned from the command line (as an argument to TMKMAKE). Variables in TMKMAKE (and most other Make implementations) can be assigned only string values. The syntax for defining and assigning a variable in a Makefile is as follows:

var = value

In this syntax, var is the name of the variable, and value is the string to be assigned to it. The first character of var must be in the first column of the Makefile. To reference a variable within a Makefile, enclose it in parentheses and prefix it all with a dollar sign ($)
(e.g., to reference the Makefile variable named MYVAR, use $(MYVAR)). Although variables can be named using uppercase and/or lowercase characters, most conventional Makefiles use only uppercase characters in variable names. Variables can be referenced anywhere within the description block. When Make encounters a variable reference, it substitutes the reference with the value of the variable in its place. If a variable is referenced

before it is given a value, or if it is not assigned at all, TMKMAKE replaces the reference with an empty string.

As a simple example of the use of variables, suppose a project is to be built into two separate configurations, one for the current release of OS/400 and the other for the previous release. You could create a variable named CONFIG and refer to it in description blocks that create program and module objects, as in Figure 1.

Now, with the TMKMAKE command, give CONFIG a value, as shown here:

TMKMAKE +

MAKETARG(‘debug02’) +

MACRO(‘CONFIG=tgtrls(*prv)’)

The MACRO parameter of TMKMAKE allows you to give a value to one or more variables referenced in a Makefile. Thus, the TGTRLS parameter of the Create RPG Module (CRTRPGMOD) command would be substituted for the $(CONFIG) reference, and the module would be built for the previous release of the operating system. Note that the TGTRLS parameter is used in many other compilation and program generation commands, so the $(CONFIG) reference could be used in each of the description blocks using these commands. Note also that if CONFIG had not been given a value in the MACRO parameter of TMKMAKE, the $(CONFIG) reference would be translated into an empty string, and hence the default value of TGTRLS would be implied.

Conditional Preprocessing

When Make evaluates variables and makes substitutions for the variables’ references in the Makefile, it does so at “preprocessing” time in the Make process. That is, Make performs all variable substitutions before evaluating any description blocks. Another action that Make can perform prior to description block evaluation is conditional directive evaluation. An “if-then-else” structure is provided to allow sections of the Makefile to be alternately switched “on” or “off,” depending on the value or existence of a Make variable.

In the previous example, if the value for CONFIG had not been specified on the command line, the programs would be built with the default value for the TGTRLS parameter of the build commands, which is generally *CURRENT. Suppose the *PRV configuration should be built by default instead of the *CURRENT configuration. This function could be performed by means of the following conditional statement:

!ifndef CONFIG
CONFIG=TGTRLS(*PRV)
!endif

The exclamation point (!) indicates to TMKMAKE that the line contains a preprocessing directive that should be evaluated prior to description block evaluation. All preprocessing directives should be given in lowercase (but not the parameters to the directive). The !ifndef directive is used to “enable” the section of the Makefile between a subsequent !endif directive and itself, but only if the variable named by its argument is defined either previously in the Makefile or as an argument in the MACRO parameter. Similarly, but inversely defined, is the !ifdef directive. In the example, the effect is to assign the value TGTRLS(*PRV) to CONFIG only if it has not already been assigned in the MACRO parameter of TMKMAKE (or in a previous line of the Makefile). Thus, the build will deviate from the previous version of OS/400 only if the CONFIG variable is set on the command line.

You can also use the !else directive following one of the “ifs,” as in the following:

!ifndef CONFIG
CONFIG=TGTRLS(*PRV)
TEXT=Default build
!else
TEXT=Special build
!endif

Two occassionally useful preprocessing directives are also available: !undef allows you to revoke a macro definition. It takes a macro name as a parameter and, if processed, removes the macro from Make’s current dictionary of macros. Thus, any subsequent

reference of the macro will return an empty string. !error may be used to halt Make at the point it is processed, and it may be followed by a text string that will be output. !error can be helpful when debugging a complex Makefile.

Implicit Targets

With TMKMAKE and other modern Make programs, it is possible to specify implicit targets to create a set of objects with a given extension from another set of objects with another extension. Instead of explicitly specifying the full names of the targets and dependencies, the first line of the description block specifies the extensions of the targets and dependencies. This can save a lot of redundant description blocks, which may be identical with the exception of the basenames of the targets and dependents. Figure 2 shows two description blocks that create two separate ILE modules from RPG code.

Note that the only differences between the two description blocks are the basenames of the targets, dependents, and references to the target in the compiler command. Instead, you could specify an implicit target to combine the two description blocks, as in Figure 3.

When using implicit targets, you have to give TMKMAKE a hint about which extensions to use. The .SUFFIXES special target tells TMKMAKE that its list of dependents is a list of extensions to be used in resolving implicit targets. .SUFFIXES needs to be defined only once in the Makefile, usually before the implicit target definitions. In Figure 3, the implicit target description block follows the .SUFFIXES block. The target specification and the apparent lack of dependencies are what distinguish this description block as an implicit target block. The target specification is actually a specification of one class of target and one class of dependent. It is a wildcard specification, and it is read as “*.qrpgsrc objects are dependents of * targets,” where * is a common basename of the target and its dependent. So when Make encounters a target that is not explicitly defined in a description block, say test, it will match test to the implicit target and then attempt to resolve the dependency test.qrpgsrc. If there does exist a source member named QRPGSRC(TEST) in the current library, then the command list will be executed.

Built-in Variables

Notice the odd-looking variable reference in the command list for the example in Figure 3. $(@F) is one of TMKMAKE’s “built-in” variables and is usable only in description blocks. These variables are very special in that they are resolved not at preprocessing time, but rather at description block evaluation time. $(@F) is substituted with the object name (mnemonic F) of the target (mnemonic @). For a target named test, $(@F) is substituted with the string “test.” TMKMAKE’s built-in variables come in two flavors: regular and extended. Figure 4 lists the regular built-in macros, the availability of which may be limited depending upon whether or not they are used in implicit target description blocks.

Notice that the name of the variable reference is not enclosed in parentheses for the regular built-in variables. The extended built-in variables are variations of the regular builtins with this syntax:

$({regvarname}{modifier})

Here, {regvarname} refers to one of the variable names of the regular built-in variables: @, ?, <, *, or **. {modifier} is one of the modifiers listed in Figure 5.

In the example above, $(@F) gave us the file name of the target. For another example, suppose there were a target with an explicit path, such as this:

mylib/myprog : mylib/mymod

crtpgm pgm(mylib/myprog) module(mylib/mymod)

In the command section of the description block, the library name of the target could be referenced with $(@L), instead of the explicit references to mylib.

More Fun with Implicit Targets

In Part 1, I showed you how to construct a pseudotarget description block with no command section. TMKMAKE actually handles the case of no command section by

checking for any implicit target description blocks that match the targets and dependents of the commandless description block. For clarity, a description block such as the following could be added:

test : test.qrpgsrc

This matches the previously defined implicit target description block for building RPG modules since the target has the extension and the dependent has the qrpgsrc extension.

As a final example of implicit targets, suppose that there were only single-module, single-language programs in a different project. While this is an impractical use of ILE RPG, it is an effective demonstration; with modification, the example could be used with OPM RPG. There will be three programs, and the source members for the modules will have the same name as the programs. These programs can be built with one implicit target block and one pseudotarget, as follows:

.SUFFIXES : .qrpgsrc .

all : debug test ship

.qrpgsrc. :

crtrpgmod module(*curlib/$(@F)) source(*curlib/qrpgsrc)

crtpgm pgm(*curlib/$(@F)) module($(@F))

Invoking TMKMAKE using this Makefile with all as the argument in the MAKETARG parameter will invoke the RPG compiler and the bind command for three source members and three ILE modules to create the three programs.

TMKMAKE matches undefined targets to the extensions specified as dependents in the .SUFFIXES description block in left-to-right order. The first extension matching the undefined target identifies the implicit target description block to use to generate the target. If no suffix matches or no implicit target for the suffix exists, then the build of the undefined target fails.

Whenever you define new implicit targets in a Makefile, you should add the extensions of the target and dependent as dependents of the .SUFFIXES target block at the top of the Makefile. Otherwise, Make may not be able to correctly match the implicit targets.

Built-in Targets

TMKMAKE includes some built-in implicit targets, too. These can simplify a Makefile even more, to the point that it is possible to write an effective Makefile that contains no commands at all! The built-in implicit target blocks are actually configurable—they are contained in the QMAKSRC source file in the library where TMKMAKE is installed, in the member BUILTIN. TMKMAKE reads this file member before reading your Makefile, effectively appending its contents as a prefix to your Makefile. You can examine this file to determine if any of the built-in targets are usable in your projects.

Unfortunately, in TMKMAKE as delivered from IBM, there are several implicit rules missing from BUILTIN that should probably be there. There are no implicit targets to build ILE RPG modules from the QRPGSRC file source members like the one defined in the first implicit target example. Since BUILTIN is a source file member, however, you can add your own implicit targets here, if you wish, to suit the needs of your projects.

Tips for Writing Useful Makefiles

A well-written Makefile will most likely contain elements of all the features of Make outlined in the previous sections. The goals of Makefile programming are similar to the goals of applications programming. A good Makefile is concise, flexible, easy to understand, easy to maintain, and easy to extend.

Conciseness is achieved mainly via the implicit targets construct, which reduces the number and size of description blocks. Large projects may contain dozens of modules. It makes better sense to use implicit targets to build the modules for such projects thereby

reducing the number of description blocks from dozens to as few as one. This greatly simplifies changing the configuration of the build as well, as changes often need to be made to only a few implicit targets.

Makefile variables can be used to increase the utility of a build process. By defining and/or overriding the assignment of Makefile variables in a build process, several different build configurations are possible using a single Makefile. Makefile variables can also help to reduce the complexity of description blocks by gathering strings of similar command parameters or options under a single variable. Pseudotargets, with or without implicit targets, can help to build multiple independent parts in a single step and provide for future extendibility of the build.

As a final example, examine the smallish RPG project whose source is given in Figure 6. Suppose that the project will probably grow in size and scope. The Makefile for the project will be designed accordingly.

The first elements you should notice about this Makefile are the lines containing comments. The pound sign (#) indicates the beginning of a comment, which extends to the end of the current line. The comment can appear anywhere on any line and may be preceded by Makefile directives or description block code.

At the top of this Makefile, a few variables that control the build configuration are outlined. These variables are placed at the top of the Makefile so that they are easily accessible by the user of the Makefile, who may change or override them to suit a particular build configuration. Many seemingly static values are defined here as variable values, such as location of the development library. This makes it possible for build configuration changes to be as simple as changing a variable assignment. For the same reason, compiler and binder options variables are assigned here, such as RPGCOPTS. Note that the definition of RPGCOPTS contains a reference to an undefined variable RPGFLAGS, allowing you to specify other compiler options on the command line. When you want to do this, simply add an assignment to RPGFLAGS in the MACRO parameter of the TMKMAKE command.

Next are defined variables enumerating the lists of objects to generate. PGMS is the list of programs to be built. In this example, the project currently builds only one program, but when requirements change and it needs to build more, the names of the new programs can be added here.

Following the programs list are lists of modules required to build the programs. Each program to be built will have a separate list of modules to be built (it’s OK if the lists overlap). Here, DEBUG01MODSTYPE and DEBUG01MODS are two different expressions of the same list. The first is used as a dependency list for the DEBUG01 program target, and the second is used as an argument to the MODULE parameter of CRTPGM.

The first target in the Makefile is a pseudotarget, all. Most Makefiles have a pseudotarget similar to this one, which is invoked to build all the major objects of the project. All modules are built with implicit target description blocks, but programs, which may have several module dependencies, are built with explicit targets. Again, since there is currently only one program target, DEBUG01, there is only one explicit target in the Makefile, in the description block following the all pseudotarget description block.

Sometimes a clean pseudotarget is useful, so there is one defined in this example. When clean is invoked, all the programs and modules associated with the project are deleted. This might be necessary when you are unsure of the contents of the development library. Note that in the command list of the “clean” target, the commands are prefixed with a hyphen (-). This tells TMKMAKE to ignore errors in these commands if they occur. So, if one of the objects does not exist, TMKMAKE does not abort because of the error, but rather continues to delete the other objects.

At the end of the Makefile, the set of implicit target description blocks required to build the module lists is given. Currently, only RPG and CL modules are constructed by this build.

This Makefile generates program and module objects to the library whose name is assigned to the LIB variable. The source files it uses to do this, however, must be contained in the current library. Generally, you would invoke one of the two pseudotargets, all or clean, to use it. You could however, invoke other explicit or implicit targets, such as PROJLIB/DEBUG01C or PROJLIB/DEBUG02. You could even invoke a module target not listed in the modules list, such as PROJLIB/DEBUG03. However, this will work only if there is an RPG or CL source member in one of the two source files, QRPGSRC or QCLSRC, of the current library.

This Makefile can be used as a prototype for your projects. In most cases, it will be possible to change only a few configuration variables and the object lists to make this Makefile suitable for your project.

TMKMAKE Command Options

There are eight command parameters available with TMKMAKE. The default options are best in most cases, but it’s nice to know what the other options are. Refer to Figure 7.

The default options will do the trick for you if the Makefile and library list are set up correctly. As mentioned before, the MACRO parameter can be used to override Makefile variables. And if you have more than one primary target in your Makefile, you may need to use MAKETARG. The MSGLOG parameter can usefully be changed from the default value. By specifying MSGLOG(*SESSION), all TMKMAKE-generated output goes to the session log rather than the job log, which some may find handy. Also, if a certain Makefile just isn’t working as you think it should, the OPTION(*DEBUG) parameter can sometimes be helpful.

More Information

TMKMAKE has many more features than have been introduced here. Many of these, including support for binding directories and link editor libraries, are presented in a document supplied with QUSRTOOL. The member TMKINFO in the QATTINFO file of QUSRTOOL contains this document, and it is a must-read for any programmers seriously considering using TMKMAKE in their development plan. A word of warning, though: Some of the features described in the document simply do not seem to work, such as the Output Translation feature. The basic functionality, however, is robust enough to work around this problem.

For information on Make in general, there are almost as many books about the program as there are platform implementations of it. The computer science section of any good library or bookstore will have at least one title that describes Make. Most modern C/C++ compilers bundle with, or at least assume the use of, a version of Make. Make is installed on almost every machine in the world running the UNIX operating system. Since 1998, the Free Software Foundation has been publishing a freeware version of Make for UNIX called GNU Make, for which it regularly releases updates and produces bug fixes. It also has extensive documentation that outlines the basics of Make and the enhancements implemented by the GNU Project. GNU Make and its documentation are available at http://www.gnu.org.

In the bookstores, look for the O’Reilly & Associates, Inc. book, Managing Projects with Make (by Andrew Oram and Steve Talbott), which covers the basics well. It also provides insight into the different implementations of Make.

Finally, if you are truly brave in your quest for knowledge, you have the source code to TMKMAKE sitting there on your AS/400 right now in QUSRTOOL. It could use an update and probably a bug fix or two as well, if you are so inclined.

Reference

Oram, Andrew and Steve Talbott. Managing Projects with Make. Sebastopol, California: O’Reilly & Associates, Inc., 1991.

debug02 : debug02.qrpgsrc

crtrpgmod module(*curlib/debug01)

srcfile(*curlib/qrpgsrc) $(CONFIG)

Figure 1: Using a Makefile variable

debug01 : debug01.qrpgsrc

crtrpgmod module(*curlib/debug01) srcfile(*curlib/qrpgsrc)

debug02 : debug02.qrpgsrc

crtrpgmod module(*curlib/debug02) srcfile(*curlib/qrpgsrc)

Figure 2: Explicit description blocks tend to be redundant

.SUFFIXES : .qrpgsrc .

.qrpgsrc. :

crtrpgmod module(*curlib/$(@F)) srcfile(*curlib/qrpgsrc)

Figure 3: This implicit target (following the required .SUFFIXES target) combines the two description blocks in Figure 2

$@ The full name of the target, including object tags, ,, etc. $? The list of all dependents younger than the current target (explicit target description blocks only)
$< The name of the first dependent causing execution of the command list (implicit target description blocks only)
$* The basename of the target and dependent causing execution of the command list (implicit target description blocks only)
$** The list of all dependents in the current description block

Figure 4: Built-in macros

L The library name part of the regular built-in variable’s value M The member name part of the regular built-in variable’s value (empty string if not a database file)

F The file name part of the regular built-in variable’s value (empty string if not a database file)

T The object type part of the regular built-in variable’s value (as in

” or “”) S The SEU type of the regular built-in variable’s value

Figure 5: Modifiers used by extended variables

#

# Typical RPG/CL project makefile
#

#

# configuration options
#

LIB=PROJLIB # primary development library
RPGC=CRTRPGMOD # rpg compiler
CLCL=CRTCLPGM # cl compile & bind
CLC=CRTCLMOD # cl compiler
BIND=CRTPGM # bind program
TGTRLS=TGTRLS(*PRV) # default target release is *PRV

# compiler option strings
RPGCOPTS=$(RPGFLAGS) $(TGTRLS) DBGVIEW(*ALL)
CLCOPTS=DBGVIEW(*ALL) $(TGTRLS)
BINDOPTS=REPLACE(*YES) $(TGTRLS)

#

# programs
#

PGMS=$(LIB)/DEBUG01C #

# modules to bind defined two ways.
#

DEBUG01MODSTYPE = $(LIB)/DEBUG01 $(LIB)/DEBUG02

$(LIB)/DEBUG01C
DEBUG01MODS = $(LIB)/DEBUG01 $(LIB)/DEBUG02 $(LIB)/DEBUG01C #

# primary targets
#

all : $(PGMS)

$(LIB)/DEBUG01C: $( DEBUG01MODSTYPE)

$(BIND) PGM($(LIB)/$(@F)) MODULE($(DEBUG01MODS)) $(BINDOPTS)

clean :

-DLTPGM PGM($(LIB)/DEBUG01C)

-DLTMOD MODULE($(LIB)/DEBUG01)

-DLTMOD MODULE($(LIB)/DEBUG02)

-DLTMOD MODULE($(LIB)/DEBUG01C) #

# implicit rules
#

.SUFFIXES : . . .qrpgsrc .qclsrc

.qrpgsrc.:

$(RPGC) MODULE($(LIB)/$(@F)) SRCFILE(*CURLIB/$(

.qclsrc.:

$(CLC) MODULE($(LIB)/$(@F)) SRCFILE(*CURLIB/$(

Figure 6: A Makefile for a more realistic project

MAKETARG This parameter is the target in the Makefile to evaluate. It must be bound by single-quote (‘) characters if it contains lowercase characters.

It defaults to *FIRST, which TMKMAKE interprets as the target of the first description block of the Makefile. SRCFILE This parameter is the library and file containing the Makefile. The library defaults to *LIBL, and the file defaults to QMAKSRC. SRCMBR This parameter is the member containing the Makefile. It defaults to *FIRST.

MACRO This parameter comprises the makefile variable assignments. Up to 50 variable assignments of the form var=value can be specified in this parameter. Variables assigned via this parameter override variable assignments in the Makefile. It defaults to *NONE.

OPTION This parameter is a set of the following keyword options:

*NOIGNORE causes TMKMAKE to abort when commands return error or exceptional conditions. *IGNORE causes TMKMAKE to ignore all errors and exceptions. *NOSILENT prints the command text to the output device prior to invoking the command. *SILENT does not print the commands. *BIRULES causes the “built-in” description blocks contained in the BUILTIN member of QMAKSRC in the installation library to be used. *NOBIRULES does not use BUILTIN. *EXEC causes commands in the command list to be executed, whereas *NOEXEC causes the commands not to be executed. *TOUCH causes the update time of the target and all of its dependents to be changed explicitly rather than by the commands that generate them. *NOTOUCH does not explicitly change the update time. *DEBUG displays debug information that may be useful for debugging errors in Makefiles. *NODEBUG does not display debug information. If conflicting options are specified, the last one specified in the argument list is used. The default options are *NOIGNORE, *NOSILENT, *BIRULES, *EXEC, *NOTOUCH, and *NODEBUG.

MSGLOG This parameter is the “output device” to which TMKMAKE-invoked commands and messages are directed. It will be either *JOBLOG or

*SESSION, and it defaults to *SESSION. MARGINS This parameter will specify Makefile margin column numbers as in MARGINS(left,right). It can also take the keyword default value, *SRCFILE, which for source physical files indicates column 1 for the left margin, and the record length for the right margin.

RTNCODE This parameter will specify the severity level of exceptions and/or return codes that cause TMKMAKE to interpret a command execution as successful or unsuccessful. It will specify one of *EXCEPTION, *LURC, or *BOTH to indicate that the following severity value is for exceptions, return codes, or both, respectively. Then, it will specify an integer severity value. It defaults to RTNCODE(*EXCEPTION 30).

SRVOPT This parameter comprises undocumented internal debugging options for TMKMAKE.

Figure 7: TMKMAKE command parameters

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: