Managing the Makefile for ModusToolbox® v2.x – KBA229177

Version 7

    Author: JimT_21     Version: *C

     

    Translation - Japanese: ModusToolbox v2.x の Makefile を管理する - Community Translated (JA)

     

    The ModusToolbox™ build infrastructure creates a project based on information in a makefile. This document explains how you can manage the makefile to accomplish common tasks. This document is in the form of questions and answers. As appropriate, the answer provides a common use case, what you need to know to get the task done, and an example snippet.

    This document uses the following terms:

    • makefile directory: the folder that contains the makefile; this may be a code example (starter application) or your project
    • project directory: the folder created during the project creation process; contains all files for the project, including a copy of the makefile
    • .lib file: a text file that contains a URL to a GitHub repository and a tag or SHA for a specific commit
    • auto-discovery: the process by which the build infrastructure automatically finds files

    When you create a project using the ModusToolbox build system, all files required by the project are copied into the project directory. This includes the original makefile found in the code example (starter application).

     

    1. What is the makefile and how do I use it?

    The makefile describes how to create and build a project. It contains information about what files to use, what libraries to include, what build tools to use, and so forth. This makefile is specific to the ModusToolbox build system. For general background and reference information on the command line interface, see Running ModusToolbox from the Command Line.

     

    Cypress provides many code examples on GitHub, which can be thought of as starter applications. Each contains a makefile and source files specific to the application. A code example is not self-contained. When you use the ModusToolbox IDE’s New Application wizard, or the stand-alone Project Creator tool, the build system is invoked, and all files required for the project appear in the project directory. If you use the ModusToolbox IDE, this folder is in your Eclipse workspace. If you use the Project Creator, the project directory is wherever you put it. You can then add the files to your preferred IDE, or work from the command line.

     

    The makefile controls the project creation and build process. The original makefile from the code example is duplicated in the project directory.

     

    2. Which makefile should I edit, the one in the code example or the one in the project directory?

    Typically, you create a project from a code example, and then edit the makefile in your project directory. The changes are local to your project.

     

    However, you can download a local copy of the code example from GitHub and edit that makefile. If you edit the makefile in your copy of the code example, any project built from that example has your changes.

     

    In other questions and answers, this document refers to the makefile directory. This could be either your project directory or a local copy of the code example.

     

    3. How do I add files to the project so that auto-discovery finds them?

    The build infrastructure automatically finds all source files in the makefile directory. This includes .c, .cpp, .h, .hpp, .S, .s, .o, and .a files.

     

    As a result, a simple solution is to add the files to the makefile directory. The search is recursive, so you can add the files anywhere in the makefile directory tree and the make build command finds them.

     

    However, the common use case is that you have files that exist outside the makefile directory; for example, a collection of source code on a company server.

     

    To discover files outside the makefile directory, you can add the path to the external directory using the CY_EXTAPP_PATH variable.

     

    CY_EXTAPP_PATH=./../external_source_folder

     

    Use the SOURCES and INCLUDES variables to explicitly specify the source and header files to the build process from a location not searched by the build system.

     

    The SOURCES value must be a space-separated list of specific files. Paths can be absolute or relative to the makefile directory to locate the files. You can create a search pattern with wildcards to find multiple files.

     

    SOURCES=$(wildcard ../MySource1/*.c) $(wildcard ../MySource2/*.c)

     

    Use the INCLUDES variable to specify the folder for header files. The value is a space-separated list of relative paths to the directories.

     

    INCLUDES=../MySource1 ../MySource2

     

    You can also specify that certain files or folders should be ignored. See How do I make sure auto-discovery ignores certain files?

     

    For more information refer to the Section Adding Source Files in the ModusToolbox User Guide.

     

    4. How can I add a path that contains spaces?

    Spaces in paths are problematic with many build tools, so avoid them whenever possible. If you must have spaces in a path, use the $(wildcard) function to properly escape paths that contain spaces.

     

    INCLUDES=$(wildcard ../My Source/)

     

    CY_COMPILER_PATH=$(wildcard C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.3/arm/bin)

     

    5. How can I use an absolute path when the variable value requires a relative path?

    The files you want to add may live someplace specific on a company server or your local machine. An absolute path can be easier to manage. In this case, you can create a make variable configured with an absolute path and use that as part of your “relative” path.

     

    ABS_PATH=C:/<path_to_source>/ExternalSourceFiles/

    SOURCES=$(ABS_PATH)/external_source.c

     

    6. How are slashes handled by the build system?

    On Windows, ModusToolbox uses Cygwin make under the hood. Cygwin is a POSIX-compatible environment. POSIX paths use forward slash “/” as the separator for paths. Therefore, “/” must be used when specifying any path in the makefile.

     

    Windows path names use backslash “\” as the path separator. In cases when there is a long absolute path and you need to replace “\” with “/”, you can use the $(subst) function to make the conversion easier.

     

    WIN_PATH=C:\Users\<some_long_path>\HeaderFiles

    HEADER_FILE=$(subst \,/,$(WIN_PATH))

    INCLUDES=$(HEADER_FILE)

     

    When specifying a value for ModusToolbox Make variables using the System Variable in the Environment Variable dialog, make sure you use forward slashes. For example, to specify the tools directory to be used, you can make use of the CY_TOOLS_PATHS system variable. Note that the value you enter must use forward slashes.

     

    7. How do I make sure auto-discovery ignores certain files?

    For example, you may have a subfolder with files used by a test or verification system, and you don’t want those compiled into your executable.

    Use the CY_IGNORE variable. The value is a space-separated list of folders and/or specific files you want ignored by auto-discovery. Use paths relative to the makefile directory. You can create a search pattern with wildcards to ignore multiple files.

     

    CY_IGNORE=./filename.c ./TestFolder

    CY_IGNORE+=$(wildcard ./lib/lib1/tests/*.c)

     

    8. How do I add an external library using a .lib text file?

    The ModusToolbox build infrastructure uses the git version control system. A .lib file is typically a single line of text that represents a URL to a git repository, and a specific commit within that repository. The .lib files provided by Cypress always point to a publicly available Cypress-owned repository, typically on GitHub. For example, this .lib file imports the latest version of the Peripheral Driver Library into a project.

     

    https://github.com/cypresssemiconductorco/psoc6pdl/#latest-v1.X

     

    To add your own library, create a .lib file that points to a git repository. Place the .lib file in the makefile directory. For example:

    https://gitrepos.company.com/mylibrary/#52fac15a7c06ecac951bc67fff94097e9f671efb

     

    The make getlibs command finds and processes all .lib files and uses the git command to clone or pull the code as appropriate. Then, it checks out the specific hash or tag listed in the .lib file. The source files are copied into the libs folder at the root of the project folder. The ModusToolbox new project flow and the Library Manager invoke make getlibs automatically.

     

    9. How do I add an external library by specifying files and file paths?

    See How do I add files to the project so that auto-discovery finds them?

     

    10. How do I add a precompiled binary to my project?

    The build infrastructure automatically finds .o and .a binary files in the makefile directory. A simple solution is to add the files to the makefile directory.

    However, a common use case is that the binary file(s) exist outside the makefile directory. Use the LDLIBS variable to specify application-specific precompiled binaries. The LDLIBS value must be a space-separated list of specific files. Use paths relative to the makefile directory to locate the files. You can create a search pattern with wildcards to find multiple files. These files are included in the link process.

     

    LDLIBS=../MyBinaryFolder/binary.o

    LDLIBS+=$(wildcard ../lib/*.a)

     

    If you need to include the header files for the binary, use the INCLUDES variable. See How do I add files to the project so that auto-discovery finds them?

     

    11. How do I specify a set of build tools?

    The makefile by default uses GCC Arm® 7.2.1, which comes packaged with ModusToolbox 2.0. In the makefile, the combination of variables TOOLCHAIN and CY_COMPILER_PATH are used to specify the build tools you want to use.

    The other supported toolchains include the ARM Compiler and the IAR compiler, which must be installed separately.

    The options for the TOOLCHAIN variable include:

    • TOOLCHAIN=GCC_ARM (Uses GCC 7.2.1 provided with ModusToolbox IDE)
    • TOOLCHAIN=ARM (Uses ARM Compiler)
    • TOOLCHAIN=IAR (Uses IAR Compiler)

     

    Based on the compiler chosen, specify the absolute path to the compiler’s bin directory using the CY_COMPILER_PATH variable.

    CY_COMPILER_PATH=$(wildcard C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.3/arm/bin)

    CY_COMPILER_PATH=$(wildcard C:/Keil/ARM/ARMCC/bin)

     

    12. How do I tell the build system where custom build tools are?

    To use a custom toolchain that is not directly supported by ModusToolbox, follow these steps:

    1. In your project directory, navigate to libs\psoc6make\make\toolchains\. Note: These files do not exist in the original code example folder. They are added to the project by the build system when you create the project.
    2. Create a new file <NEW_TOOLCHAIN>.mk and add the toolchain configuration.
    3. In the BSP directory, navigate to TARGET_<BSP>\linker\ and create a directory named TOOLCHAIN_<NEW_TOOLCHAIN>. Add the custom linker script inside this directory. Note that the prefix “TOOLCHAIN_” is important.
    4. In the BSP directory, navigate to TARGET_<BSP>\startup\ and create a directory named TOOLCHAIN_<NEW_TOOLCHAIN>. Add the custom startup file inside this directory.
    5. Follow the steps mentioned in How do I specify a set of build tools
    6. Build the application.

    ModusToolbox BSPs include startup and linker files for supported toolchains. If your toolchain requires different files, you need to provide them.

     

    13. How do I pass compiler flags?

    Use the CFLAGS and CXXFLAGS variables to add additional C and C++ compiler flags respectively. Refer to the respective toolchain documentation for various options.

     

    Example: For the GNU ARM Toolchain, the various options for the compiler can be found here. They can be added as follows:

    CFLAGS=-Wall -O2

    CXXFLAGS=finline-functions

     

    The value of each variable is a space-separated list of flags supported by the compiler.

    To view the changes taking effect, set the variable VERBOSE to ‘1’ in the makefile. This displays the full command lines when building.

    Precisely where the compiler flags appear depends upon the toolchain or IDE in use. You can also specify the VERBOSE option using the IDE instead of the makefile. For example, in the ModusToolbox IDE, open the project properties and go to the C/C++ Build panel. Here, you can specify VERBOSE=1 in the Build command item as shown in Figure 1.

     

    Figure 1. Build Command

    Click Apply and Close to save your changes and then build the application. Note that changes made to the  IDE options are not reflected in the makefile.

    Similarly, when using the command line, you can specify “make build VERBOSE=1” to display the full command lines when building.

     

    14. How do I create a custom build configuration?

    By default, ModusToolbox provides Debug and Release build configurations for different toolchains. They are defined in the respective <TOOLCHAIN>.mk file in libs\psoc6make\make\toolchains in the project folder. To create your own build configuration, set the CONFIG variable to a value. For example:

     

    CONFIG=MyBuild

     

    The build system also uses the value in the CONFIG variable to generate the name of the output directory inside the project folder on this path: build\<BSP>\ .

    Do not set this variable to a null or empty value.

     

    15. How do I pass linker flags?

    Use the LDFLAGS variable to add custom linker flags. Refer to the respective toolchain documentation for various options.

    Example: For the GNU ARM Toolchain, the various options for the linker can be found here.

     

    LDFLAGS=-nodefaultlibs

     

    The values must be space-separated.

     

    16. How do I use a custom linker script?

    The build infrastructure automatically uses default linker scripts. Default linker scripts are provided in the board support package for all supported toolchains (Arm, GCC, and IAR).

    To use a custom linker script, specify the file in the LINKER_SCRIPT variable. The value must be a relative path from the makefile to the linker script.

     

    LINKER_SCRIPT=../../MyFiles/myLinkerScript.ld

     

    The script must be compatible with your toolchain (.sct, .ld, .icf).

     

    17. How do I specify a pre-build task or post-build task?

    Refer to the Section Pre-builds and Post-builds in the ModusToolbox User Guide.

     

    18. How do I build a static library?

    The build system supports creating either an executable or a library. If the project builds an executable, it has the APPNAME variable set, and the LIBNAME variable is empty.

    To build a library file, ensure that the APPNAME variable is empty, and specify the library name in LIBNAME.

     

    19. What is a COMPONENT?

    A COMPONENT is a folder that contains a collection of files. Typically, a component consists of files that implement some feature or functionality in an application. For example, in a Cypress BSP, the hardware design is encapsulated in a COMPONENT named BSP_DESIGN_MODUS. It contains the design.modus file and may contain other hardware configuration files associated with the BSP.

     

    You can add or disable components.

     

    20. How do I create a custom COMPONENT and add it to the application?

    Create a folder named “COMPONENT_<NAME>”. It can be created in any location found by auto-discovery. Put the files for that component in the folder. Note that the folder must have the prefix COMPONENT_.

     

    You then add the component to your application using COMPONENTS+=<NAME>. Note that the folder prefix is not used. For example, if you created a folder named COMPONENT_MY_COMPONENT, to add that component to the application you would do this in the makefile:

     

    COMPONENTS+=MY_COMPONENT

     

    21. How do I disable a COMPONENT?

    Use DISABLE_COMPONENTS+=<NAME> to disable a component. For example:

    DISABLE_COMPONENTS+=MY_COMPONENT

     

    22. How do I override the default design.modus file in a BSP?

    You may wish to have a custom hardware configuration for your project. The design.modus file is part of the default BSP_DESIGN_MODUS component. To do this, you disable the default component and add a custom component.

     

    # Disable default component

    DISABLE_COMPONENTS+=BSP_DESIGN_MODUS

    # Add my custom component

    COMPONENTS+=CUSTOM_DESIGN_MODUS

     

    Detailed information about how to do this is in the “Overriding the BSP Configuration Files” section of the ModusToolbox User Guide.

     

    23. How do I create my own BSP?

    You need a custom BSP when your project does not use a Cypress kit.

     

    Detailed information about how to do this is in the “Creating a BSP for your Board” section in the ModusToolbox User Guide. For a BSP used for the Bluetooth SDK, the information is in the “Custom BSP” section in the ModusToolbox User Guide.

     

    24. How do I use a custom BSP for my application?

    You are likely to create a project for hardware that is not a Cypress kit. You use a custom BSP to support your board. The custom BSP is in a folder named TARGET_<BSP_NAME>. In the makefile, you set the value of the TARGET make variable to match your custom BSP.

     

    For example, if your BSP is named “MyBoard”, the contents of the BSP must be in a folder named TARGET_ MyBoard, and your makefile looks like this:

     

    # Target board/hardware

    TARGET=MyBoard

    When you execute make getlibs, your BSP files appear in a folder named TARGET_MyBoard inside your project.