Make did not work after I changed my file - makefile

These are my files:
add.c add.h main.c makefile
This is makefile:
main:main.o add.o
gcc -o main main.o add.o
main.o:$(#:%.o=%.c)
gcc -o main.o -c main.c
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
gcc -o add.o -c add.c
.PHONY:clean
clean:
rm *.o -rf
rm main -rf
Then after I change the main.c and make.
But make told me this:
make: `main' is up to date.
If I change my makefile:
main:main.o add.o
gcc -o main main.o add.o
main.o:main.c
gcc -o main.o -c main.c
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
gcc -o add.o -c add.c
.PHONY:clean
clean:
rm *.o -rf
rm main -rf
Then after I change the main.c and make.
It can work.
I donot know the reason.

The dependencies in
main.o:$(#:%.o=%.c)
add.o:$(#:%.o=%.c) $(#:%.o=%.h)
are not valid make syntax.
Replace these two rules with one pattern (generic) rule:
%.o : %.c
gcc -c -o $# ${CPPFLAGS} ${CFLAGS} $<
The above rule is actually very similar to the built-in rule for compiling .o files from .c:
Compiling C programs
n.o is made automatically from n.c with a recipe of the form $(CC) $(CPPFLAGS) $(CFLAGS) -c.
In other words, you can remove your original rules for main.o and add.o and it should build correctly.

Related

How to build static library .a for ARM using cross compiler?

I was trying to compile statically cpp-netlib and rpclib for ARM device.(Same as ZEDboard)
Everything i did is changed the compiler and system settings in CMakeLists.txt file.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT /home/a/buildroot-2018.05/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/)
set(tools /home/a/buildroot-2018.05/output/host/bin/)
set(CMAKE_C_COMPILER ${tools}arm-buildroot-linux-uclibcgnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}arm-buildroot-linux-uclibcgnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
After Makefile is created by cmake i ran make and no output has been produced. As i understand build directories should appear.
For the rpclib things went better. It has compiled the librpc.a file but unftunately its not linking to my program.
arm-buildroot-linux-uclibcgnueabihf-g++ -I/home/a/rpclib/include/ -Xlinker -static /home/a/rpclib/librpc.a main.cpp
produces this output:
/home/a/buildroot-2018.05/output/host/lib/gcc/arm-buildroot-linux-uclibcgnueabihf/6.4.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: cannot find -lgcc_s
/home/a/buildroot-2018.05/output/host/lib/gcc/arm-buildroot-linux-uclibcgnueabihf/6.4.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
but there is gcc_s in the sysroot directory.
~/buildroot-2018.05/output/host/arm-buildroot-linux-uclibcgnueabihf$ find ./ -name *gcc_s*
./sysroot/lib/libgcc_s.so
./sysroot/lib/libgcc_s.so.1
./sysroot/usr/include/boost/asio/detail/gcc_sync_fenced_block.hpp
./sysroot/usr/include/boost/atomic/detail/caps_gcc_sync.hpp
./sysroot/usr/include/boost/atomic/detail/ops_gcc_sync.hpp
./sysroot/usr/include/boost/atomic/detail/ops_gcc_sparc.hpp
./sysroot/usr/include/boost/atomic/detail/caps_gcc_sparc.hpp
./sysroot/usr/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
./lib/libgcc_s.so
./lib/libgcc_s.so.1
I guess i am missing something important about cross-compilation.
So basically i have 3 questions:
Can you suggest some resources about cross-compilation for embdedd devices?
How to compile cpp-netlib?
How to link already compiled librpc?
Actually buildroot supports building static libraries.
Steps to build a custom library using buildroot:
Create a folder inside buildroot/package folder with the name of target library.
e.g. my path looks like this /home/a/buildroot-2018.05/package/rpclib
Create Config.in file in target library dir with the needed parameters which can be checked in buildroot manual or better
Create [package-name].mk
Then add entry in /buildroot/package/Config.in
Then package can be marked for installation in menuconfig/target pacckages
My Config.in file for rpclib
config BR2_PACKAGE_RPCLIB
bool "rpclib"
depends on BR2_INSTALL_LIBSTDCPP
depends on BR2_USE_WCHAR
help
rpclib is a modern C++ msgpack-RPC server and client library
http://rpclib.net
My rpclib.mk file
RPCLIB_VERSION = v2.2.1
RPCLIB_SITE = $(call github,rpclib,rpclib,$(RPCLIB_VERSION))
RPCLIB_INSTALL_STAGING = YES
RPCLIB_INSTALL_TARGET = NO
RPCLIB_CONF_OPTS = -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
$(eval $(cmake-package))
And entry in Config.in in the buildroot/packages dir
source "package/rpclib/Config.in"
After executing make i received
./output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib/librpc.a
Working in my little beatle (https://gitlab.com/melviso1/beatle) I have a custom makefile for building rpclib without using cmake stuff (I apologize but I really hate cmake and similar tools). Maybe that can help.
Put it in the root of rpclib for building, clean or install. Please review tabs in the following script, because my pasting here can make some loses.
I used this to compile rpclib inside arm. For cross-compiling you could edit and change build tools.
CXXFLAGS=-std=c++0x -O3 -pthread -DASIO_STANDALONE -DRPCLIB_ASIO=clmdep_asio -DRPCLIB_FMT=clmdep_fmt -DRPCLIB_MSGPACK=clmdep_msgpack -Wall
INCLUDE=-Iinclude -I./dependencies/include
OBJS=obj/format.o obj/posix.o obj/client.o obj/client_error.o obj/response.o obj/server_session.o obj/dispatcher.o obj/optional.o obj/rpc_error.o obj/server.o obj/this_handler.o obj/this_server.o obj/this_session.o
all: obj librpc.a
obj:
mkdir -p obj
librpc.a: $(OBJS)
ar -r -s librpc.a $(OBJS)
obj/format.o: dependencies/src/format.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./dependencies/src/format.cc -o obj/format.o
obj/posix.o: dependencies/src/posix.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./dependencies/src/posix.cc -o obj/posix.o
obj/client.o: lib/rpc/client.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/client.cc -o obj/client.o
obj/client_error.o: lib/rpc/detail/client_error.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/client_error.cc -o obj/client_error.o
obj/response.o: lib/rpc/detail/response.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/response.cc -o obj/response.o
obj/server_session.o: lib/rpc/detail/server_session.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/server_session.cc -o obj/server_session.o
obj/dispatcher.o: lib/rpc/dispatcher.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/dispatcher.cc -o obj/dispatcher.o
obj/optional.o: lib/rpc/nonstd/optional.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
obj/rpc_error.o: lib/rpc/rpc_error.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
obj/server.o: lib/rpc/server.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
obj/this_handler.o: ./lib/rpc/this_handler.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
obj/this_server.o: lib/rpc/this_server.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
obj/this_session.o: ./lib/rpc/this_session.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $#
install:
cp -rf include/rpc /usr/local/include/
cp librpc.a /usr/local/lib/
uninstall:
rm -rf /usr/local/include/rpc
rm /usr/local/lib/librpc.a
clean:
rm -f librpc.a
rm -f obj/*
.PHONY: obj clean install uninstall`

I cannot get makefile to work

I have been fighting with makefile and I need help. I am running a virtual linux window in windows.
from a folder containing my main.c file, I type make and I get
$make
arm-linux-gnueabihf-gcc -g -Wall -I c:\intelFPGA\16.1\embedded\ip\altera\hps\altera_hps\hwlib\include _c main.c -o main.o
process_begin: CreateProcess(NULL, arm-linux-gnueabihf-gcc -g -Wall -I c:\intelFPGA\16.1\embedded\ip\altera\hps\altera_hps\hwlib\include _c main.c -o main.o, ...)failed.
make(e=2): The system cannot find the file specified.
make: *** [main.o] Error 2
This folder contains the following files and an empty folder.
main.c
Makefile
my_first_hps
If I type "where make", I get.
$where make
c:\intelFPGA_lite\16.1\nios2eds\bin\gnu\H-x86_64-mingw32\bin\make.exe
c:\intelFPGA\16.1\quartus\bin64\cygwin\bin\make.exe
c:\Coreutils\bin\make.exe
My Makefile is.
#
TARGET = my_first_hps
#
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -g -Wall -I ${SOCEDS_DEST_ROOT}c:/intelFPGA/embedded/ip/altera/hps/altera_hps/hwlib/include
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH= arm
build: $(TARGET)
$(TARGET): main.o
$(CC) $(LDFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
I know it's a bit late but for those who get the same error, I just changed the following line:
CC = $(CROSS_COMPILE)gcc
to
CC = $(CROSS_COMPILE)gcc.exe
which has worked for me. Also don't forget that you should have Altera EDS and DS-5 installed. I installed DS-5 at the same place with EDS:

Multiple Level of Dependencies in a Makefile

I am very new to makefiles. I have been able to write the script shown below by copying different examples found online. If I am doing something wrong, or not conventional, please point it out.
This is my (working) Makefile for a fortran code I have. The main program stored in main.f08 calls a module stored in file1.f08:
FC = gfortran
SRCS: main.f08
OBJS: $(SRCS:.f08=.o)
EXEC: $(SRCS:.f08=)
all: $(EXEC)
file1.o file1.mod: file1.f08
$(FC) -c $<
touch $*.o $*.mod
main.o: file1.mod
%.o: %.f08
$(FC) $(FFLAGS) -c $<
main: file1.o
%: %.o
$(FC) -o MainExe $^
clean:
rm -f MainExe *.o *.mod
I have tried to extrapolate that technique to write a makefile which has a ladder of dependencies. For example, main.f08 would be calling the module file1.f08, which in turn would be calling the module file2.f08. Here is what I have so far:
FC = gfortran
SRCS: main.f08
OBJS: $(SRCS:.f08=.o)
EXEC: $(SRCS:.f08=)
all: $(EXEC)
file2.o file2.mod: file2.f08
$(FC) -c $<
touch $*.o $*.mod
file1.o: file2.mod
file1.o file1.mod: file1.f08
$(FC) -c $<
touch $*.o $*.mod
main.o: file2.mod file1.mod
%.o: %.f08
$(FC) $(FFLAGS) -c $<
main: file1.o
%: %.o
$(FC) -o MainExe $^
clean:
rm -f MainExe *.o *.mod
The command line output consist of a few line showing that the code starts compiling the two modules and the main program and then several lines of errors that look like this:
Undefined symbols for architecture x86_64:
"___brownian_MOD_calcb", referenced from:
___integral_MOD_calcint in Integral.o
I've been working on this and I actually have figured it out.
The main executable should be linked to the module's object files in the correct order (an object file should not precede its dependency) followed by its object file, main.o. The module's object file should be linked to their dependency (if any) and their .f08 file. Finally, the touch command makes sure that the .mod files are up to dates with the .o files. Here is the corrected code showed in its simplest version:
FC = gfortran
all: main
main : file2.o file1.o main.o
$(FC) -o executable file2.o file1.o main.o
main.o: main.f08
$(FC) -c main.f08
file2.o : file2.f08
$(FC) -c file2.f08
touch file2.o file2.mod
file1.o : file2.o file1.f08
$(FC) -c file1.f08
touch file1.o file1.mod
A more advanced version of the makefile is shown below:
FC = gfortran
SRCS = main.f08
SOBJ = $(SRCS:.f08=.o)
EXEC = #(SRCS:.f08=)
FILE = file2.f08 file1.f08
FOBJ = $(SRCS:.f08=.o)
all: $(EXEC)
$(EXEC): $(FOBJ) $(SOBJ)
$(FC) -o executable $^
%.o: %.f08
$(FC) -c $<
touch $*.o $*.mod

How can I write a mingw-make makefile on Windows?

I am new to using GNU make. I have a makefile as below:
CFLAGS = -c -I $(WXWIN)\include\
hello: main.o
main.o:main.cpp
gcc -c main.cpp
clean:
rm main.o
When I run make command in console it can't find the header file "wx/wx.h". Its location: $(WXWIN)=D:\wxWidgets\
Change your makefile as follows:
CFLAGS = -c -I $(WXWIN)\include
hello: main.o
main.o: main.cpp
gcc $(CFLAGS) main.cpp
clean:
rm main.o

How to define rules in the Makefile to compile only that *.cpp files which was modified (and their dependencies), not all *.cpp files

Lets say I have files:
Libs:
one.cpp, one.h
two.cpp, two.h
three.cpp, three.h
Program:
program.cpp
Is there way, to create Makefile which will compile only that *.cpp which were modified from last compilation?
Currently I have something like that:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: $(OBJS) program
.cpp.o:
g++ -Wall -c $<
program:
g++ -Wall $(OBJS) program.cpp -o program
clean:
rm -f $(OBJS) program
I works fine, but when I compile my program and then change two.cpp or two.h I need to run "make clean" first, because when I secondly run "make" I get:
Nothing to be done for 'all'.
I would like to change my Makefile in that way, it would recognize my changes and recompile that file and its dependencies (if one.cpp uses code from two.cpp which was modified, both files should be recompiled).
So if I modify two.cpp, make should do:
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
But if one.cpp uses code from two.cpp which was modified, make shold do:
g++ -Wall -c one.cpp
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
First we make the object files prerequisites of the executable. Once this is done, Make will rebuild program whenever one of the SRCS changes, so we don't need OBJS as an explicit target:
all: program
program: $(OBJS)
g++ -Wall $(OBJS) program.cpp -o program
Then we make the header files prerequisites of the objects, so that if we change three.h, Make will rebuild three.o:
$(OBJS): %.o : %.h
And finally since one.cpp uses code from two.cpp by means of two.h (I hope), we make two.h a prerequisite of one.o:
one.o: two.h
And to make things cleaner and easier to maintain we use automatic variables:
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
Put it all together and we get:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: program
$(OBJS): %.o : %.h
one.o: two.h
.cpp.o:
g++ -Wall -c $<
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
clean:
rm -f $(OBJS) program
There are a few more things we could do (like adding program.o to OBJS), but this is enough for today.
Add the files a command depends upon to run to the right of the target name.
Example:
default: hello.c
gcc -o hello.bin hello.c
install: hello.bin
cp hello.bin ../
All you need to do is tell make that the .o file depends on the .cpp file:
%.cpp.o: %.cpp
g++ -Wall -c -o $# $<

Resources