Makefile generating error - c

Every time I enter the command on UNIX
unix1% make clean
It returns an error message
mksh: Warning: newline is not last character in file makefile
Current working directory /home/s/m/mel
rm -f *.o core firstpass
unix1%
Here is my makefile:
firstpass: main.o hashFunct.o symbolTable.o opcodeTable.o
gcc main.o hashFunct.o symbolTable.o opcodeTable.o -o firstpass
main.o: main.c
gcc -c main.c
hashFunct.o: hashFunct.c
gcc -c hashFunct.c
symbolTable.o: symbolTable.c
gcc -c symbolTable.c
opcodeTable.o: opcodeTable.c
gcc -c opcodeTable.c
clean:
rm -f *.o core firstpass
I don't understand the problem, and I've tried to open it in emacs and see no mysterious characters. Also the word firstpass is the last character in the makefile. What does this error exactly mean?

mksh: Warning: newline is not last character in file makefile
The problem is exactly what it said, it wants a newline as the last character of the file. Currently the last character is probably the s of firstpass.
Open it in an editor, go to the end of the file, hit return.
Some editors will add a final newline to files for you.
A newline at the end of a file should not be a requirement. This sort of warning is common in older systems whose parsers might freak out if they are given input without a newline. Perl 1 is the only time I've seen this in the wild, and that's from 1987, but C compilers still issue this warning.

Related

C Programming: makefile:2: *** missing separator. Stop

My code is a spellchecker program that checks words from an input file and that checks those words from the inputfile with a dictionary file.
I am trying to create a makefile and keep getting this error here makefile:2: *** missing separator. Stop. In Addition, I am writing my code in repl.it.
I don't know what is happening or why it is doing that?
This is my makefile contents:
a.out: main.o spell_lib.o spell.o
gcc *.o
main.o: main.c spell_lib.h spell_lib.c
gcc -c main.c
spell_lib.o: spell_lib.h spell_lib.c
gcc -c spell_lib.c
regarding: gcc *.o
this line must begin with a <tab> not a space
I was able to fix the issue, i just went and copied and pasted my code i had previously created in putty which has the correct indentations.

Including input statements and conditions in the make file

I am trying to create a makefile, for the first time. I went through some tutorials and I managed to create one, but I am having trouble with a couple of things. Below are the details.
Below are the files in the order of execution:
CSV_to_txt.c - no dependency on any other files.
I want to include CSV_files/Equilibrium_trajectories.csv, which is my input, in the make file. Further, I run the command tac Chemical_Equilibrium.txt in the terminal. Can I include this in the make file as well?
fluid_profile.c - depends on pdfutil.h and beta_util.h.
I have the same problem of reading the inputs, for ex:
Enter the number of points
1000 --> to be included in the make file.
This file creates a text file called fluid_points.txt. What I want to include in the makefile is if this file already exists don't execute the command gcc fluid_points.c -o fluid_points.o -lm.
Structure of the make file:
all:
gcc CSV_to_txt.c -o CSV_to_txt.o -lm
./CSV_to_txt.o
#Include the file path and name when asked for it
#ubuntu terminal command --> tac filename.txt > filename_changed.txt
gcc fluid_profile.c -o fluid_profile.o -lm
./fluid_profile.o
#Enter the number of points when prompted to do so
#If fluid_points.txt file is already existing don't execute the above command, instead execute the below one
gcc blah.c -o blah.o -lm
./blah.o
clean:
$(RM) *.o *~
Any sort of help or even a link to a tutorial would be helpful.
A suggested makefile:
run:
.PHONY: run
CSV_to_txt: CSV_to_txt.c
gcc CSV_to_txt.c -o CSV_to_txt -lm
fluid_profile: fluid_profile.c
gcc fluid_profile.c -o fluid_profile -lm
blah: blah.c
gcc blah -o blah.c -lm
run: CSV_to_txt fluid_profile blah
echo "CSV_files/Equilibrium_trajectories.csv" | ./CSV_to_txt.o
tac Chemical_Equilibrium.txt
echo "1000" | ./fluid_profile.o
./blah.o
clean:
$(RM) *.o *~
So, a break down -- first line, predeclare target run, such that it becomes the default target (if you do make, it will run the first target ). Declare this as a phony target (This means there's no actual file called run being produced. You can look up .PHONY for more details)
Then create some rules to generate the executables. Each executable has its own rule to generate it. Typically you would use automatic variables for these like $# and $<, but I wanted to keep it simple for now.
Then the rule for run. This is dependent on the executables (so executables will finish building before this rule runs).
Then, to pass the filename into the executable, you can simply echo the filename, and then pipe that into the executable.
You have a common newbie error... this is to think that a source file depends on other source files (a .c file depends on some .h files) This is an error and probably the cause you are not getting your result.
The objective of a Makefile is to describe file dependencies in order to do the minimum set of commands to build the final target you specify. For this you need to think that a target is something you are goint to create.
Is a source .c file something you create during the build proces? Not, so it cannot be a target of a rule. The target, indeed is the result of the compilation. The source file doesn't depend on a header file... it just includes it to make the compilation of the .o target (this is, actually the target).
Let's say you have a program hello.c that includes modA.h and modB.h. (and even modB.h includes modB2.h) If you modify any of them, you need to recompile hello.c, so your rule will be:
# (1)
hello.o: hello.c modA.h modB.h modB2.h
cc -c hello.c # (2) see below.
(1) a rule line starts at column 1 and has a left hand side (the target file) and a list of sources (dependencies). Each time make sees that the target doesn't exist or has a last change date earlier than the change dates of any of the dependencies, the command lines below are executed, one after the other.
(2) a command rule starts with a <tab> char in the first column of the line. It represents a command (or a list of commands, each in it's command line) that are required to generate the target file from the sources.
a line starting with # is a comment line (also valid to start in the middle of a rule or a command line)
There is anothe type of line (a macro definition) but you need to learn first how to create dependencies and get used to them, before starting learning how to create macros. Read the make(1) doc first.
you see that we only compile hello.c, but we have to do it every time we change any of the other files above. There are two modules, modA.o and modB.o, each of them with their .c file and the includes needed in hello.c. So:
modA.o: modA.c modA.h
cc -c modA.c
modB.o: modB.c modB.h modB2.h
cc -c modB.c
so when we change any of modA.c or modA.h then modA.o will be created. And as modB.h we said above that included modB2.h, then if we modify it, it should be compiled.
Now the dependency of the program to be linked: As the program is compiled, it has just three modules: hello.o, modA.o and modB.o. To create hello all these three modules must be given to the linker.... so the Makefile needs also:
hello: hello.o modA.o modB.o
cc -o hello hello.o modA.o modB.o
and so, the complete Makefile is:
# this rule is put first to become the default target.
# the default target is the final program.
hello: hello.o modA.o modB.o
cc -o hello hello.o modA.o modB.o
# this rule is for the hello.o target only.
hello.o: hello.c modA.h modB.h modB2.h
cc -c hello.c
# this rule is for modA.o
modA.o: modA.c modA.h
cc -c modA.c
# and this one for modB.o
modB.o: modB.c modB.h modB2.h
cc -c modB.c
and with this Makefile you'll enjoy, because you can touch any file, but the compiler will compile only the correct dependencies to generate the final executable program.
Make has a lot of more functionality, but that requires you to know at least the most basic of it. Once after you have succeeded on the creation of the correct dependencies, you can start to study the other facilities of make, that are only there to abbreviate/avoid rewritting the same thing several times. But read at least the make manual page.

Makefile in C: all vs target -std=c1x error

I am working on a C homework assignment and I came across a simple yet specific error when creating my Makefile.
My initial Makefile was simple:
all: numbers.o
gcc -Wall -pedantic -std=c1x numbers.c -o numbers
clean:
rm *.o
For whatever reason, despite the C program compiling correctly in the terminal, I repeatedly get the following error:
gcc: error: -std=c1x: No such file or directory
Makefile:2: recipe for target 'all' failed
The problem was actually because I had copied the gcc line from a pdf file. Thanks to the comment by raspy:
For sure it has nothing to do with target name. It looks like gcc did not treat the switch as a switch, but rather as a file name. Have you copied this command from somewhere? It happens that the - is not a simple dash but some dashy-looking Unicode character, most notably converted in word processors.

C Makefile compilation error - "linker input file unused because linking not done"

I'm having a problem with a C Makefile.
This is the code for the Makefile in bash:
CC=gcc
CFLAGS=-g -Wall
CCLINK=$(CC)
OBJS=flight.o runway.o airport.o main.o
RM=rm -f
# Creating the executable (airport)
airport: $(OBJS)
$(CCLINK) -o airport $(OBJS)
# Creating object files using default rules
main.o: main.c airport.h ex2.h flight.h runway.h
airport.o: airport.c airport.h ex2.h flight.h runway.h
runway.o: runway.c runway.h ex2.h flight.h
flight.o: flight.c flight.h ex2.h
# Cleaning old files before new make
clean:
$(RM) airport *.o *.bak *~ "#"* core
When I make the file, it says that:
make: `airport` is up to date.
After that - I can call "airport" in bash and it lets me enter some inputs the way I want it to be.
BUT- when I'm trying to check if "airport" is compiled by:
gcc -g -Wall -c airport
I get an error says that:
gcc: airport: linker input file unused because linking not done
Does someone know what could be the problem?
Thanks!
Gavriel.
The aim of Makefile is to avoid recompiling a file if its source is unchanged; when it happens, make says that the file is up to date.
This might be annoying if you want to check again the warnings. Then, simply call make to recompile everything, by typing
make clean ; make
Another goal of Makefile is to avoid typing the gcc commands by yourself, prone to errors. For instance, at the end of your question, you ask to make an object file from an executable (option -c), which is wrong. The good way to make an object file is to call make :
make airport.o
Finally, to produce the executable, you can either type
make airport
or, since airport: is the first target, type
make

Error: Don't know how to make

I have been given a makefile which I modified into this:
############################################
# Makefile using OCI (Oracle Call Interface)
# D. LaRue - May, 2001
############################################
ORACLE_HOME=/opt/oratcp11/product/11.2.0/client11R2_32bits
CC=/opt/SUNWspro/SUNWspro12/sparc/SUNWspro/bin/cc
COMMON_SRC=../common
BNS_INCLUDE=../include
LIBHOME=$(ORACLE_HOME)/lib/
RDBMSLIB=$(ORACLE_HOME)/rdbms/lib/
WSSCOMMON_LIB=/vobs/wssCommon/lib_32
TARGET_DIR=.
LLIBCRYPTO =-lbnscrypto
LSOLCRYPTO =-lcryptoutil -lpkcs11
WSSLIBS =-lwssmbx -ldes
LIBRDBMS_CLT =-lclient11 -lvsn11 -lcommon11 -lgeneric11 -lmm
LLIBCLNTSH =-lclntsh -ldl
CORELIBS =-lcore11 -lnls11
LDLIBS =-lnsl -lsocket -lgen -lm
EXSYSLIBS =-R $(ORACLE_HOME)/lib
STATICTTLIBS =$(LLIBRDBMS_CLT) $(CORELIBS) $(WSSLIBS) $(LLIBCRYPTO)
OCISHAREDLIBS =$(LLIBCLNTSH) $(LDLIBS) -Bstatic $(STATICTTLIBS) -Bdynamic $(LSOLCRYPTO)
LDFLAGS =-L$(ORACLE_HOME)/lib -L$(ORACLE_HOME)/rdbms/lib -L$(WSSCOMMON_LIB) -L../lib_32
INCLUDE =-I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/plsql/public -I$(ORACLE_HOME)/network/public -I$(COMMON_SRC) -I$(BNS_INCLUDE) -I.
CFLAGS =$(INCLUDE) $(LDFLAGS) -g -Xt
BESSOBJS=bessToWss.o
COMMONLIST=$(COMMON_SRC)/oracle.c \
$(COMMON_SRC)/logger.c
INTFOBJS=$(BESSOBJS) $(COMMONLIST)
ALL: $(TARGET_DIR)/bessToWss
$(TARGET_DIR)/bessToWss: $(INTFOBJS)
$(CC) $(CFLAGS) $(INTFOBJS) $(OCISHAREDLIBS) -o $#
clean:
$(RM) *.o
When I run the file I get an error
". Stop.e: Error: Don't know how to make "bessToWss
Any idea what is wrong? I run this on some unix machine via a script. The script calls make after sets some paths or some other settings. As you can see I'm not sure how it's called.
Thanks :)
The error message looks peculiar — do you have CRLF line endings in the makefile?
". Stop.e: Error: Don't know how to make "bessToWss
That could be:
/bin/make: Error: Don't know how to make "bessToWssCR". Stop.
where the CR is the carriage return moving the print position back to the start of the line.
Did you create the makefile, or edit it, on a Windows machine? Did you FTP or copy it without using a text mode transfer, so the CRLF line-endings were preserved?
If so, get rid of the carriage returns. Edit the file on Unix with vim and do :set fileformat=unix and save again.
Under this hypothesis, make is trying to build a program whose name includes a CR (carriage return) in the name and you've not given it a rule for doing that.

Resources