include stdio makefile - makefile

I'm trying to use the sprintf() function. Therefore I have to include the stdio.h in my C project. If I compile the project without including the stdio.h in my makefile, the compiler generates the error that sprintf() is a unknown function. Including the stdio.h to the makefile generates the error that there is "no rule to make target."
The makefile template gives the options as follows:
NAME = test
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld -v
AR = arm-none-eabi-ar
AS = arm-none-eabi-as
CP = arm-none-eabi-objcopy
OD = arm-none-eabi-objdump
CFLAGS = -I./ -c -fno-common -O0 -g -mcpu=cortex-m3 -mthumb
AFLAGS = -ahls -mapcs-32 -o crt.o
ASFLAGS = -Wa,-gstabs
LFLAGS = -Tlinkerscript_rom.cmd -nostartfiles
CPFLAGS = -Obinary
ODFLAGS = -S
I hope that you can help me out, because I have no desire to rewrite every standard function.
Sven

Makefiles don't read include files. The C preprocessor reads include files, before the resulting file is compiled by the compiler. You should include the header in your C file. Just add:
#include <stdio.h>
Somewhere close to the top, before any function definitions etc.
This will show a declaration of the function to the compiler, which will remove the warning.

Just include stdio.h at the top of your c file
#include <stdio.h>
The only reason to put a .h file in your makefile is so that the files dependent upon your header will be recompiled if anything in the header is changed. Needless to say, this is most commonly with header files you have written.

If there is an error after including stdio.h, you have a broken tool chain. If you update your question to indicate your platform, we may be able to help you fix it :)

Related

How to include *project root* headers compiling with GCC C++ compiler?

How to include headers located in project root compiling with GCC C++ compiler?
I want to tell GCC compiler to search for some header files in project root.
I do NOT want to make changes in code and use relative paths in #include directives - e.g. #include "../../myheader.h"
I compile source code I do not own and I do not want to maintain own version.
I do NOT want to specify absolute include path e.g. g++ -c -IC:\root_project_folder .. for obvious reasons.
I have tried: g++ -c -I .., g++ -c -I/ .. and g++ -c -I"/" .. but it does not work.
Please advise.
root_project_folder
|--myheader.h
|--src_folder
|-prog.cpp
The symbol for the current directory is ..
You're looking for -I.

Default link script in GNU Make

I have this very simple makefile:
P = hello_world.exe
OBJECTS = main.o
CFLAGS = -g -Wall -O3
LDLIBS =
CC = clang
$(P): $(OBJECTS)
When I run make it will compile main.c but it will not link to hello_world.exe. Shouldn't that be happening automatically?
My environment is cygwin 64bit.
The output of make -p is here: http://pastebin.com/qbr0sRXL
There's no default rule for .exe files that I'm aware of (or can find in that output).
You'll need to write one yourself.
If your output was hello_world and you had a hello_world.c/hello_world.cpp source file and also a main.c/main.cpp file then your makefile as written would work I believe (since the default %: %.o rule would apply and your added prerequisite would be added to the hello_world prerequisite list).

CppuTest: undefined reference to pthread during final linking

I'm a newby in cppuTest and actually I'm trying to build the ./examples within the CppuTest root directory. Source and Test files are compiled without problems but I'm stucking on the final linking stage where I get this error:
C:\CppUTest\cpputest-3.7.1\examples>make
compiling AllTests.cpp
compiling CircularBufferTest.cpp
compiling EventDispatcherTest.cpp
compiling HelloTest.cpp
compiling MockDocumentationTest.cpp
compiling PrinterTest.cpp
compiling CircularBuffer.cpp
compiling EventDispatcher.cpp
compiling Printer.cpp
compiling hello.c
Building archive lib/libCppUTestExamples.a
a - objs/ApplicationLib/CircularBuffer.o
a - objs/ApplicationLib/EventDispatcher.o
a - objs/ApplicationLib/Printer.o
a - objs/ApplicationLib/hello.o
Linking CppUTestExamples_tests
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexCreate':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:248: undefined reference to `_imp__pthread_mutex_init'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexLock':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:255: undefined reference to `_imp__pthread_mutex_lock'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexUnlock':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:260: undefined reference to `_imp__pthread_mutex_unlock'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexDestroy':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:266: undefined reference to `_imp__pthread_mutex_destroy'
collect2.exe: error: ld returned 1 exit status
make: *** [CppUTestExamples_tests] Error 1
I'm using MinGW on Windows 7. The MinGW contains also the pthread.a library. My makefil look as follows:
#---------
#
# CppUTest Examples Makefile
#
#----------
#Set this to # to keep the makefile quiet
ifndef SILENCE
SILENCE = #
endif
#--- Inputs ----#
COMPONENT_NAME = CppUTestExamples
CPPUTEST_HOME = ..
CPPUTEST_USE_EXTENSIONS = Y
CPP_PLATFORM = Gcc
CFLAGS = -Dmalloc=cpputest_malloc -Dfree=cpputest_free
CPPFLAGS =
GCOVFLAGS = -fprofile-arcs -ftest-coverage
LDFLAGS = -lpthread
#USER_LIBS = -lpthread
# This line is overriding the default new macros. This is helpful
# when using std library includes like <list> and other containers
# so that memory leak detection does not conflict with stl.
CPPUTEST_MEMLEAK_DETECTOR_NEW_MACRO_FILE = -include ApplicationLib/ExamplesNewOverrides.h
SRC_DIRS = \
ApplicationLib
TEST_SRC_DIRS = \
AllTests
INCLUDE_DIRS =\
.\
ApplicationLib\
$(CPPUTEST_HOME)/include\
include $(CPPUTEST_HOME)/build/MakefileWorker.mk
As you can see the pthread lib is given to the linker with the LDFLAGS....
somebody similar experience? or maybe knows where the problem is?
Will be thankful for any tips!
thx to #Keith Marshall and #MadScientist,
so instead of
LDFLAGS = -lpthread
I used:
LD_LIBRARIES += -lpthread
and placed this line directly before:
include $(CPPUTEST_HOME)/build/MakefileWorker.mk
Now it works.
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called
ld) via the C compiler. The precise recipe used is:
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
instead.
So in this case -lpthread should be set or added to LDLIBS, not LDFLAGS.

Is it not allowed create a static library without a .c file in it?

I have two files -> fact.h and main.c in the /home/snyp1/new folder. main.c has the main function which calls the fact(int x) function in fact.h. I am creating a .a archive with the ar command ->
snyp1#Snyp:~/new$ ar -r -s libfact.a fact.o
ar: creating libfact.a
fact.h fact.o libfact.a main.c
snyp1#Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
snyp1#Snyp:~/new$ ranlib libfact.a
snyp1#Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
I am on ubuntu 12.04. Please let me know whats wrong. (Also, if I don't use the -L/.../new, gcc will say it can't find "lfact", maybe its because its not in /usr/local/lib)
EDIT: OK I have found the cause. Its due to the fact that I was using fact.h to build the fact.o and then putting it in the library, it wasn't working as expected. So I now changed it into file.c and is working fine now. I should have provided that information, I'm sorry. Though I don't know why this kind of problem should arise. Aren't libraries possible to make without at least one .c file in it?
I was using fact.h to build the fact.o and then putting it in the library, it wasn't working as expected.
Do you mean you were compiling fact.h to produce fact.o?
If so, that wasn't doing what you expect. When you invoke gcc on a header file it produces a precompiled header, not an object file. So although you got a file called foo.o it wasn't a valid object file. If you had just run gcc -c fact.h it would have produced a precompiled header fact.gch, but presumably you ran gcc -c fact.h -o fact.o which causes the file to be called fact.o even though it's still a precompiled header. file fact.o would have shown that:
$ file fact.o
fact.o: GCC precompiled header (version 013) for C
You could have forced GCC to treat the file as C code, not a header, by running gcc -x c -c fact.h -o fact.o (the -x c says to treat the input as C code instead of inferring the type from the file extension) but it's probably simpler and less confusing to just name your file correctly instead of trying to compile a header.
Aren't libraries possible to make without at least one .c file in it?
They need at least one object file (i.e. .o file) but you didn't have a valid object, you had a precompiled header misleadingly named as .o, but it was not actually an object file.
if I don't use the -L/.../new, gcc will say it can't find "lfact", maybe its because its not in /usr/local/lib
The linker doesn't only look in /usr/local/lib, there are other default places it looks, but yes, that's basically the problem. Note that you can also say -L. if the library is in the current directory, that's easier than giving an absolute path.
I'm not sure ar supports a dash on anything other than the first option. Try
ar -rs libfact.a fact.o
or just
ar rs libfact.a fact.o
Mind you, I don't know why running ranlib didn't work though.

compiler directive for compiling on different platforms

I am compiling a demo project.
The project is written for windows and linux. I have written a Makefile. However, I am not sure how to specify the platform the compiler will be compiling on.
I will be compiling on Linux.
In my source file I have this:
#if defined(WIN32)
#include ...
#include ...
#elif defined(LINUX)
#include ...
#include ..
#else
#error "OS not supported"
#endif
My simple Makefile is this. And when I compile I get the error "OS not supported".
How can I add the directive so that it will compile with the #elif defined(LINUX).
LIBS_PATH = -L/usr/norton/lib
INC_PATH = -I/usr/norton/include
LIBS = -lntr
app: *.cpp *.h Makefile
g++ $(LIBS_PATH) $(INC_PATH) *.cpp -o app
Many thanks for any suggestions,
Decide which is going to be your default platform - say LINUX.
LIBS_PATH = -L/usr/norton/lib
INC_PATH = -I/usr/norton/include
LIBS = -lntr
PLATFORM = -DLINUX
CXX = g++
app: *.cpp *.h Makefile
${CXX} ${CFLAGS} ${PLATFORM} ${INC_PATH} *.cpp -o $# ${LIBS_PATH} ${LIBS}
You can use round brackets in place of braces. This uses a macro for the C++ compiler, allows you to add other flags via CFLAGS (though that is also usually set by 'make'), and adds a platform, the include path, the library path and the actual library to the compile line.
Note that your rule enforces a complete recompilation of everything every time anything changes. This is 'safe' but not necessarily efficient. Note that wild-cards are dangerous too - more so for the source than the headers. You may include that backup copy of a file in the build (old-reader.cpp - you only wanted reader.cpp in there really). More conventionally, you list the object files needed for the program so that each object file can be individually rebuilt when needed, and the results linked together. If you get your dependencies correct (a moderately big 'if'), then there's no problem. If you get them wrong, you can end up with inconsistent programs.
However, if the difference is between a 5 second recompile and a 5 minute recompile, you should probably take the 5 minute recompilation (as shown) and answer another SO question while waiting.
To compile on Linux (64-bit):
make CFLAGS="-m64"
To compile on Linux (32-bit):
make CFLAGS="-m32"
To compile on Windows 64:
make PLATFORM=-DWIN64
To compile on Windows 32:
make PLATFORM=-DWIN32
Etc.
You can add -DLINUX=1 when compiling.
Also, if you run:
echo "" | cpp -dD
You can see the list of default #define when compiling. In linux, there will always be a:
#define __linux__ 1
in the output. So if you change your LINUX by the above #define, you don't need to do anything special. Ie:
...
#elif defined(__linux__)
...
As for the Makefile itself, I would do something like:
CXX=g++
CPPFLAGS = -I/usr/norton/include
LDFLAGS = -L/usr/norton/lib -lntr
OBJ_FILES = one.o two.o
app: $(OBJ_FILES) Makefile
one.o: one.cpp one.h
two.o: two.cpp two.h
So the implicit rules are used.

Resources