- Main Page
- Modules
- Data Structures
- Files

# Make Environment
[Introduction]

### Introduction

pico]OS comes with a powerful make environment based on GNU Make. The make files are universal to all target platforms and most compilers. They are the first step to platform independent software developement.

The core files of the make environment are located in the subdirectory `picoos/make`. The main makefile for pico]OS is stored in the pico]OS root directory, and every platform port comes with a makefile that teaches the platform dependent environment to the make system.

The makefiles were tested with GNU make 3.80
For MS Windows platforms, you can download a Windows version of make from http://mingw.sourceforge.net/download.shtml

### Compiling pico]OS

To compile the pico]OS library, you need to execute the makefile in the pico]OS root directory. The makefile knows three targets, that are:

- `all` builds the pico]OS library
- `clean` deletes all binaries generated by previous make run
- `docu` builds the documentation using the doxygen tool

The targets `all` and `clean` need the additional parameter `PORT` that specifies the destination port. For example, a valid make call would look like this (at the DOS prompt):

    C:\picoos-1.0.0> make all PORT=6502

This will build pico]OS for the 6502 processor family. After the successful execution of make you will find two new subdirectories: The `obj` directory contains all generated object files, and the `lib` directory the final library.

There is a second option available on the command line: `BUILD=DEBUG` will build a debug version of the operating system, and a `BUILD=RELEASE` will build a release version. Note that the debug version is the default when this option is not given.

Note: The name of the port is the name of its subdirectory in the `ports` directory.

### Compiling pico]OS from within an other project

Usually you will have more than one project that uses pico]OS. pico]OS is only installed one time on the harddisk, and you have several projects that link against the pico]OS library. Every project has different requirements on the RTOS, thus each project has its own configuration files for pico]OS. To avoid binary clashes with the other projects, it is required to tell make where the configuration files are located and where the generated pico]OS library shall be stored. This is done by two additional arguments in the command line of the make call:

    C:\picoos-1.0.0> make all PORT=6502  RTOS_OUTPUTDIR=/repository/myproj/RTOS   \
                                         DIR_CONFIG=/repository/myproj/config

The parameter `RTOS_OUTPUTDIR` tells make where to store the generated pico]OS library. `DIR_CONFIG` specifies the directory where the configuration files can be found. Note that the paths should be absolute paths, or, relative paths from the view of pico]OS (and that is mostly impracticable).

### Building An Application

The pico]OS library is only the first step to an executable. The make environment supports also the linking of object files and libraries to get an executable. For example, you have written a 'hello world' program that uses pico]OS. To compile and link the file `hello.c` you need to perform the following steps:

- create a subdirectory somewhere in the `picoos` directory tree
- place your file `hello.c` in this directory
- generate and place a makefile (or copy and rename the file `outfile.mak` from the examples directory) in the same directory. The makefile should look like this:

    01 # ---------------------------------------------------------------------------
    02 # PRECONDITION SETUP
    03 # ---------------------------------------------------------------------------
    04
    05 # Set relative path to the picoos root directory  -> YOU NEED TO CHANGE THIS!
    06 RELROOT = ../../../picoos/
    07
    08 # Set fixed target platform                       -> YOU MAY CHANGE THIS!
    09 #PORT = x86w32  (->need to be specified at the command line)
    10
    11 # Set fixed build mode (DEBUG or RELEASE)         -> YOU MAY CHANGE THIS!
    12 #BUILD = DEBUG  (->need to be specified at the command line)
    13
    14 # Get pico]OS path from environment (if it is set)
    15 ifneq '$(strip $(PICOOS))' ''
    16 RELROOT := $(PICOOS)/
    17 endif
    18
    19 # Include common makefile
    20 include $(RELROOT)make/common.mak
    21
    22
    23
    24 # ---------------------------------------------------------------------------
    25 # PROJECT SETTINGS
    26 # ---------------------------------------------------------------------------
    27
    28 # To include the pico]OS nano layer, set this define to 1
    29 NANO = 0
    30
    31 # Set target filename (the name of the executable, without extension)
    32 TARGET = hello
    33
    34
    35 ### Set up lists of source files ###
    36
    37 # Set list of C source files / assembler files
    38 SRC_TXT = hello.c
    39
    40 # Set list of header files used by the C source files
    41 SRC_HDR =
    42
    43 # You may add some already compiled object files here
    44 SRC_OBJ =
    45
    46 # Add the libraries you are using in your program here
    47 SRC_LIB =
    48
    49
    50 # Set additional C-defines
    51 CDEFINES +=
    52
    53 # Set additional include paths
    54 DIR_USRINC +=
    55
    56 # Set the directory that contains the configuration header files.
    57 # If this variable is not set, the default configuration files will be
    58 # taken from the port/default directory.
    59 # If you wish to use your own configuration files, you can place them
    60 # in the current directory. Then, set  DIR_CONFIG = $(CURRENTDIR)
    61 DIR_CONFIG =
    62
    63 # Set the output directory for the generated binaries. If you do not
    64 # set this variable, the files will be stored in the pico]OS root
    65 # root directory structure (pioos/out, picoos/lib, picoos/obj)
    66 DIR_OUTPUT = $(CURRENTDIR)/bin
    67
    68 # Include pico]OS based modules. Set here the list of modules
    69 # (libraries) you want to use in your project. Note that the module
    70 # name is the name of the directory where the sources and the makefile
    71 # is stored. The makefile must be named "makefile" or "makefile.pico"
    72 # Example:  MODULES += $(RELROOT)../lcdinterface
    73 MODULES +=
    74
    75 # Execute external makefiles to build other libraries. Add here
    76 # the filenames (with path) of other makefiles you wish to execute.
    77 EXEC_MAKEFILES +=
    78
    79
    80
    81 # ---------------------------------------------------------------------------
    82 # BUILD THE EXECUTABLE
    83 # ---------------------------------------------------------------------------
    84
    85 include $(MAKE_OUT)
    86

The lines 6, 20, 32, 38 and 85 are mandatory. The `PORT` variable may also be set at the command line when make is invoked, even like the `BUILD` mode. `RELROOT` sets the relative way to the pico]OS root directory. Line 20 includes the main makefile of the make environment. In line 29 you can enable the nano layer of pico]OS that is available with pico]OS 0.8.0. Line 32 sets the name of the executable to generate. Note that only the basename must be specified, the file extension is added automatically. Lines 37 to 47 set the source files that shall be linked to the pico]OS library. `SRC_TXT` specifies a list of sourcecode files (in textual form). `SRC_OBJ` and `SRC_LIB` specify a list of existing object files and libraries that shall be linked to the executable. `SRC_HDR` is a list of the header files that are used by your project. In line 51 you can set preprocessor defines to control the compilation of your software. The defines are passed to the compiler and can be checked with the if / endif preprocessor command in the C source files. Additional include paths for header files can be set in line 54. Please use the preprocessor command `include` `<header.h>` to include a header file that is located in the global include path. If your application uses an other configuration than the default, you can place your own configuration files `poscfg.h` and `noscfg.h` into your project directory. You must then set `DIR_CONFIG` (line 61) to the place where the configuration files are located. Note that this path is absolute to the pico]OS root, so if your project directory is `picoos-1.0.0/myproject`, you would set `DIR_CONFIG = myproject`. To make things easier, the pre-defined variable `CURRENTDIR` points always to the current directory. In line 66 you may specify your own output directory for the generated binaries. If you do not set this variable, the binaries will be saved in the directory `picoos-1.0.0/out/portname/rel_or_deb/`. Finally, the line 85 includes the makefile that starts the build process.

There is something special you should notice: You can tell the makefile to execute other, external makefiles. For example, this is useful to start a makefile that shall compile a library that is used by your program. Usually, you would add the library to the `SRC_LIB` variable in line 47. The corresponding library makefile can be added to the variable `EXEC_MAKEFILES` in line 77. Every time this makefile is executed, also the library makefile will be executed, ensuring the library is up to date.

And there is another special thing: You can divide your project into smaller modules. The modules are compiled to libraries and the libraries are then linked to the main program. For your own libraries, you should use the template makefile 'library.mak' in the examples directory. A description of this file you will find in the next section, see below. If you are using this modularized architecture, you can simply add the modules you wish to link to your main program to the variable `MODULES` in line 73. You do not need to set also the library name in line 47, this does the pico]OS make for you.

To build your application, simply invoke make with the target `all` to generate the executable. The makefile supports also the target `clean` that cleans your last build again. Note: If you do not have set the `PORT` and the `BUILD` mode in the makefile, you need to specify them on the make command line. In this case, a valid make call would look like this: `" make all PORT=x86w32 BUILD=DEBUG "`

### Building A Library or Module

As described above, sometimes it is useful (or maybe necessary) to divide a project into some smaller modules or so called libraries. For this purpose pico]OS provides an example makefile (see examples directory, file `library.mak`) that looks like this:

    01 # ---------------------------------------------------------------------------
    02 # PRECONDITION SETUP
    03 # ---------------------------------------------------------------------------
    04
    05 # Set relative path to the picoos root directory  -> YOU NEED TO CHANGE THIS!
    06 RELROOT = ../../../picoos/
    07
    08 # Get pico]OS path from environment (if it is set)
    09 ifneq '$(strip $(PICOOS))' ''
    10 RELROOT := $(PICOOS)/
    11 endif
    12
    13 # Include common makefile
    14 include $(RELROOT)make/common.mak
    15
    16
    17
    18 # ---------------------------------------------------------------------------
    19 # LIBRARY SETTINGS
    20 # ---------------------------------------------------------------------------
    21
    22 # Set target file name (library filename without extension)
    23 TARGET =
    24
    25
    26 ### Set up lists of source files ###
    27
    28 # Set list of C source files / assembler files
    29 SRC_TXT =
    30
    31 # Set list of header files used by the C source files
    32 SRC_HDR =
    33
    34 # You may add some already compiled object files here
    35 SRC_OBJ =
    36
    37
    38 # Set additional C-defines
    39 CDEFINES +=
    40
    41 # Set additional include paths
    42 DIR_USRINC +=
    43
    44 # Set the output directory for the generated binaries. If you do not
    45 # set this variable, the files will be stored in the pico]OS root
    46 # root directory structure (pioos/out, picoos/lib, picoos/obj)
    47 # Note: Please keep the ifeq/endif pair. This allows to set the
    48 # output directory from outsite (may be by a project makefile).
    49 ifeq '$(strip $(DIR_OUTPUT))' ''
    50 DIR_OUTPUT = $(CURRENTDIR)/bin
    51 endif
    52
    53
    54
    55 # ---------------------------------------------------------------------------
    56 # BUILD THE LIBRARY
    57 # ---------------------------------------------------------------------------
    58
    59 include $(MAKE_LIB)
    60

Like above, the lines 6, 14, 23, 29 and 59 are mandatory. `RELROOT` sets the relative way to the pico]OS root directory. Line 14 includes the main makefile of the make environment. Line 23 sets the name of the generated library. Note that only the basename must be specified, the file extension is added automatically. Lines 28 to 35 set the source files that shall be added to the library. `SRC_TXT` specifies a list of sourcecode files (in textual form), and `SRC_HDR` is set to a list of C header files that are referenced by the C source files. The variable `SRC_OBJ` can be filled with some precompiled object files (but this feature you won't really use). In line 39 you can set preprocessor defines to control the compilation of your software. The defines are passed to the compiler and can be checked with the if / endif preprocessor command in the C source files. Additional include paths for header files can be set in line 42. Please use the preprocessor command `include` `<header.h>` to include a header file that is located in the global include path. In line 50 you may specify your own output directory for the generated binaries. If you do not set this variable, the binaries will be saved in the directory `picoos-1.0.0/out/portname/rel_or_deb/`. Finally, the line 59 includes the makefile that starts the build process.
To generate the library manually, you can call the makefile with the port and build mode parameter: `" make all PORT=x86w32 BUILD=DEBUG "` . As an option, you may also set the NANO flag to 1 (`NANO=1`) if the library uses the nano layer of pico]OS.
But in most cases you will start the makefile from within a main makefile that is used to compile the whole project. Take the file `outfile.mak` from the examples directory as a template for such a main makefile. When you add this library makefile (that means, the name and path of the directory where this library makefile is located) to the `MODULES=` variable in the main makefile, the library makefile will be automatically executed when the project is built. All command line parameters that are set to execute the main makefile will also be passed to the library makefiles.

### Format Of File port.mak

Each platform port need to have a special version of the file port.mak. This file is used to tell the make environment the settings needed to compile files for the platform. This settings include: The compiler / linker / archiver to use, runtime libraries to link to the exectuable, file extension names, and various port specific settings. Here is an example how the file `port.mak` may look like:

    01  #
    02  # port.mak for the 6502 port
    03  #
    04
    05  # Compiler: Define place of compiler
    06  CC65 = h:/cc65
    07
    08  # Compiler: Define target type
    09  TG = c64
    10
    11  # Set to 1 to include generic pico]OS "findbit" function
    12  GENERIC_FINDBIT = 0
    13
    14  # Define extensions
    15  EXT_C   = .c
    16  EXT_ASM = .s
    17  EXT_OBJ = .o
    18  EXT_LIB = .lib
    19  EXT_OUT = .$(TG)
    20
    21  # Define tools: compiler, assembler, archiver, linker
    22  CC = $(CC65)/bin/cc65
    23  AS = $(CC65)/bin/ca65
    24  AR = $(CC65)/bin/ar65
    25  LD = $(CC65)/bin/ld65
    26
    27  # Define to 1 if CC outputs an assembly file
    28  CC2ASM = 1
    29
    30  # Define general options
    31  OPT_CC_INC   = -I
    32  OPT_CC_DEF   = -D
    33  OPT_AS_INC   = -I
    34  OPT_AS_DEF   = -D
    35  OPT_AR_ADD   =
    36  OPT_LD_SEP   =
    37  OPT_LD_PFOBJ =
    38  OPT_LD_PFLIB =
    39  OPT_LD_FIRST = $(CC65)/lib/$(TG).o
    40  OPT_LD_LAST  = $(CC65)/lib/$(TG).lib
    41
    42  # Set global defines for compiler / assembler
    43  CDEFINES =
    44  ADEFINES =
    45
    46  # Set global includes
    47  CINCLUDES = $(CC65)\include .
    48  AINCLUDES = $(CC65)\include .
    49
    50  # Distinguish between build modes
    51  ifeq '$(BUILD)' 'DEBUG'
    52    CFLAGS   += -g
    53    AFLAGS   += -g
    54    CDEFINES += _DBG
    55    ADEFINES += _DBG
    56  else
    57    CDEFINES += _REL
    58    ADEFINES += _REL
    59  endif
    60
    61  # Define Compiler Flags
    62  CFLAGS += -t $(TG) -O -A -T -o
    63
    64  # Define Assembler Flags
    65  ASFLAGS += -t $(TG) -o
    66
    67  # Define Linker Flags
    68  LDFLAGS = -t $(TG) -Ln $(DIR_OUT)/$(TARGET).lbl -m $(DIR_OUT)/$(TARGET).map -o
    69
    70  # Define archiver flags
    71  ARFLAGS = a

The lines 12, 15 - 19, 22 - 25, 28, 31 - 40, 54 - 55, 57 - 58, 62, 65, 68 and 71 are mandatory. If `GENERIC_FINDBIT` (line 12) is enabled (= set to 1), the file fbit_gen.c is compiled and linked to the pico]OS library. Some compilers need a special handling to compile C-files. If `CC2ASM` is set to 1, the make system will first generate assembly files from C source files before generating the final object file from the intermediate assembly file.