GCC Toolchain Eclipse Setup Guide Part 3 — Makefile Project

A PDF version of this guide, including Eclipse setup and project debugging is available in the Documentation section.

This is the third part of this series on setting up a bare-metal GCC toolchain in Eclipse. The previous article explained how to set up a managed build project where Eclipse manages the build process automatically.

The other type of Eclipse project, a Makefile project, is more complicated to setup but offers greater control and flexibility over the build process. A Makefile based project is also independent of Eclipse and can be built and maintained easily outside of Eclipse. This can be useful for automated builds.

Workspace Setup

Some configuration is helpful at the workspace level when using a Makefile build, it is also a good idea to see if Eclipse has detected the toolchain that was added to the system PATH environment variable earlier in this guide.

First launch Eclipse if it’s not already started. The workspace selection prompt should appear.

Eclipse workspace selection dialog with text box and browse button to select a workspace directory. Additionally an optional checkbox is available to set the currently selected workspace as the default.
Eclipse workspace selection prompt

If a workspace was created during the Eclipse installation select it, otherwise create it now. It is strongly recommended to create a unique workspace that will be used exclusively for the projects related to the GCC toolchain that will be installed in this guide. The workspace selected should not have a path name that is excessively long and it is recommended not to use spaces in the path name either. To keep everything well contained and ordered this example will use “C:/eclipse_gcc/eclipse_workspace” as the
workspace.

Click “Launch”.

The Eclipse welcome screen should appear.

Eclipse IDE empty workspace welcome screen with links to available documentation and tutorials on Eclipse.
Eclipse welcome screen

The welcome screen can be closed by pressing the X next to the Welcome tab. This reveals the main Eclipse view, which should be empty if this is a new workspace.

Eclipse IDE empty workspace.
Eclipse main view

Open the workspace preferences by clicking the Window->Preferences menu entry.

Window menu with
Eclipse workspace preferences menu entry

Navigate to the “Core Build Toolchains” subsection of the “C/C++” section of the Preferences panel. This should display a list of detected toolchains. If the toolchain was installed correctly and was added to the PATH environment variable, it should appear in the list.

Eclipse preferences
CDT Core Build Toolchains

In this example the toolchain for ARM installed earlier was detected with the path to the main GCC executable being
C:/eclipse_gcc/gcc/bin/arm-none-eabi-gcc.exe correctly displayed.

Next it is helpful to change the Cross GCC compiler settings discovery for Eclipse CDT. This while help with some indexing issue later. To do so navigate to the “C/C++->Build->Settings” section of the Preferences panel and open the “Discovery” tab.

Eclipse build discovery configuration panel with
CDT Discovery Settings panel

Click the “CDT Cross GCC Built-in Compiler Settings” item from the list. The “Command to get compiler specs:” box should be modified to add the toolchain prefix in front of the command. In our example “arm-none-eabi-“.

The result should look as follows:

Eclipse build discovery configuration panel with
Modified CDT Cross GCC Built-in Compiler Settings

That is all for the workspace configuration, click “Apply and Close” to apply and save the configuration.

Makefile Project Setup

When creating a new Makefile project, it is advisable to create it in a directory that already contains at least an empty Makefile. This is to ensure that the correct project type and nature are set when creating the project. The makefile should be named either “makefile” or “Makefile” with a capital M.

For this example we’ll use a directory named ex_make_build for the project with an empty Makefile named “makefile”.

To create a new Makefile project select the File->New->Makefile Project With Existing Code menu entry

Eclipse File menu with
New Makefile project menu item

This should open the New Project dialog. Browse or type the path to the existing makefile created earlier or you source code to build. By default the project name is the same as the directory name but can be changed if desired. Finally, select “Cross GCC” as the toolchain.

The C and C++ checkboxes can be used to enable disable indexing of C++ or C code. If either of those will be found in your project, the corresponding box should be checked.

Eclipse New Makefile Project with existing code creating dialog. Text boxes for project name and location, with browse button, are filled. Two check boxes allow selection of either C or C++ or both. Finally, the bottom panel allows the selection of the type of toolchain to be used for indexer configuration. The
New Makefile Project dialog

Click Finish. Eclipse will return to the main view with the newly created project in the workspace.

Eclipse IDE workspace with the newly created project displayed in the left project explorer view.
Eclipse main view with new project

Let’s add a file to build named main.c with a minimal main function. To do so right-click on the project then click the New->file menu item.

New File context menu item.
Project new file menu item

In the “Create New File” dialog enter the name of the file, “main.c” in this example.

Eclipse create new file dialog with text box and project tree available to set the location of the new file and another text box at the bottom to set the name.
New File dialog

At this moment if a C or C++ include directive of a standard header is written in the C file, it will most probably be underlined stating that there is an unresolved inclusion. This is due to the CDT indexer being unable to invoke the cross compiler.

Note that if you have a native GCC compiler available in your environment PATH it might be used by default for indexing. In which case there won’t be unresolved inclusions reported by the indexer. However, since these headers do not match the current toolchain it can cause a few issues with code completion and indexing.

Screenshot of the code editor with a dummy main function to be used for demonstration. A popup warning is shown with informs the user of the unresolved inclusion of
Example of an unresolved inclusion

To fix this issue open the Project Properties, either by right-clicking on the project or selecting the project and opening the Project->Properties menu item.

Project menu with the
Project Properties menu item

In the Properties panel navigate to the “Preprocessor Include Paths, Macros etc.” section of the “C/C++ General” category.

Preprocessor include paths configuration panel with
C/C++ Providers Settings

Assuming that the workspace setup was done, on this screen select the “CDT Cross GCC Built-in Compiler Settings” item and check the “Use global provider shared between projects” checkbox. This will change the provider’s configuration to the one we set in the workspace.

Preprocessor include path panel with
Modified C/C++ Providers Settings

At this point the include files should no longer be unresolved. Now that the inclusions are fixed, we need a Makefile. Here is a minimal example Makefile:

# Intermediary objects working directory.
OBJDIR := obj

# Name of the output binary executable file.
LINK_TARGET := a.out

# Application source files list.
APP_SOURCE := main.c

# Name of toolchain executables to use.
CC := arm-none-eabi-gcc
AS := arm-none-eabi-gcc
AR := arm-none-eabi-ar
LD := arm-none-eabi-gcc

# C Build flags.
C_FLAGS := -mcpu=cortex-m4 -g -ffunction-sections --specs=nosys.specs

# C Build warning flags.
WARNING_FLAGS := -Wall -pedantic -Wconversion

# Configure include directories.
INCLUDEDIR = $(subst \,/,$(PWD)) \
             $(BSP_SRC_DIR) \

# Extract all the C source file names.
SOURCE += $(notdir $(APP_SOURCE))

# Compute intermediary object names.
OBJ += $(SOURCE:%.c=$(OBJDIR)/%.o)

# Build everything.
all : $(OBJDIR) $(LINK_TARGET)
    @echo All done

# Firmware binary linking.
$(LINK_TARGET) : $(OBJ)
    $(LD) -o $@ $^ $(C_FLAGS)
    
# C files build.
$(OBJDIR)/%.o : %.c | $(OBJDIR)
    $(CC) $(C_FLAGS) $(WARNING_FLAGS) -o $@ -c

$(OBJDIR) : 
    mkdir $(OBJDIR) 

.PHONY: clean 
clean: 
    rm -rf ${OBJDIR} 
    rm -rf $(LINK_TARGET)

The project can now be built using the “Build Project” item from the context menu.

Build Project menu item

The Makefile project is now ready for development.

Eclipse IDE with console output announcing that the build finished without errors.
Built Makefile project

Indexing External Source Files

Oftentimes when using a Makefile project it is desirable to build source files that are outside the project directory. In that situation the indexer may not be able to find those files automatically which leads to unresolved inclusions warnings, code-completion issues and difficulty with debugging.

Example of unresolved inclusion within the Eclipse IDE code editor where a header file is underlined in a weavy yellow line.
Unresolved inclusion of an external file

For example, in the previous screenshot the external include file uart/bp_uart.h is underlined in yellow, meaning it hasn’t
been found by the indexer.

To solve this problem the path to the source files must be added in two locations. To do so open the project Properties and navigate to the “Paths and Symbols” On that screen open the “Source Location” tab. If it is not displayed use the arrows on the right which will show any hidden tabs on this panel.

Eclipse project's
Project Source Location configuration

To add a new external source location click “Link Folder”.

Link folder dialog with text box to select the name of the linked folder and checkbox to select a folder from the file system. If checked a text box and browse button is available to select a directory from the file system.
Link Directory dialog

Check the “Link folder in the file system” box and then browse or type the location of the external source. In this example the external source code location is the “C:/ip_dev/base_platform” directory. Click OK to add the directory.

Once the source location is linked, it is necessary to add the location to the indexer’s include path. To do so open the “Includes” tab. And select either GNU C or GNU C++ depending on your project type.

Note that in the case both C and C++ was selected when initially creating the project, CDT will use the C++ compiler for indexing. In this case it’s important to add the include files paths to the GNU C++ language and note GNU C.

Eclipse project's
Add directory path dialog

Click “Workspace…” to add a workspace location.

Folder selection dialog with a project directory tree to browse for an include path to add.
Add workspace path dialog

Select the previously created workspace link, in this example “base_platform”. Then click OK to add the path.

After doing the procedure for each external source location, they should be properly indexed and reachable during a debugging session.

That is it for part 3, please read part 4 if you are interested in the the debug configuration using GDB. Check out part 1 for the Eclipse and toolchain configuration guide as well as part 2 for the managed build project setup.

Visit the Documentation section for a PDF version of this guide including Eclipse and debugging setup.

Questions or comments? Do not hesitate to contact us at blog@jblopen.com. Your questions, comments and, suggestions are appreciated.


See all articles