Manual for Ocera Make System (OMK) version 0.2-214-g59449e6
Copyright © 2007, 2008, 2009, 2010, 2011, 2013 Michal Sojka, Pavel Pisa
Next: User’s Manual, Previous: Ocera Make System, Up: Ocera Make System [Contents][Index]
OMK is an advanced make system written entirely in GNU make. Compiling
software using OMK requires only GNU Make and standard UNIX
utilities (sh
, sed
, cmp
, ...)
installed. OMK aims to be developer friendly; to use OMK, you do not
need to understand (sometimes) cryptic syntax of Makefiles.
You can use OMK on all platforms where you can run GNU Make including Cygwin and MinGW. MS DOS was not tested.
Next: Quick Start, Previous: Overview, Up: Overview [Contents][Index]
Here we list some of OMK features, which we think are important for choosing of a make system.
make
for a particular subdirectory in the
source tree.
Next: History, Previous: Why to Use OMK?, Up: Overview [Contents][Index]
If you get some sources, which are distributed with OMK, usually the following commands are sufficient to compile the whole project.
make default-config make
To use OMK in your own project, follow these steps:
make omkize
in the root directory.
Your project is now ready to compile.
Previous: Quick Start, Up: Overview [Contents][Index]
OMK was originally written by Pavel Píša as a solution to have one common make system for OCERA project, where we needed to compile user-space programs, Linux kernel modules and RT Linux modules in one package. Although this system was not accepted for the whole OCERA project. Several individual developers (mostly from Czech Technical University) liked it and started to use it.
As a number of projects using OMK grew it was necessary to modularize the make system to support more “targets”. Michal Sojka took care about the process of modularization.
Next: Original README, Previous: Overview, Up: Ocera Make System [Contents][Index]
Next: Invoking OMK, Previous: User’s Manual, Up: User’s Manual [Contents][Index]
The main concept of OMK is very simple. In the heart of OMK are two
files Makefile.rules and Makefile.omk. The former one
resides in project root directory and contains all compilation rules
needed for compilation of the particular project. There are different
Makefile.rules for different platforms (Unix, RTEMS, system-less,
...). Makefile.omk is stored in every (sub)directory and
describes what should make
perform in that directory (e.g.
compile a program from several source files). It uses declarative syntax
(assign values to variables) similar to Automake files
Makefile.am. The content of Makefile.omk is described in
the following sections.
Since make
searches by default for a Makefile and not
for Makefile.rules or Makefile.omk, there
must1 be a small generic Makefile in every
directory, whose task is only to find Makefile.rules in the
actual or any parent directory and include it. This search is performed
only once at the beginning of compilation.
The compilation process itself is comprised of several passes. Every pass traverses the whole directory structure2 and does a particular task in every directory of the project. Typically, these passes are:
This pass takes all include files marked for “export” and copies (or links) them to the include directory under _compiled directory. See Header Files.
Also, during this pass, automatically generated header file are generated according to the current configuration. See Configuration and Conditional Compilation.
During this pass, all include files are in place, so all libraries can be compiled.
Finally, programs can be compiled and linked against libraries created in the previous pass.
The results of compilation are stored under the _compiled directory. This directory is structured as a classical Unix file-system (it contains directories like bin, lib and include) and can be directly copied to the target device or to some directory on a host computer (e.g. /usr/local).
Besides _compiled directory, there in a _build directory. Under this directory are stored some temporary files and intermediate compilation products (object files, dependency files etc.).
In the next section, we provide an overview of methods, how to invoke OMK from command line. Section Interfacing OMK to popular IDEs covers running of OMK from popular IDEs.
Sections Compiling Programs through Configuration and Conditional Compilation deals with the content of Makefile.omk. Its syntax in usual cases compatible to GNU Automake’s Makefile.am syntax. Also, the scheme for naming variables was inspired by Automake so most OMK variables have the name like ‘target_TYPE’.
Next: Compiling Programs, Previous: Basic Concepts, Up: User’s Manual [Contents][Index]
Before using OMK for the first time, you have to call:
make default-config
See Configuration and Conditional Compilation for details. If you forget to do this, OMK will notice you.
To compile the whole project or only some subtree of the project, call
make
in the appropriate directory.
To clean files in _build directory but not in _compiled one, use:
make clean
To clean the compilation completely, you can either remove _compiled and _build directories manually, or call
make distclean
which does the same. This command removes these directories even if you call it from a subdirectory.
To debug compilation problems, you can use V
variable (see
V):
make V=1
You can also set values of some other variables on command line for temporary change something. The example below compiles the code temporarily with debugging information:
make CFLAGS="-g -O0 -Wall"
If your project uses an alternative make-system (e.g. Automake or custom makefiles), it might be useful for you to use the command:
make omkize
This will find all Makefile.omk files in all subdirectories and copies generic Makefile from the root directory to that subdirectories. This way you can easily switch your project to use OMK.
If this variable equals to ‘1’, the whole command lines for all executed commands are displayed. When not set or zero, only short messages are printed. Value of ‘2’ displays the whole command lines as with ‘1’ and in addition directory navigation messages are printed.
Next: Compiling Libraries, Previous: Invoking OMK, Up: User’s Manual [Contents][Index]
To tell OMK to compile a program, you need to set some variables in Makefile.omk (usually) in the directory where program sources are located.
In the example bellow program test
will be compiled from
source test.c.
bin_PROGRAMS = test test_SOURCES = test.c
The variables are:
Contains a list of names (whitespace separated) of programs to be compiled in this directory.
Almost the same as bin_PROGRAMS, but resulting binaries are stored in bin-tests directory instead of bin. This variable is intended for various test programs not to be mixed with the final product.
Almost the same as bin_PROGRAMS, but resulting binaries are stored in bin-utils directory instead of bin. This variable is intended for various development utilities not to be mixed with the final product.
For every program name xxx in bin_PROGRAMS
,
test_PROGRAMS
or utils_PROGRAMS
, this variable contains
a list of sources that are needed to compile the program. OMK uses an
extension of the filename to determine the compiler to compile this
source.
This variable contains a list of libraries the program xxx will be linked with.
test_LIBS = m curses
CFLAGS specific for the compiler program. If this variable is set, its value efectively overrides the value of OMK_CFLAGS variable.
CXXFLAGS specific for the compiler program. If this variable is set, its value efectively overrides the value of OMK_CXXFLAGS variable.
CPPFLAGS specific for the compiler program. If this variable is set, its value efectively overrides the value of OMK_CPPFLAGS variable.
Program sources generated (by other rules) in the build directory. See the following example.
bin_PROGRAMS = p p_GEN_SOURCES = gen.c gen.c: echo "int main() { return 0; }" > $@
This variable contains a list of libraries which needs to be linked to to all programs or shared libraries in this directory.
This variable contains a list linker switches to load additional libraries. You usually specify here -L and -l switches.
Note: The value of this variable is not used used by OMK for any purpose other than linker invocation. Therefore dependency handling of shared libraries does not work if the library is specified in LOADLIBES instead of lib_LOADLIBES.
Next: Compiler Flags, Previous: Compiling Programs, Up: User’s Manual [Contents][Index]
With OMK, you can easily create statically or dynamically linked libraries. The way of creating libraries is very similar to how programs are created. See Compiling Programs.
In Makefile.omk, you specify several variables, which defines how the libraries should be compiled. In the example below the library ‘mylib’ (full filename will be libmylib.a) is created from two sources funca.c and funcb.c. Interface of this library is defined in myfunc.h. Therefore, we export this header for use by other programs.
lib_LIBRARIES = mylib mylib_SOURCES = funca.c funcb.c include_HEADERS = mylib.h
Variables for use with libraries are:
Specifies a list of statically linked libraries to be compiled. OMK
automatically prepends lib
prefix library names.
Specifies a list of dynamically linked libraries to be compiled.
For every library name xxx in lib_LIBRARIES
or
shared_LIBRARIES
, this variable contains a list of sources that
are needed to compile the library. OMK uses an extension of the
filename to determine the compiler to compile this source.
Previous: Compiling Libraries, Up: Compiling Libraries [Contents][Index]
C and C++ libraries are not very useful without header files. OMK provides several variables that control operations with header files.
During compilation, header files are copied (or linked by symbolic links) from source directories to the _compiled tree (see include-pass). Libraries and programs are then compiled against these copies. The following variables control which headers are copied and what is their destination file name.
Specifies the list of header files to be exported for use by other libraries/programs. The files are exported directly to the include directory even if the file is located in a subdirectory (like sci_regs.h in the example below)
include_HEADERS = regs.h periph/sci_regs.h
Similar to include_HEADERS, but the directory prefix is always
kept. To include the file exported by this variable, use
#include <prefix/header.h>
.
Exports the header files under different name. The form of the items
in this whitespace separated list is: real name->
new
name.
renamed_include_HEADERS = orte_config_omk_win32.h->orte_config.h
If this variable equals to ‘y’, symbolic links to headers in source directories are used in _compiled tree instead of copies.
Normally, the header files are copied into _compiled directory to be prepared for transfer into target location afterwards. Copying ensures that resulting libraries are in correspondence with the header files even if the header is changed by a developer but the library is not recompiled.
On the other side, the copying could make problems during development. Most IDEs, allows you to jump directly to the place, where an error is reported by the compiler. If the error is in a header file, IDE opens you the copy of the header file. If you correct the error there, after the next compilation, your header file will be overwritten by the old version from your source tree.
This option is not typically used in Makefile.omk, but in the top level configuration file config.omk or on command line.
Next: Recursing into Subdirectories, Previous: Compiling Libraries, Up: User’s Manual [Contents][Index]
OMK follows the same philosophy for flag variables as does Automake. The variables with OMK_ prefix (e.g. OMK_CPPFLAGS) are supposed to be used by the package developer and variable without that prefix (e.g. CPPFLAGS) are reserved for the user. The following
Preprocessor switches.
C compiler switches.
Directives passed to the C or C++ compiler with additional directories
to be searched for header files. In most cases you need to specify an
absolute path. To specify a directory relative to the source
directory, you can use the $(SOURCES_DIR)
variable, which
refers to the directory, where Makefile.omk is located. This
variable applies to all compilations invoked in the current directory.
INCLUDES = -I$(SOURCES_DIR)/my_include_dir
Directives passed to the C or C++ compiler with preprocessor macro definitions. This variable applies to all compilations invoked in the current directory.
DEFS = -DDEBUG=1
Next: Dependency Tracking, Previous: Compiler Flags, Up: User’s Manual [Contents][Index]
OMK is probably most useful in projects consisting of multiple directories. For such projects, it is not easy to write from scratch classic Makefiles that provides all the needed features.
You can instruct OMK to descend to a (sub)directory by setting the
SUBDIRS
variable in Makefile.omk.
This variable contains a list of directories, in which compilation must be also invoked. Usually, names of subdirectories are used, but you can use any path specification here.
Compilation is invoked in these directories before it is invoked in the current directory.
See also AUTOMATIC_SUBDIRS.
This variable is set by OMK and can be used as the value of
SUBDIRS
variable. It contains a list of all direct
subdirectories, which contain Makefile.omk. This is especially
useful if you are combining several projects or components
together. In the root directory of your project, you just create
symbolic links the components from other projects and all the linked
directories automatically appears as the value of this variable.
SUBDIRS = $(ALL_OMK_SUBDIRS)
If this variable is set to ‘y’ and SUBDIRS
is not assigned
in Makefile.omk, then SUBDIRS
is assigned a default
value $(ALL_OMK_SUBDIRS)
.
Next: Configuration and Conditional Compilation, Previous: Recursing into Subdirectories, Up: User’s Manual [Contents][Index]
OMK automatically tracks dependencies of files in the project. Dependencies of object files are produced with gcc’s -Mx options. This means that whenever a header file is changed, OMK recompiles only those files, which included that file.
Dependencies are also maintained for libraries and binaries. To find the dependencies, OMK parses linker map files, so a change to some library causes relinking of all programs using that library.
Next: Advanced OMK Features, Previous: Dependency Tracking, Up: User’s Manual [Contents][Index]
In many projects, it is necessary to configure the compilation process. By
this configuring we mean, setting some parameters that influence the
output of compilation process. In GNU projects, configure
script is usually responsible for configuration. User provides some
parameters to configure
, which is run before compilation, and
this script does all steps needed to configure the sources and
make-system in the desired way.
OMK has its own configuration mechanism, which is described in this section. For future releases, we plan that this mechanism can make use of GNU Autoconf, but currently there is no directly integrated support for it.
There exist three different configuration files config.omk-default, config.target and config.omk. All of these have to be stored in the same directory as Makefile.rules. During compilation, these files are included in Makefile.rules in this order which means that variables assigned in the former files are overridden by those from later ones. All settings specified here apply to the whole compilation tree. Each file is intended for a different kind of configuration values:
Stores default configuration of compiled components. This file is automatically generated (see below) and should not be edited by users.
Stores default configuration for a project or target hardware. This file is intended to be stored in a version control system and should be modified only by the maintainer of the project.
For cross compiled projects, this file typically contains settings of variables like CC and CFLAGS.
This is a file for end users, where any default settings set in the above files can be overridden. This file should not be stored in version control system. The project should compile without having this file.
Besides variables defined in config.target, Makefile.omk
in any subdirectory can specify some configuration parameters. When
make default-config
is run, all these parameters are found and
together with their default values are stored as makefile variables in
config.omk-default. This file is included during compilation, so
if you don’t specify other values, these defaults are used. If you are
not satisfied with these defaults, you can override the values of
parameters either locally for your build in config.omk or
globally for all people working with the project in
config.target.
Next: Using Configuration Parameters, Previous: Configuration and Conditional Compilation, Up: Configuration and Conditional Compilation [Contents][Index]
To specify names and default values of configuration parameters use the
default_CONFIG
variable in Makefile.omk.
This variable contains a list of configuration parameters and their default values. The format of every item in this list is CONFIG_xxxx=value. You can name the parameter as you want, but it is good practice to start the name with ‘CONFIG_’ prefix.
OMK can automatically generate header files, with C preprocessor macro definitions according to the OMK’s configuration parameters. The actual content of generated header files depends on the form of the value. The possible forms are:
‘y’, ‘n’ or ‘x’
This defines boolean parameters. If the value of the parameter is
‘y’, the ‘#define CONFIG_xxx 1’ is generated, if it is
‘n’, no #define
is generated.
‘x’ is a special value called recessive ’n’. The meaning
is that this parameter influences the component in the current
directory (i.e. the corresponding #define
will be included in
LOCAL_CONFIG_H
; see LOCAL_CONFIG_H) but the default value
is not specified here. If the default value is not specified anywhere,
the behavior is the same as if ‘n’ is specified.
‘number’
Numeric parameters. The define looks like ‘#define CONFIG_xxx number’
‘text’
Text without quotes. The define looks like ‘#define CONFIG_xxx text’
‘"text"’
Text with quotes. The define looks like ‘#define CONFIG_xxx "text"’
Example of using default_CONFIG
. Makefile.omk reads like:
default_CONFIG = CONFIG_DEBUG=y CONFIG_SLOW=n default_CONFIG += CONFIG_NUM=123 CONFIG_ARCH=arm default_CONFIG += CONFIG_QUOTES="Text+quotes" SUBDIRS=subdir
and subdir/Makefile.omk like:
default_CONFIG = CONFIG_SUBDIR=y CONFIG_DEBUG=x
After running make default-config
, the content of
config.omk-default will be:
# Start of OMK config file # This file should not be altered manually # Overrides should be stored in file config.omk # Config for subdir CONFIG_SUBDIR=y #CONFIG_DEBUG=x # Config for CONFIG_DEBUG=y CONFIG_SLOW=n CONFIG_NUM=123 CONFIG_ARCH=arm CONFIG_QUOTES="Text+quotes"
Next: Common Variables, Previous: Specifying Configuration Parameters, Up: Configuration and Conditional Compilation [Contents][Index]
Configuration parameters can be used in two ways:
For the first use, your Makefile.omk may contain something like:
SUBDIRS = arch/$(CONFIG_ARCH) ifeq ($(CONFIG_DEBUG),y) DEFS += -DUSE_SIMULATOR endif
For the second use, there are several variables that control the generation of header files with configuration values. These variables are described here:
The value of this variable is the name of a header file, which will
contain all configuration parameters declared in the current directory
by default_CONFIG
. This header file is accessible only by files
in the current directory and it should be included like #include
"myconfig.h"
.
In Makefile.omk, the use of this variable can look like this:
LOCAL_CONFIG_H = myconfig.h
This variable is similar to LOCAL_CONFIG_H
. One difference is
that the generated header file is accessible to all sub-projects in
all directories, not only to the files in the same directory (the
header is stored in _compiled tree). The second difference is
that you have to specify, which configuration parameters you want to
appear in the header file.
This variable determines the configuration parameters that should be
stored in a header file specified by
config_include_HEADERS
. The xxx in the name of this
variable needs to be the same as the base name (without extension) of
the header file.
Example of using config_include_HEADERS
:
default_CONFIG = CONFIG_LINCAN=y CONFIG_LINCANRTL=n CONFIG_LINCANVME=n config_include_HEADERS = global.h global_DEFINES = CONFIG_OC_LINCAN CONFIG_OC_LINCANRTL
Here, we include only two out of the three configuration parameters defined in the current Makefile.omk. It is also possible to include configuration parameters defined in a different directory.
Previous: Using Configuration Parameters, Up: Configuration and Conditional Compilation [Contents][Index]
It is common practice to use config.target or config.omk to store project-wide settings. Here is the list of variables, which are commonly set here (but they can also be set elsewhere, e.g. in Makefile.omk).
You can easily “reconfigure” your project by changing the config.omk file. It is useful to have several configurations stored in different files and let config.omk be a symbolic link to the desired configuration.
CC
¶The name of C compiler.
CFLAGS
¶Command line options for C compiler.
CXX
¶The name of C++ compiler.
CPPFLAGS
¶Additional parameters (besides CFLAGS
) to by passed to C++
compiler.
Next: Properties of Specific Makefile.rules, Previous: Configuration and Conditional Compilation, Up: User’s Manual [Contents][Index]
In this section we list several OMK features, which are more complicated or rarely used so they were omitted in previous sections.
Next: Additional Variables, Previous: Advanced OMK Features, Up: Advanced OMK Features [Contents][Index]
make
only in a
subdirectory. Sometimes, it might be useful to rebuild the whole
project. You can either change working directory to the root of your
project and call make
there or, as a shortcut, you can use
W
variable (see W) to compile everything directly from a
subdirectory.
make W=1
make
in the top
directory or even in read-only directories after changing working
directory from your tree to the readonly media.
If this variable equals to ‘1’, the whole project is
(re)compiled, even if make
is called from a subdirectory.
Next: Adding Hooks to Passes, Previous: Organization of the Source Tree, Up: Advanced OMK Features [Contents][Index]
If this variable equals to ‘n’ (default is unset), then OMK uses
the leaf Makefile only when it is invoked by simple
make
command. Later, during recursive directory descent leaf
Makefile is not used and Makefile.rules is included
directly.
This feature is useful if you are integrating some non-OMK project into your project. You only add Makefile.omk files to the non-OMK project and don’t need to modify project’s original Makefiles.
This variable can be set either globally in a config.* file or locally in some Makefile.omk. In the latter case, it influences only subdirectories of the directory containing Makefile.omk.
This variable is set internally by OMK and its value is the absolute path to the directory with compiled sources. It can be used if you need to refer to sources files in some custom constructs in Makefile.omk.
include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
The same as SOURCES_DIR. Provided for Automake compatibility.
This variable is set internally by OMK and its value is the absolute path to the directory containing Makefile.rules currently used during compilation.
Identification the type of Makefile.rules used for compilation. Values are like ‘linux’, ‘rtems’, ‘sysless’, ... This variable is automatically generated during creation of Makefile.rules and can be used in configuration files (see Configuration and Conditional Compilation) or in Makefile.omk to tweak compilation for specific targets.
Next: Integration of Wvtest Framework, Previous: Additional Variables, Up: Advanced OMK Features [Contents][Index]
Sometimes it is necessary to run some special commands as a part of
compilation. Typical example might be a tool which generates source
files on the fly. OMK supports calling additional commands during
compilation by so called pass hooks. A pass hook is an ordinary
make target which is invoked as part of compilation during a particular
pass (see passes). Pass hooks can be defined by assigning their
names to xxx_HOOKS
variable.
Specifies one or more hooks (make targets) which are invoked during pass xxx. The working directory of commands or this target is under the _build tree.
In the example bellow header file generated_header.h is created during ‘include-pass’ by convert_data program. The program takes data_file.txt in the source directory as the input and creates the header file in the in the correct directory under the _build tree.
include-pass_HOOKS = generated_header.h generated_header.h: $(SOURCES_DIR)/data_file.txt convert_data < $^ > $@
Previous: Adding Hooks to Passes, Up: Advanced OMK Features [Contents][Index]
OMK has integrated support for Wvtest unit testing framework. It is a very minimalistic framework whose integration with OMK does not impose almost any particular policy of writing the tests. Wvtest tests are specified by the following two variables:
This variable has the same meaning as test_PROGRAMS with two
exceptions: (1) the program is automatically linked with the library
specified by WVTEST_LIBRARY
variable and (2) the program is
automatically executed by make wvtest
(see below).
Defines the name of a script (e.g. shell script) which is executed by
make wvtest
. Write the scripts so, that they can be run from
arbitrary directory, i.e. in the case of shell scripts ensure that the
wvtest.sh library is sourced like this:
. $(dirname $0)/wvtest.sh
Specifies the name of the library that is automatically linked with
wvtest_PROGRAMS
. The default is wvtest.
There is also an OMK pass called wvtest-pass
which consecutively
runs all wvtest_PROGRAMS
and wvtest_SCRIPTS
in the
traversed subdirectories of the current directory. Every program or
script is executed in a temporary directory under _build
directory with PATH
variable modified to include
_compiled/bin as the first component and LD_LIBRARY_PATH
modified to include _compiled/lib as the first component. This
allows the tests to run the bin_PROGRAMS
without explicitly
specifying their full path and to use shared libraries without the path
as well.
When make is invoked as make wvtest
it runs make
wvtest-pass
under the control of wvtestrun script, which must be
present in the same directory as Makefile.rules. This script
suppresses the normal output of passed tests and prints only their
summary. For failed tests, the full output is shown. Additionally, when
the output is written to a terminal, the status of each test is
displayed in color for easy inspection.
Next: Running OMK under Windows OS, Previous: Advanced OMK Features, Up: User’s Manual [Contents][Index]
In previous sections, general properties of Makefile.rules were documented. This section contains documentation to features found only in some particular Makefile.rules.
Next: System-Less, Previous: Properties of Specific Makefile.rules, Up: Properties of Specific Makefile.rules [Contents][Index]
This Makefile.rules is used not only for Linux as the name suggests, but also for other Unices and even for Windows.
The name of the operating system (OS) where make was invoked.
Should specify the name of OS where the resulting binary should be used. If not specified manually, it equals to BUILD_OS.
Lists subdirectories with QT project (.pro) file. OMK will generate
there Makefile by calling qmake
with correct
parameters to interface QT application to the rest of the compilation
tree. Then make
is called there to compile QT
application. Variable ‘QTDIR’ must be set to the directory with
QT installation (e.g. /usr/share/qt4 on Debian).
Lists the names of the files (persumably scripts) to be copied to _compiled/bin.
Next: RTEMS, Previous: Linux, Up: Properties of Specific Makefile.rules [Contents][Index]
This Makefile.rules is designed for compilation of code for (small) micro-controllers without operating systems. See http://rtime.felk.cvut.cz/hw/index.php/System-Less_Framework for more information about our framework, which uses this rules.
Previous: System-Less, Up: Properties of Specific Makefile.rules [Contents][Index]
TODO
Next: Interfacing OMK to popular IDEs, Previous: Properties of Specific Makefile.rules, Up: User’s Manual [Contents][Index]
It is possible to use OMK under Windows OS with MinGW (see http://www.mingw.org/). Unfortunately, the compilation speed is much lower than on UNIX systems.
TODO: Is it necessary to install anything special?
Next: Troubleshooting & Knows Bugs, Previous: Running OMK under Windows OS, Up: User’s Manual [Contents][Index]
Next: Eclipse/CDT, Previous: Interfacing OMK to popular IDEs, Up: Interfacing OMK to popular IDEs [Contents][Index]
KDevelop has support for custom build systems. To use KDevelop to develop projects using OMK follow these steps. These steps are valid for version 3.5.0 of KDevelop, but for previous versions it doesn’t differ much.
make
.
CONFIG_xxx
variables and their values.
Next: Emacs, VIM, etc., Previous: KDevelop, Up: Interfacing OMK to popular IDEs [Contents][Index]
TODO
Previous: Eclipse/CDT, Up: Interfacing OMK to popular IDEs [Contents][Index]
Since OMK compilation is started by executing make
command,
many common editors can work easily with OMK.
Under Emacs, you can use compile
or recompile
commands as you are used to do.
Previous: Interfacing OMK to popular IDEs, Up: User’s Manual [Contents][Index]
make clean
in the directory with errors. The
reason for this behavior is that OMK remembers dependencies of every
file. After renaming something, the original name is still stored in
dependencies, but make doesn’t know how to create this non-existent
source.
To compile something manually, you can run OMK by make
V=2
. This will print all commands executed together with directory
navigation messages. Find the command you want to execute manually in
the output. To run it, you need to change the working directory to the
correct one in the _build tree. The correct directory can be
found in make output on the line ‘Entering directory’ preceding
the desired command.
make
distclean
before you run make
.
Next: Development, Previous: User’s Manual, Up: Ocera Make System [Contents][Index]
Since this manual still doesn’t cover all aspects of OMK, we include here a README.rules file, which was written for the first version of OMK.
Important notice: This make system uses features found in recent versions of GNU Make program. If you encounter problems with package building, check, that you use correct version of Make program. The Make older than version 3.80, could not be used. Even Make version 3.80 has annoying bug which causes building fail with misleading message "virtual memory exhausted". Please, upgrade at least to version 3.81 of GNU Make.
There is list of features which we want to solve with our make system:
FIXME (our CAN framework includes more libraries common with our other projects, we need to separate some utility libraries etc.)
There is probably only one alternative fully supporting above requirements and it is GNU Autoheader...Automake...Autoconf... system. But it is complicated and requires big amount of support files. It would be acceptable if it could be easily used for OCERA framework. But there are important show stoppers for that system:
The problem calls for some solution, which would have minimal impact on other components and would be elegant and would be maintainable and small, because our main goal is components development and not make systems development.
There is result of our trial. It is OMK make system.
The Makefile and Makefile.omk files should be in all source
directories. Common Makefile.rules file is required in the toplevel
sources directory. Alternatively this file could be moved
to link tree pointing into readonly media or can be anywhere
else if MAKERULES_DIR
and SOURCES_DIR
are specified.
Syntax of Makefile.omk files is for usual cases compatible to Automake’s Makefile.am descriptions. There are specific targets for RT-Linux and Linux kernel related stuff
Makefile.omk user defined variables
SUBDIRS
¶list of subdirectories intended for make from actual directory
lib_LIBRARIES
¶list of the user-space libraries
list of the user-space shared libraries
kernel_LIBRARIES
¶list of the kernel-space libraries
rtlinux_LIBRARIES
¶list of the RT-Linux kernel-space libraries
include_HEADERS
¶list of the user-space header files
nobase_include_HEADERS
¶headers copied even with directory part
kernel_HEADERS
¶list of the kernel-space header files
rtlinux_HEADERS
¶list of the RT-Linux kernel-space header files
bin_PROGRAMS
¶list of the require binary programs
utils_PROGRAMS
¶list of the development utility programs
kernel_MODULES
¶list of the kernel side modules/applications
rtlinux_MODULES
¶list of RT-Linux the kernel side modules/applications
xxx_SOURCES
¶list of specific target sources
INCLUDES
¶additional include directories and defines for user-space
kernel_INCLUDES
¶additional include directories and defines for kernel-space
rtlinux_INCLUDES
¶additional include directories and defines for RT-Linux
default_CONFIG
¶list of default config assignments CONFIG_XXX=y/n ...
The Makefile is same for all sources directories and is only 14 lines long. It is there only for convenience reasons to enable call "make" from local directory. It contains code which locates Makefile.rules in actual or any parent directory. With standard BASH environment it works such way, that if you get into sources directory over symbolic links, it is able to unwind yours steps back => you can make links to readonly media component directories, copy Makefile.rules, Makefile and toplevel Makefile.omk, adjust Makefile.omk to contain only required components and then call make in top or even directories after crossing from your tree to readonly media.
The system compiles all files out of source directories. The actual
version of system is adapted even for OCERA tree mode if
OCERA_DIR
variable is defined in Makefile.rules
There are next predefined directory name components, which can be adapted if required
BUILD_DIR_NAME = _build
prefix of directory, where temporary build files are stored
COMPILED_DIR_NAME = _compiled
prefix of directory, where final compilation results are stored
GROUP_DIR_NAME = yyy
this is used for separation of build sub-trees in OCERA environment where more Makefile.rules is spread in the tree
Next directories are used:
KERN_BUILD_DIR := $(MAKERULES_DIR)/$(BUILD_DIR_NAME)/kern
directory to store intermediate files for kernel-space targets
USER_BUILD_DIR := $(MAKERULES_DIR)/$(BUILD_DIR_NAME)/user
directory to store intermediate files for user-space targets
USER_INCLUDE_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/include
directory to store exported include files which should be installed later on user-space include path
USER_LIB_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/lib
same for user-pace libraries
USER_UTILS_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/bin-utils
utilities for testing, which would not probably be installed
USER_BIN_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/bin
binaries, which should go into directory on standard system PATH (/usr/local/bin, /usr/bin or $(prefix)/bin)
KERN_INCLUDE_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/include-kern
directory to store exported include files which should be installed later on kernel-space include path
KERN_LIB_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/lib-kern
same for kernel-pace libraries
KERN_MODULES_DIR := $(MAKERULES_DIR)/$(COMPILED_DIR_NAME)/modules
builded modules for Linux kernel or RT-Linux system
There is more recursive passes through directories to enable mutual dependant libraries and binaries to compile. Next passes are defined
generates config.omk-default or xxx-default (FIXME) configuration file
checks and creates required build directories
copies header files to USER_INCLUDE_DIR
and KERN_INCLUDE_DIR
builds objects in USER_BUILD_DIR/relative path and creates libraries in USER_LIB_DIR
links respective binaries in USER_{BIN,UTILS}_DIR directory. If some object file is missing it compiles it in USER_BUILD_DIR/relative path
builds libraries for kernel space targets
builds kernel modules
The amount of passes is relatively high and consumes some time. But only other way to support all required features is to assemble one big toplevel Makefile, which would contain all components and targets cross-dependencies.
Drawbacks of designed make system
The last point is critical. I have not noticed it first, because I use Slackware-9.2 and it contains latest released version of MAKE (version 3.80). The problem appears when I have tried to build bigger libraries. There is bug in version 3.80, which results in misleading error "Virtual memory exhausted". It is known bug with ID 1517
* long prerequisite inside eval(call()) => vm exhausted, Paul D. Smith
I have optimized some rules to not push memory to the edge, but there could be still issues with 3.80 version.
I have downloaded latest MAKE CVS sources. The compilation required separate lookup and download for .po files and full Autoheader... cycle. I have put together package similar to release. Only ./configure –prefix=... and make is required. CVS sources contains version 3.81beta1. You can download prepared sources archive from http://paulandlesley.org/make/make-3.81beta1.tar.bz2 Or you can get our local copy from http://cmp.felk.cvut.cz/~pisa/can/make-3.81beta1.tar.gz
The archive contains even "make" binary build by me, which should work on other Linux distributions as well. Older version of MAKE (3.79.x released about year 2000) found on Mandrake and RedHat are not sufficient and do not support eval feature. I do not expect, that Debian would be more up-to-date or contain fixes to MAKE vm exhausted bug.
The local CTU archive with our CAN components prepared for inclusion into OCERA SF CVS could be found in my "can" directory
http://cmp.felk.cvut.cz/~pisa/can/ocera-can-031212.tar.gz
The code should build for user-space with new make on most of Linux distros when make is updated.
If you want to test compile for RT-Linux targets, line
#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
in Makefile.rules has to be activated and updated to point RT-Linux directory containing "rtl.mk". There is only one library ("ulutrtl") and test utility compiled for RT-Linux (can/utils/ulut/ul_rtlchk.c).
The next line, if enabled, controls compilation in OCERA project tree
#OCERA_DIR := $(shell ( cd -L $(MAKERULES_DIR)/../../.. ; pwd -L ) )
The LinCAN driver has been updated to compile out of source directories.
Please, check, if you could compile CAN package and help us with integration into OCERA SF CVS. Send your comments and objections.
The OMK system has been adapted to support actual OCERA configuration process. I am not happy with ocera.mk mix of defines and poor two or three rules, but OMK is able to overcome that.
The OMK system has integrated rules (default-config) to build default
configuration file. The file is named config.omk-default for
the stand-alone compilation. The name corresponds to OCERA config +
"-default" if OCERA_DIR is defined. This file contains statements
from all default_CONFIG
lines in all Makefile.omk. The
file should be used for building of own config.omk file, or as
list for all options if Kconfig is used.
Next: Variable Index, Previous: Original README, Up: Ocera Make System [Contents][Index]
This section is far from complete. Its purpose is to document internals of Makefile.rules as well as other things needed only by people who hack OMK itself.
A pass is created by instantiation of omk_pass_template
with
pass-name as one of arguments. This defines several targets which
are described here:
pass-name
Target used to invoke the individual pass either from command line or from inside of Makefile.rules.
pass-name-submakes
Invoked recursively from pass-name. The reason for this is the fact that
pass-name-this-dir
This target calls make recursively once again with pass-name-local target, which does the real-work. Make’s working directory is set to the corresponding directory in _build tree and the -local
pass-name-dirname-subdir
This target is responsible for recursive invocation of make
in
subdirectories specified in SUBDIRS
variable.
Previous: Development, Up: Ocera Make System [Contents][Index]
Jump to: | A B C D I K L M N O Q R S T U V W X |
---|
Jump to: | A B C D I K L M N O Q R S T U V W X |
---|
When USE_LEAF_MAKEFILES is set to ‘n’, this Makefile can be omitted in subdirectories. See USE_LEAF_MAKEFILES.
In future, we are planning some optimization that allows OMK to traverse the directories only once and thus decrease compilation time.