“OneMK” – makefiles made easy.

HCL recently has released a new version of the C API Toolkit for Notes/Domino 11.0.1. I had already written about it here.

Thomas Hampel reported that there will also be another release of the toolkit after the release of version 12 of Notes / Domino. In this version the makefiles will be included again, which are missing in version 11.0.1.

Basically, there is nothing against using the makefiles from version 9.0.1. However, I think the makefiles are not very user-friendly, especially for beginners. In addition, a separate makefile with the platform-specific characteristics must be created for each platform.

There are a number of tools that do the manual assembly for you ( cmake, boost-build, automake etc ), but the tools themselves must be installed on each platform, and require a more or less extensive training in the handling.

I have worked with boost-build myself for a long time. To make it easier for beginners (and old hands) to work with makefiles, I started a small project over the turn of the year 2020 / 2021.

The goal is to create makefiles in a standardized way, and to be able to use one and the same makefile for the build of a project on different platforms. If possible, no additional software should be necessary.

The result is “OneMK“. The project consists of several files, which contain definitions for compiler and linker settings, and limit the configuration of a makefile to the absolutely necessary things.

Prerequisites

The project can be installed within an existing folder structure in the “makefiles” directory. Here is a screenshot of how I installed it.

Additionally an environment variable GIT_REPOSITORY is expected, which points to the root directory. (git)

If you are working on Linux, then you must also create a corresponding directory structure there and export the environment variable GIT_REPOSITORY accordingly.

The notesapi directory can contain one or more versions of the SDK.

There are several files in the makefiles directory.

  • common.notesapi.VERSION.mk contains the compiler and linker parameters necessary for the respective SDK version.
  • common.recipes.mk contains the “recipes” for the build of a project.

There are recipes for

  • clean – cleans the project directory and deletes .o and .pdb files of a previous build.
  • info – gives information about the source files and object files
  • make – the actual build process
  • install/ uninstall – installs or removes the generated binary file in a target directory to be specified

After “installing” “OneMK“, we can now start creating makefiles for our projects.

Simple example

Here is an example of what the makefile for an executable (application) looks like.

#### ######################################################### ####
# MAKEFILE FOR C/C++ PROJECT
# Author: Ulrich Krause
# Date:   2021/02/10
# sample makefile to build /notesapi/11.0.1/samples/basic/intro
#### ######################################################### ####
BASE_DIR = $(GIT_REPOSITORY)/
ifeq ($(BITNESS),)
BITNESS = 32
endif
TYPE = application
TARGET = intro
SUFFIX = c
#------------------------------------------------------------------
include $(BASE_DIR)makefiles/common.notesapi.11.0.1.mk
#------------------------------------------------------------------

SRCDIR =
INCLUDES = 

#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#
SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

#------------------------------------------------------------------
# Recipes (included from common.recipes.mk) 
#
include $(BASE_DIR)makefiles/common.recipes.mk
#------------------------------------------------------------------

Create a new file in the directory /notesapi/1101/samples/basic/intro/make.mk and copy the code into the file.
If the environment variable GIT_REPOSITORY is set, and the necessary files are in the previously described location, then you can start the build process with the following command in the directory /notesapi/1101/samples/basic/intro/.

This works on both Windows and Linux with the same makefile. You do not need to create separate makefiles for the different platforms. On Windows, make sure to open the appropriate command prompt for 32 or 64 bit.

make -f make.mk clean make 

will start the build process. you should see output similar to this on the console. For 32 Bit ( wich is the standard BITNESS in the makefile )

For 64Bit build, you can either set this as the default in your makefile or use

make -f make.mk clean make BITNESS=64

If you see WARNINGS during the build process, you can either fix them in your source code ( which is the preferred way to handle warnings and errors) or you can simply ignore them.

To suppress the console output, on Windows you can add #pragma statements into the pragma.h file in the makefiles folder. The file is a forced include and will be added to your project includes at build time.

If you want to install the builded binary, use

make -f make.mk clean make install INSTALLDIR=c:/notes

Keep in mind that INSTALLDIR is case-sensitive

You can use the exact same makefile also on Linux.

More complex example

Here is a more complex example for an extension manager ( shared dll / lib )

#### ######################################################### ####
# MAKEFILE FOR C/C++ PROJECT
# Author: Ulrich Krause
# Date:   2021/01/17
#### ######################################################### ####
BASE_DIR := $(GIT_REPOSITORY)/
ifeq ($(BITNESS),)
BITNESS = 64
endif
TYPE = shared
TARGET = secureid
SUFFIX = cpp
#------------------------------------------------------------------
include $(BASE_DIR)makefiles/common.notesapi.11.0.1.mk
#------------------------------------------------------------------
SRCDIR += src/

INCLUDES += inc
INCLUDES +=	$(BASE_DIR)hashlib/src
INCLUDES +=	$(BASE_DIR)undocumented

LDLIBS_ADDITIONAL_PATH += $(BASE_DIR)_static_libs

ifeq ($(DETECTED_OS),$(strip Windows))
LDLIBS += undocumented-w64.lib
LDLIBS += Iphlpapi.lib
LDLIBS += libhl++-64.lib
LDLIBS += /NODEFAULTLIB:libcmt
MDF := /DEF:secureid.def
WINVER = /DWINVER=0xA00 
else 
LDLIBS += -lhl++-64 
LDLIBS += -lstdc++fs
endif
LANGUAGE = c++17
#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#------------------------------------------------------------------

SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

#------------------------------------------------------------------
# Recipes (included from common.recipes.mk) 
include $(BASE_DIR)makefiles/common.recipes.mk
#------------------------------------------------------------------

If you need to exclude src files because the will not work on the target platform, you can do this

#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#------------------------------------------------------------------

SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
ifneq ($(DETECTED_OS),$(strip Windows))
SRCS:=$(subst src/windowsonly.cpp,,${SRCS})
endif
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

The windowsonly.cpp will be removed from the list of source files, if the DETECTED_OS is not “Windows”.

This is only a short introduction to OneMK. The content of the files is mostly self-explanatory ( or so I hope ). You should be able to create makefiles for your existing projects and build them successfully.

There is a lot room for improvements and I would be happy to get some feedback if you like the idea. And I also appreciate any help. I have tested OneMK with several of my projects, simple and complex. It should also work for you, but I do not guarantee it.