why is gcc gets executed in this make file? - makefile

I have the following makefile when type make i got the following output. why is gcc gets called in this case?
nasm -felf ./source/multiboot.s
gcc multiboot.o -o multiboot
gcc: error: multiboot.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [multiboot] Error 4
makefile:
CC=gcc
ASM=nasm
ASMFLAG=-felf
SOURCE=./source/
all: multiboot
multiboot.o: $(SOURCE)multiboot.s
$(ASM) $(ASMFLAG) $(SOURCE)multiboot.s

The "all" command depends on "multiboot", but there is no explicit rule defining how to produce "multiboot". In this case, Make uses a predefined rule that understands that, if the "$target.o" target exists, then "$target" can be constructed from "$target.o" by running the linker (in this case, GCC).
It seems like the problem in this case is that your instructions for the "multiboot.o" command does not actually produce the file "multiboot.o" as output. Try simply doing:
multiboot.o: multiboot.s
(That is, without specifying the command to run). Simply declaring this dependency should, by a similar mechanism, result in an implicit rule/command to create the "multiboot.o" output from "multiboot.s".

Related

Makefile rules vs source and object files

I'm studying how 'make' works and I encountered a little oddity
Suppose I have a folder with only 'helloworld.c' and 'Makefile'
Makefile contains
helloworld: helloworld.o
gcc -o helloworld helloworld.o
The output of 'make' in a bash console is
cc -c -o helloworld.o helloworld.c
gcc -o helloworld helloworld.o
The rule "helloworld" depends on the file "helloworld.o" which is not present, hence make creates it (the first line in the output).
But why?
I would have expected it to fail, in absence of a "helloworld.o:" rule that tells it how to compile said file. Why does it run the first command out of its own will?
Thanks
The reason is implicit rules.
From the GNU Make manual:
Implicit rules tell make how to use customary techniques so that you
do not have to specify them in detail when you want to use them. For
example, there is an implicit rule for C compilation. File names
determine which implicit rules are run. For example, C compilation
typically takes a .c file and makes a .o file. So make applies the
implicit rule for C compilation when it sees this combination of file
name endings.
In other words, make knows how to build helloworld.o from helloworld.c even if you don't specify an appropriate rule.
To get more information on this subject you can follow GNU Make manual, especially section 10, which is devoted to the usage of implicit rules.

Cannot specify include file with make and MinGW

I'm facing an issue with a simple makefile and gcc (MinGW with Windows 10).
This is my simple makefile
IJNI=-I"C:\Program Files (x86)\Java\jdk1.7.0_79\include"
IJNIWIN32=-I"C:\Program Files (x86)\Java\jdk1.7.0_79\include/win32"
CC=gcc
default: main
main: lowlevelAccess.o
$(CC) $(IJNI) $(IJNIWIN32) -c lowlevelAccess -o lowlevelAccess.o
When from a command promp I launch make, I obtain:
gcc -c -o lowlevelAccess.o lowlevelAccess.c
lowlevelAccess.c:7:17: fatal error: jni.h: No such file or directory
#include <jni.h>
^
compilation terminated.
make: *** [lowlevelAccess.o] Error 1
What is wrong?
Thank you!
You aren't adding your -I flags on the lowlevelAccess.o compilation but that's the rule that needs it (not the linking rule where you have it now).
Try adding CFLAGS += $(IJNI) $(IJNIWIN32) to your makefile (possibly use CPPFLAGS instead I'm not sure offhand which is technically more correct here).
See Variables Used by Implicit Rules for what those variables are and Catalogue of Built-In Rules (or the output from make -qp) to see what the default rules that use those variables look like.

Trouble with simple makefile in C

I am somewhat of a beginner in C and have a project due where I need to include a makefile to compile my single file program that uses pthreads and semaphores. My makefile looks like:
# Makefile for pizza program
pizza: pizza.o
gcc -lrt -lpthread -g -o pizza pizza.o
pizza.o: pizza.c
gcc -lrt -lpthread -g -c pizza.o pizza.c
and I keep getting:
make: Nothing to be done for 'Makefile'.
I have done several makefiles before and have never gotten this message. I've tried different semantics in the makefile and have only gotten this same message. And yes, the command is tabbed after the target and dependency line.
Using gcc on tcsh. I have read other makefile posts on SO but I wasn't able to use any of the answers to figure it out for my case.
Any help would be greatly appreciated!
The arguments to make are the targets to be built.
You are running make Makefile which is telling make to try to build the Makefile target.
There is no such target in your makefile, make has no built-in rule that applies to that target and the file exists (and is assumed to be up-to-date) which is what that message is telling you.
To run the default target (by default the first target listed) you can just run make (assuming you are using a default name like Makefile for your makefile).
You can also use the -f argument to make to select an alternate makefile name.
So make -f Makefile will in this case (since Makefile is a default searched name) do the same thing as make.

Include mpi to make file

I am trying to include MPI compiler to my makefile. The makefile is already prepared such that I only need to include the address of the MPI compiler in a a separate env file. However doing so does not work. I can get the cpp file to run manually by typing:
mpicxx Demo_00.cpp -o aprogram
./aprogram
I test where the mpi compiler is located using:
which mpicxx
/usr/bin/mpicxx
In the env file the corresponding line is:
MPICXX=/usr/bin/mpicxx
However, when I try to 'make' he cpp file I get the following error:
make Demo_00
g++ Demo_00.cpp -o Demo_00
Demo_00.cpp:2:17: fatal error: mpi.h: No such file or directory
compilation terminated.
make: *** [Demo_00] Error 1
The cpp file is in the same folder as the env file and the makefile.
I am not quite sure how to identify the error.
Thank you for your help,
Tartaglia
If you want to change the name of the C++ compiler, you have to change the variable CXX. That's the default variable make uses when it wants to compile C++ code.
This line in your log file:
g++ Demo_00.cpp -o Demo_00
says that you are using g++ compiler instead of mpixx.
Usually in makefiles compiler definition is at the beginnig of the file and looks like this:
CC=g++
just change it to mpixx
CC=mpixx
Thank you all for your responses, I took a closer look into the makefile I thought I was using and it turns out, as you have already suggested, I was not using it at all. The makefile was only able to execute one specific cpp file with one specific name. So whenever I typed in make *.cpp I was using the standard make as you already pointed out.
Thanks again for your help.

Makefile not rebuilding dependencies

I'm new to using makefiles and trying to produce a basic makefile as part of an exercise for university. I have two source code files, chello.c and writeexit.s, which have to be compiled/assembled and then linked to produce chello.
This is the code I have so far for the makefile:
chello: chello.o writeexit.o
ld -N chello.o writeexit.o -o chello
chello.o: chello.c
gcc -c chello.c -o chello.o
writeexit.o: writeexit.s
as writeexit.s -o writeexit.o
The whitespace before ld, gcc and as are all tabs, so I think the whitespacing is fine. When I call 'make makefile', it returns 'make: Nothing to be done for `makefile'.' However, if I change the dependencies of chello, like chello.c, the same message is returned and chello's behaviour is not modified.
From man make:
make executes commands in the makefile to update one or more target
names, where name is typically a program. If no -f option is present,
make will look for the makefiles GNUmakefile, makefile, and Makefile,
in that order.
make makefile will actually execute your "makefile" (because it is listed among the default names in the man page) file, trying to build the "makefile" target (because of the argument you are passing), which already exists
What you need is to build the "chello" binary, so you have to type:
make chello
Or alternatively:
make -f makefile chello
Alternative account here, it seems to work fine if I just call "make" instead of "make makefile". This question can be ignored.

Resources