Why doesn't make build an object file on the first run? - makefile

I have this Makefile:
CFLAGS := $(CFLAGS) -std=c99
shell: main.o shellparser.o shellscanner.o
$(CC) -o shell main.o shellparser.o shellscanner.o
main.o: main.c shellparser.h shellscanner.h
shellparser.o: shellparser.h
shellparser.h: shellparser.y lemon
./lemon shellparser.y
shellscanner.o: shellscanner.h
shellscanner.h: shellscanner.l
flex --outfile=shellscanner.c --header-file=shellscanner.h shellscanner.l
# Prevent yacc from trying to build parsers.
# http://stackoverflow.com/a/5395195/79202
%.c: %.y
lemon: lemon.c
$(CC) -o lemon lemon.c
For some reason, on the first run of make, shellparser.o isn't built:
> make
cc -o lemon lemon.c
./lemon shellparser.y
flex --outfile=shellscanner.c --header-file=shellscanner.h shellscanner.l
cc -std=c99 -c -o main.o main.c
cc -std=c99 -c -o shellscanner.o shellscanner.c
cc -o shell main.o shellparser.o shellscanner.o
i686-apple-darwin10-gcc-4.2.1: shellparser.o: No such file or directory
make: *** [shell] Error 1
rm shellscanner.c
If I run it again, it then builds it correctly:
> make
cc -std=c99 -c -o shellparser.o shellparser.c
cc -o shell main.o shellparser.o shellscanner.o
So what do I have out-of-order such that it doesn't build it the first time?

The first time you try to build, Make doesn’t know that lemon outputs shellparser.c, so it doesn’t try to build it. When you rebuild, shellparser.c does exist, so Make uses it. The solution is to explicitly tell Make that lemon outputs shellparser.c:
diff --git a/Makefile b/Makefile
index bf2655e..d6b288d 100644
--- a/Makefile
+++ b/Makefile
## -7,7 +7,7 ## main.o: main.c shellparser.h shellscanner.h
shellparser.o: shellparser.h
-shellparser.h: shellparser.y lemon
+shellparser.c shellparser.h: shellparser.y lemon
./lemon shellparser.y
shellscanner.o: shellscanner.h
diff --git a/main.c b/main.c
index 81ec151..4179981 100644
--- a/main.c
+++ b/main.c
## -33,7 +33,7 ## void parse(const char *commandLine) {
}
// Borrowed from http://stackoverflow.com/a/314422/79202.
-char * getline(void) {
+char * my_getline(void) {
char * line = malloc(100), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;
## -69,7 +69,7 ## int main(int argc, char** argv) {
void* shellParser = ParseAlloc(malloc);
char *line;
printf("> ");
- while ( line = getline() ) {
+ while ( line = my_getline() ) {
parse(line);
printf("> ");
}
Also I renamed getline so it would build on my mac; thanks for posting all your source!

Related

How to properly use -MD flag in Makefile

I'm trying to create a Makefile where make only recompiles necessary .cpp files.
By default, it works well if I edit .cpp, however, when I edit .h files, it just ignores the changes.
So I've read of -MD flag and its friend -MP (used to avoid bugs when typing make).
However, I can't seem to make it working, if I use -MMD, it works perfectly but I rely on system includes too as I'm writing a library too that is evolving along with the project. Thus, if I update the libary header and reinstall the library, typing make in the main project should recompiles files that includes the changed header.
When using -MMD flag, it - as expected - does not recompile the project, however, using -MD flag, it does recompile everything. In fact, -MD recompiles everything every time, even when nothing changed.
Here is a minimal project structure that reproduce the issue:
./Makefile:
all: build
re: clean build
build: build_lib install_lib build_client
build_lib:
$(MAKE) -C lib
$(MAKE) install -C lib
build_client:
$(MAKE) -C client
install_lib:
$(MAKE) install -C lib
.PHONY: clean
clean: clean_lib clean_client
clean_lib:
$(MAKE) clean -C lib
clean_client:
$(MAKE) clean -C client
./client/Makefile:
CC = g++
INC = -I../lib
CXXFLAGS = -Wall $(INC) -g -MD -MP
EXEC_NAME = ../test
src = $(shell find $(SOURCEDIR) -name '*.cpp')
obj = $(src:.cpp=.o)
LIBRARIES = -ltest_lib
LDFLAGS = -rdynamic $(LIBRARIES)
all: $(EXEC_NAME)
re: clean $(EXEC_NAME)
$(EXEC_NAME): $(obj)
$(CC) -o $# $^ $(LDFLAGS)
-include $(obj:.o=.d)
.PHONY: clean
clean:
rm -f $(obj) $(EXEC_NAME)
./lib/Makefile:
.PHONY : clean
CXXFLAGS= -fPIC -g -Itest_lib/include -MMD -MP
LDFLAGS= -shared
SOURCES = $(shell find $(SOURCEDIR) -name '*.cpp')
HEADERS = $(shell find $(SOURCEDIR) -name '*.h')
OBJECTS=$(SOURCES:.cpp=.o)
TARGET=libtest_lib.so
INC_FOLDER=test_lib/include
CUR_DIR = $(shell pwd)
all: $(TARGET)
install:
sudo rm -rf /usr/local/lib/libtest_lib.so && sudo ln -s $(CUR_DIR)/$(TARGET) /usr/local/lib/libtest_lib.so
sudo rm -rf /usr/local/include/test_lib && sudo cp -r $(INC_FOLDER) /usr/local/include/test_lib
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $# $(LDFLAGS)
-include $(OBJECTS:.o=.d)
./client/main.cpp:
#include "bar.h"
int main()
{
Bar b;
b.sayHello();
b.sayBye();
return 0;
}
./client/bar.h
#ifndef __BAR__
#define __BAR__
#include <test_lib/foo.h>
#include <iostream>
struct Bar : public Foo
{
Bar() {};
~Bar() {};
void sayBye() const {
std::cout << "Bye " << name << "..." << std::endl;
};
};
#endif
./lib/test_lib/include/foo.h
#ifndef __FOO__
#define __FOO__
struct Foo
{
const char *name;
Foo(const char *name = "world");
~Foo();
void sayHello() const;
};
#endif
./lib/test_lib/src
#include "foo.h"
#include <iostream>
Foo::Foo(const char *name) : name(name) {}
Foo::~Foo() {}
void Foo::sayHello() const
{
std::cout << "Hello " << name << " !" << std::endl;
}
Problem was that I copied the library headers all the time in /usr/local so the files got newer and the client make then thought every header of the library had changed.
A simple fix to this problem was to replace in the library Makefile the following line:
sudo rm -rf /usr/local/include/test_lib && sudo cp -r $(INC_FOLDER) /usr/local/include/test_lib
by
sudo rm -rf /usr/local/include/test_lib && sudo ln -s $(CUR_DIR)/$(INC_FOLDER) /usr/local/include/test_lib
On a side note, provided example is missing the removal of .d files on the clean rule.

Make is not recognizing my library!

I am trying to create a program in C++ that utilizes the rudeconfig library.
I run make, and get this:
g++ -o Homework5_executable helloworld.o -lrudeconfig -L/home/j/je/jea160530/hw5/libs
/bin/ld: cannot find -lrudeconfig
collect2: error: ld returned 1 exit status
make: *** [Homework5_executable] Error 1
I know this is happening because make is not recognizing the rudeconfig library, however I have followed the instructions on the rudeconfig site for install correctly.
Here is the code:
Makefile
#
# Set up info for C++ implicit rule
CXX = g++
CXXFLAGS = -Wall
CPPFLAGS = -I/home/012/j/je/jea160530/hw5/include
#
# Set up any Linker Flags
LDFLAGS = -L/home/012/j/je/jea160530/hw5/libs
#
# Set up libraries needer for compilation
LDLIBS = -lrudeconfig
#
# We choose the project name. This is used in building the file name for the backup target
PROJECTNAME = JesseAlotto_Homework5
#
# We choose the source files to include and name the output
SRCS = helloworld.cc
#
# We choose the name of the executable to be created
EXEC = Homework5_executable
#
# NORMALLY DON'T NEED TO CHANGE ANYTHING BELOW HERE
# =================================================
#
OBJS = $(SRCS:cc=o)
all: $(EXEC)
clean:
rm -f $(OBJS) *.d *~ \#* $(EXEC)
Makefile: $(SRCS:.cc=.d)
# Pattern for .d files.
# =====================
%.d:%.cc
#echo Updating .d Dependency File
#set -e; rm -f $#; \
$(CXX) -MM $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
# This is a rule to link the files. Pretty standard
# ================================================
$(EXEC): $(OBJS)
$(CXX) -o $(EXEC) $(OBJS) $(LDFLAGS) $(LDLIBS)
#echo Program compiled succesfully!
#
# Backup Target
# =============
backup: clean
#mkdir -p ~/backups; chmod 700 ~/backups
#$(eval CURDIRNAME := $(bash pwd))
#$(eval MKBKUPNAME := ~/backups/$(PROJECTNAME)-$(shell date +'%Y.%m.%d-%H:%M:%S').tar.gz)
#echo
#echo Writing Backup file to: $(MKBKUPNAME)
#echo
#tar -zcvf $(MKBKUPNAME) ./$(CURDIRNAME)
#chmod 600 $(MKBKUPNAME)
#echo
#echo Done!
#
# Include the dependency files
# ============================
-include $(SRCS:.cc=.d)
helloworld.cc
#include <string>
#include <iostream>
#include <fstream>
#include <tclap/CmdLine.h>
#include <map>
#include <stdlib.h>
#include <rude/config.h>
using namespace rude;
int main(int argc, char *argv[]){
std::string nextLine;
std::map<int, std::string> optionMap;
try{
std::cout << "hello world!";
//Command Line Variable
TCLAP::CmdLine cmd("CS3377.002 Program 5", ' ', "1.0");
//Switch Args
TCLAP::SwitchArg daemonSwitch("d", "daemon", "Run in daemon mode (forks to run as a daemon).", cmd, false);
//Unlabeled Value Args
TCLAP::UnlabeledValueArg<std::string> infileArg("infile", "The name of the configuration file. Defaults to cs3376dirmond.conf", true, "cs3376dirmond.conf", "config filename", false);
//Add leftover flags to cmdLine object
cmd.add(infileArg);
//Parse the command line
cmd.parse(argc, argv);
//Create an enumeratedlist for the mapping
enum flags {DAEMON, INFILE};
//Map keys and values to map
if (daemonSwitch.getValue()){
optionMap[DAEMON] = "1";
}
else{
optionMap[DAEMON] = "0";
}
optionMap[INFILE] = infileArg.getValue();
//Load input file
std::ifstream inputFile;
inputFile.open(optionMap[INFILE].c_str(), std::ios::in);
if(!inputFile){
std::cerr << "Error: no input file" << std::endl;
}
//============================================PARSE CONFIGURATION FILE==========================
Config config;
config.load("cs3376dirmond.conf");
//==============================================================================================
inputFile.close();
return 0;
} catch (TCLAP::ArgException &e) //catch any exceptions
{ std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;}
}
The error is caused by this command:
g++ -o Homework5_executable helloworld.o -lrudeconfig -L/home/j/je/jea160530/hw5/libs
not by make itself.
The error means that the linker isn’t finding librudeconfig.so in the library search path. From your comments, it turns out the library is named rudeconfig.so instead, so you need to specify
LDLIBS = -l:rudeconfig.so
instead of -lrudeconfig (which always expands to librudeconfig.so or librudeconfig.a).
Ideally, the library should be installed as librudeconfig.so...

Build to static libs and DPDK into an image file

I have a project lets call it AB, which looks a follows:
/path/to/<br>
---|dpdk-stable-17.05.1/...<br>
---|AB/<br>
------|main.cpp<br>
------|Makefile<br>
------|dir1/<br>
----------|c1.c<br>
----------|c2.c<br>
----------|c3.c<br>
----------|h1.h<br>
----------|Makefile<br>
------|dir2/<br>
----------|h2.h<br>
----------|cpp1.cpp<br>
----------|cpp2.cpp<br>
----------|Makefile<br>
I've compiled the dpdk with make install successfuly.
I am trying to create dir1.a and dir2.a and to build together with main.cpp and of-course the DPDK libs an "AB" image file.
The Makefile in AB (the main makefile) looks as follows:
>DPDK_VER=dpdk-stable-17.05.1
>
>RTE_SDK=$(shell pwd | sed -n 's/AB.*//p')/$(DPDK_VER)<br>
>RTE_TARGET=build
>
>include $(RTE_SDK)/mk/rte.vars.mk
>
>XXFLAGS := $(CFLAGS) -I../dir1/ -g<br>
>CXXFLAGS += -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS<br>
>CFLAGS += -g -O0 -std=gnu99 -Wall -Wno-unused-value<br>
>LDLIBS += -lfuse -lstdc++ --start-group -ldir1 -ldir2
>
>LDFLAGS += --end-group
>
>APP = AB
>
>SRCS-y := main.cpp
>
>OBJS-y := main.o
>
>SRCS-y := $(patsubst %.cpp,%.c,$(SRCS-y))<br>
>OBJS-y := $(patsubst %.o,obj/%.o,$(OBJS-y))
>
>DIRS-y = <br>
>DIRS-y += dir1<br>
>DIRS-y += dir2
>
>.PHONY: dirs-y $(DIRS-y)
>
>include $(RTE_SDK)/mk/rte.subdir.mk<br>
>include $(RTE_SDK)/mk/rte.extapp.mk
>
>.PHONY: clean<br>
>clean:<br>
> rm -rf *.o build/*.o build/$(APP)
The Makefile in dir1 looks:
>DPDK_VER=dpdk-stable-17.05.1
>
>RTE_SDK=$(shell pwd | sed -n 's/AB.*//p')/$(DPDK_VER)<BR>
>RTE_TARGET=build
>include $(RTE_SDK)/mk/rte.vars.mk
>
>export RTE_OUTPUT=$(shell pwd)/../build/
>
>CXXFLAGS := $(CFLAGS) -g<BR>
>CXXFLAGS += -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -lgnustl_shared<br>
>CFLAGS += -g -O0 -std=gnu99 -Wall -Wno-unused-value -I../dir2
>
>LIB = dir1.a
>
>SRCS-y := c1.c c2.c c3.c<br>
>OBJS-y := c1.o c2.o c3.o
>
>SRCS-y := $(patsubst %.cpp,%.c,$(SRCS-y))<br>
>OBJS-y := $(patsubst %.o,obj/%.o,$(OBJS-y))
>
>include $(RTE_SDK)/mk/rte.extlib.mk
>
>.PHONY: all<br>
> all
>
>.PHONY: clean<br>
>clean:<br>
> rm -rf *.o *.a ../build/lib/$(LIB)'
The Makefile in dir2 looks:
>DPDK_VER=dpdk-stable-17.05.1
>
>RTE_SDK=$(shell pwd | sed -n 's/AB.*//p')/$(DPDK_VER)<br>
>RTE_TARGET=build
>
>include $(RTE_SDK)/mk/rte.vars.mk
>
>export RTE_OUTPUT=$(shell pwd)/../build/
>
>CXXFLAGS := $(CFLAGS) -g<br>
>CXXFLAGS += -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -lgnustl_shared -I../dir1 -I.<br>
>CFLAGS += -g -O0 -std=gnu99 -Wall -Wno-unused-value<br>
>
>LIB = dir1.a
>
>SRCS-y := cpp1.cpp cpp2.cpp<br>
>OBJS-y := cpp1.o cpp2.o
>
>SRCS-y := $(patsubst %.cpp,%.c,$(SRCS-y))<br>
>OBJS-y := $(patsubst %.o,obj/%.o,$(OBJS-y))
>
>include $(RTE_SDK)/mk/rte.extlib.mk
>
>.PHONY: all<br>
> all
>
>.PHONY: clean<br>
>clean:<br>
> rm -rf *.o *.a ../build/lib/$(LIB)
the make output is:
== Build /dir1
CC c1.o
CC c2.o
CC c3.o
AR dir1.a
INSTALL-LIB dir1.a
== Build /dir2
g++ -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -I/path/to/AB/build/include -I/path/to/dpdk-stable-17.05.1/build/include -include /path/to/dpdk-stable-17.05.1/build/include/rte_config.h -g -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -lgnustl_shared -I../dir1 -I. -c -o cpp1.o cpp2.cpp
g++ -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -I/path/to/AB/build/include -I/path/to/dpdk-stable-17.05.1/build/include -include /path/to/dpdk-stable-17.05.1/build/include/rte_config.h -g -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -lgnustl_shared -I../dir1 -I. -c -o cpp2.o cpp2.cpp
AR dir2.a
INSTALL-LIB dir2.a
/path/to/dpdk-stable-17.05.1/mk/internal/rte.install-post.mk:98: warning: overriding recipe for target _postinstall'<br>
/path/to/dpdk-stable-17.05.1/mk/internal/rte.install-post.mk:75: warning: ignoring old recipe for target_postinstall'
/path/to//dpdk-stable-17.05.1/mk/internal/rte.clean-post.mk:61: warning: overriding recipe for target _postclean'<br>
/path/to//dpdk-stable-17.05.1/mk/internal/rte.clean-post.mk:38: warning: ignoring old recipe for target_postclean'
/path/to//dpdk-stable-17.05.1/mk/internal/rte.build-post.mk:38: warning: overriding recipe for target _postbuild'<br>
/path/to/dpdk-stable-17.05.1/mk/internal/rte.build-post.mk:38: warning: ignoring old recipe for target_postbuild'
/path/to/AB/Makefile:40: warning: overriding recipe for target clean'<br>
/path/to/dpdk-stable-17.05.1/mk/rte.app.mk:308: warning: ignoring old recipe for targetclean'
g++ -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -I/path/to/AB/build/include -I/path/to/dpdk-stable-17.05.1/build/include -include /path/to/dpdk-stable-17.05.1/build/include/rte_config.h -I../dir1/ -g -std=c++1y -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -c -o main.o /path/to/AB/main.cpp
LD AB
== Build /path/to/AB/dir1
make[2]: * No rule to make target c1.o', needed bydir1.a'. >Stop.
make[1]: * [dir1] Error 2
make: *** [all] Error 2
The dir.a dir2.a and AB image are all created!
BUT:
1) why does the make goes back to Build dir1 at the end and announces that the c1.o is missing for dir1.o?
2) How to get rid of the "warning: ignoring old recipe for target `XXX'"?
Thanks!
The code is not quite reproducible, but I guess the root cause is that there are two includes in the main Makefile, rte.subdir.mk and rte.extapp.mk.
Try to put the main.cpp into an src directory and use just rte.subdir.mk in the main Makefile, moving all application build functionality to src/Makefile...

make error : *** missing separator. Stop

This is my makefile:
OBJECTS = main.o
CFLAGS = -g -wall
NAME = make
CC = gcc
build: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(NAME)
I'm getting below error when I tried to make(Applied tab before gcc command) :
makefile:6: *** missing separator. Stop.
How can I fix this?
First of all, it looks like you have spaces instead of tab.
As for the Makefile itself, I'd make it little bit simpler. For a source file main.c:
int main() {
return 0;
}
I would go with Makefile:
CFLAGS = -g -wall
CC = gcc
main: main.c
$(CC) $(CFLAGS) $< -o $#

gcc makefile error: make: *** No rule to make target

I'm trying to use GCC on a OS X to compile my project.
I just modified Makefile.posix as follows:
GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_8-20143
GNU_VERSION := 4.8.3
GNU_PREFIX := arm-none-eabi
GDB_PORT_NUMBER := 9992
FLASH_START_ADDR = $(shell $(OBJDUMP) -h $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out -j .text | grep .text | awk '{print $$4}')
JLINK_OPTS = -device nrf51822 -if swd -speed 4000
JLINK_GDB_OPTS = -noir
JLINK = JLinkExe $(JLINK_OPTS)
JLINKD_GDB = JLinkGDBServer $(JLINK_GDB_OPTS)
flash-jlink: flash.jlink
$(JLINK) flash.jlink
flash.jlink:
printf "loadbin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(FLASH_START_ADDR)\nr\ng\nexit\n" > flash.jlink
erase-all: erase-all.jlink
$(JLINK) erase-all.jlink
erase-all.jlink:
# Write to NVMC to enable erase, do erase all, wait for completion. reset
printf "w4 4001e504 2\nw4 4001e50c 1\nsleep 100\nr\nexit\n" > erase-all.jlink
run-debug:
$(JLINKD_GDB) $(JLINK_OPTS) $(JLINK_GDB_OPTS) -port $(GDB_PORT_NUMBER)
.PHONY: flash-jlink flash.jlink erase-all erase-all.jlink run-debug
When I try to start the server with the modified Makefile.posix :
make -f ble_app_hrs.Makefile run-debug
I got this error:
Macintosh:gcc $ make -f ble_app_hrs.Makefile run-debug
/bin/sh: - : invalid option
Usage: /bin/sh [GNU long option] [option] ...
/bin/sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
make: *** No rule to make target `JLinkGDBServer', needed by `run-debug'. Stop.
Here the file ble_app_hrs.Makefile :
TARGET_CHIP := NRF51822_QFAA_CA
BOARD := BOARD_PCA10001
# application source
C_SOURCE_FILES += main.c
C_SOURCE_FILES += battery.c
C_SOURCE_FILES += led.c
C_SOURCE_FILES += ble_dis.c
C_SOURCE_FILES += ble_bas.c
C_SOURCE_FILES += ble_hrs.c
C_SOURCE_FILES += ble_srv_common.c
C_SOURCE_FILES += ble_sensorsim.c
C_SOURCE_FILES += softdevice_handler.c
C_SOURCE_FILES += ble_advdata.c
C_SOURCE_FILES += ble_debug_assert_handler.c
C_SOURCE_FILES += ble_error_log.c
C_SOURCE_FILES += ble_conn_params.c
C_SOURCE_FILES += app_timer.c
C_SOURCE_FILES += pstorage.c
C_SOURCE_FILES += crc16.c
C_SOURCE_FILES += device_manager_peripheral.c
C_SOURCE_FILES += app_trace.c
C_SOURCE_FILES += simple_uart.c
C_SOURCE_FILES += app_gpiote.c
C_SOURCE_FILES += app_button.c
SDK_PATH = ../../../../../
OUTPUT_FILENAME := ble_app_hrs
DEVICE_VARIANT := xxaa
#DEVICE_VARIANT := xxab
USE_SOFTDEVICE := S110
#USE_SOFTDEVICE := S210
CFLAGS := -DDEBUG_NRF_USER -DBLE_STACK_SUPPORT_REQD
# we do not use heap in this app
ASMFLAGS := -D__HEAP_SIZE=0
# keep every function in separate section. This will allow linker to dump unused functions
CFLAGS += -ffunction-sections
# let linker to dump unused sections
#LDFLAGS := -Wl,--gc-sections
INCLUDEPATHS += -I"$(SDK_PATH)Include/s110"
INCLUDEPATHS += -I"$(SDK_PATH)Include/ble"
INCLUDEPATHS += -I"$(SDK_PATH)Include/ble/device_manager"
INCLUDEPATHS += -I"$(SDK_PATH)Include/ble/ble_services"
INCLUDEPATHS += -I"$(SDK_PATH)Include/app_common"
INCLUDEPATHS += -I"$(SDK_PATH)Include/sd_common"
INCLUDEPATHS += -I"$(SDK_PATH)Include/sdk"
C_SOURCE_PATHS += $(SDK_PATH)Source/ble
C_SOURCE_PATHS += $(SDK_PATH)Source/ble/device_manager
C_SOURCE_PATHS += $(SDK_PATH)Source/app_common
C_SOURCE_PATHS += $(SDK_PATH)Source/sd_common
include $(SDK_PATH)Source/templates/gcc/Makefile.common
and here the file Makefile.common that uses Makefile.posix:
DEVICE := NRF51
DEVICESERIES := nrf51
SDK_INCLUDE_PATH = $(SDK_PATH)/Include/
SDK_SOURCE_PATH = $(SDK_PATH)/Source/
TEMPLATE_PATH += $(SDK_SOURCE_PATH)/templates/gcc/
OUTPUT_BINARY_DIRECTORY := _build
ifeq ($(OS),Windows_NT)
include $(TEMPLATE_PATH)Makefile.windows
else
include $(TEMPLATE_PATH)Makefile.posix
endif
ifeq ($(LINKER_SCRIPT),)
ifeq ($(USE_SOFTDEVICE), S110)
LINKER_SCRIPT = gcc_$(DEVICESERIES)_s110_$(DEVICE_VARIANT).ld
OUTPUT_FILENAME := $(OUTPUT_FILENAME)_s110_$(DEVICE_VARIANT)
else
ifeq ($(USE_SOFTDEVICE), S210)
LINKER_SCRIPT = gcc_$(DEVICESERIES)_s210_$(DEVICE_VARIANT).ld
OUTPUT_FILENAME := $(OUTPUT_FILENAME)_s210_$(DEVICE_VARIANT)
else
LINKER_SCRIPT = gcc_$(DEVICESERIES)_blank_$(DEVICE_VARIANT).ld
OUTPUT_FILENAME := $(OUTPUT_FILENAME)_$(DEVICE_VARIANT)
endif
endif
else
# Use externally defined settings
endif
CPU := cortex-m0
# Toolchain commands
CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc"
AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as"
AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r
LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld"
NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm"
OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump"
OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy"
MK := mkdir
RM := rm -rf
OBJECT_DIRECTORY := _build
LISTING_DIRECTORY := _build
C_SOURCE_FILES += system_$(DEVICESERIES).c
ASSEMBLER_SOURCE_FILES += gcc_startup_$(DEVICESERIES).s
# Linker flags
#LDFLAGS += -L"$(GNU_INSTALL_ROOT)/arm-none-eabi/lib/armv6-m"
#LDFLAGS += -L"$(GNU_INSTALL_ROOT)/lib/gcc/arm-none-eabi/$(GNU_VERSION)/armv6-m"
LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mcpu=$(CPU) -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
# Compiler flags
CFLAGS += -mcpu=$(CPU) -mthumb -mabi=aapcs -D$(DEVICE) -D$(BOARD) -D$(TARGET_CHIP) --std=gnu99
CFLAGS += -Wall -Werror
CFLAGS += -mfloat-abi=soft
# Assembler flags
ASMFLAGS += -x assembler-with-cpp
INCLUDEPATHS += -I"../"
INCLUDEPATHS += -I"$(SDK_PATH)Include"
INCLUDEPATHS += -I"$(SDK_PATH)Include/gcc"
INCLUDEPATHS += -I"$(SDK_PATH)Include/ext_sensors"
# Sorting removes duplicates
BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) )
####################################################################
# Rules #
####################################################################
C_SOURCE_FILENAMES = $(notdir $(C_SOURCE_FILES) )
ASSEMBLER_SOURCE_FILENAMES = $(notdir $(ASSEMBLER_SOURCE_FILES) )
# Make a list of source paths
C_SOURCE_PATHS += ../ $(SDK_SOURCE_PATH) $(TEMPLATE_PATH) $(wildcard $(SDK_SOURCE_PATH)*/) $(wildcard $(SDK_SOURCE_PATH)ext_sensors/*/) $(wildcard $(SDK_SOURCE_PATH)ble/*/)
ASSEMBLER_SOURCE_PATHS = ../ $(SDK_SOURCE_PATH) $(TEMPLATE_PATH) $(wildcard $(SDK_SOURCE_PATH)*/)
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILENAMES:.c=.o) )
ASSEMBLER_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASSEMBLER_SOURCE_FILENAMES:.s=.o) )
# Set source lookup paths
vpath %.c $(C_SOURCE_PATHS)
vpath %.s $(ASSEMBLER_SOURCE_PATHS)
# Include automatically previously generated dependencies
-include $(addprefix $(OBJECT_DIRECTORY)/, $(COBJS:.o=.d))
### Targets
debug: CFLAGS += -DDEBUG -g3 -O0
debug: ASMFLAGS += -DDEBUG -g3 -O0
debug: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
.PHONY: release
release: clean
release: CFLAGS += -DNDEBUG -O3
release: ASMFLAGS += -DNDEBUG -O3
release: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
echostuff:
#echo C_OBJECTS: [$(C_OBJECTS)]
#echo C_SOURCE_FILES: [$(C_SOURCE_FILES)]
#echo C_SOURCE_PATHS: [$(C_SOURCE_PATHS)]
## Create build directories
$(BUILD_DIRECTORIES):
$(MK) $#
## Create objects from C source files
$(OBJECT_DIRECTORY)/%.o: %.c
# Build header dependencies
$(CC) $(CFLAGS) $(INCLUDEPATHS) -M $< -MF "$(#:.o=.d)" -MT $#
# Do the actual compilation
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $# $<
## Assemble .s files
$(OBJECT_DIRECTORY)/%.o: %.s
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $# $<
## Link C and assembler objects to an .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES)
$(CC) $(LDFLAGS) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
## Create binary .bin file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
## Default build target
.PHONY: all
all: clean release
clean:
$(RM) $(OUTPUT_BINARY_DIRECTORY)
## Program device
.PHONY: flash
flash: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
nrfjprog --reset --program $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
.PHONY: reset
reset:
nrfjprog --reset
.PHONY: erase
erase:
nrfjprog --erase
any help will be appreciated
TAB character in Brackets editor were replaced by 4 spaces (sp sp sp sp).
Changing to other editor (TextMate) solved the problem
All these lines are wrong:
flash-jlink: flash.jlink $(JLINK) flash.jlink
flash.jlink: printf "loadbin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(FLASH_START_ADDR)\nr\ng\nexit\n" >flash.jlink
erase-all: erase-all.jlink $(JLINK) erase-all.jlink
# Write to NVMC to enable erase, do erase all, wait for completion. reset
erase-all.jlink: printf "w4 4001e504 2\nw4 4001e50c 1\nsleep 100\nr\nexit\n" > erase-all.jlink
run-debug: $(JLINKD_GDB) $(JLINK_OPTS) $(JLINK_GDB_OPTS) -port $(GDB_PORT_NUMBER)
I don't know if you were just careless with your cut and paste, but there must be a newline and TAB on the next line, or a semicolon, before the command. Like this:
flash-jlink: flash.jlink
$(JLINK) flash.jlink
flash.jlink:
printf "loadbin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(FLASH_START_ADDR)\nr\ng\nexit\n" >flash.jlink
erase-all: erase-all.jlink
$(JLINK) erase-all.jlink
# Write to NVMC to enable erase, do erase all, wait for completion. reset
erase-all.jlink:
printf "w4 4001e504 2\nw4 4001e50c 1\nsleep 100\nr\nexit\n" > erase-all.jlink
run-debug:
$(JLINKD_GDB) $(JLINK_OPTS) $(JLINK_GDB_OPTS) -port $(GDB_PORT_NUMBER)

Resources