I'm trying to run a simple makefile that looks like this:
T=-ansi -pedantic -Wall -Werror
a.out: test.o extra.o
gcc $(T) -c test.o extra.o
test.o: test.c test.h
gcc $(T) -c test.c
extra.o: extra.c extra.h
gcc $(T) -c extra.c
clean:
rm *.o a.out
But I seem to be getting warnings telling me that "linker input file unused because linking not done"
I tried removing the "-c" from the a.out directive, after the gcc, but that produced to give me more problems. I'm not sure how to go about proceeding from here, any ideas/input would be much appreciated.
EDIT: I'm running the program by "make -T", also removing the -c from a.out, causes the error" invalid symbol index"
You need to remove the -c from the a.out command:
a.out: test.o extra.o
gcc $(T) test.o extra.o
or, better:
a.out: test.o extra.o
gcc $(T) -o $# test.o extra.o
or, still better:
extra: test.o extra.o
gcc $(T) -o $# test.o extra.o
The error message is normally because you specify something like -lm on a command line with -c, but you're not doing that here. OTOH, you are listing object files with the -c option — that'll generate the warning:
gcc -ansi -pedantic -Wall -Werror -c test.o extra.o
^ this one, here
Those .o files are the linker inputs, but you're not linking. Drop the -c and you will generate a.out. That should proceed OK.
I think this is the first time I've seen a makefile used to build a.out. It is unusual in the extreme — not precisely wrong, but definitely not the way you normally use make. It has built-in rules to build programs from single source files, such as example from example.c. Normally, you give a program a meaningful name based on one of the source files. Note that creating a program test is usually a bad idea; there is a standard test command built into the typical shell and confusion is rampant.
Related
For a project, I have to create a simple makefile for the source code which includes pthreads and command line arguments (if those matter to include).
The first version of the makefile that didn't work was this:
mr: mr.o
g++ -std=c++11 -pthread mr.o -o mr
mr.o: mapred.cc
g++ -std=c++11 -pthread -c mapred.cc
clean:
rm *.o mr
and I got the following error that the object file did not exist?
So then I decided to flip the two first statements around:
mr.o: mapred.cc
g++ -std=c++11 -pthread -c mapred.cc
mr: mr.o
g++ -std=c++11 -pthread mr.o -o mr
clean:
rm *.o mr
and it compiles, sort of? All I get in the terminal is:
g++ -std=c++11 -pthread -c mapred.cc
and nothing else. When I look at what files were created, all I see is a new file mapred.o created but no executable. So no errors but not fully completed. If you guys have any tips to help me out that would be very appreciated. Thank you!
If you don't specify an explicit output name with the -o option, then the compiler will name object file the same as the source file but with an .o suffix.
In your case, the command
g++ -std=c++11 -pthread -c mapred.cc
will create an object file named mapread.o.
Either use mapread.o for your target names and when linking, or use the -o option:
g++ -std=c++11 -pthread -c mapred.cc -o mr.o
As for your second problem, unless you specify an explicit target when invoking make, it will only use the first target and nothing else.
I have made a Makefile for my CMSC 202 course project, 'Blackjack'. It does everything I need it to and it works perfectly. You may be asking why I posted here then, this is because I have no idea how it works and I didn't use any other resources but myself to create it.
Here is my Makefile code.
# Object files to either reference or create
OBJECTS = Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
# The executable file that will be created at the end
EXEC = Proj2.out
# The flags to use for compilation
FLAGS = -Wall
# The code compiler to use for compilation
CC = g++
# Perform action on all object files (May or may not exist)
all: $(OBJECTS)
$(CC) $(FLAGS) -o $(EXEC) $(OBJECTS)
Here is the terminal output when I call make in the terminal.
g++ -c -o Proj2.o Proj2.cpp
g++ -c -o Blackjack.o Blackjack.cpp
g++ -c -o Deck.o Deck.cpp
g++ -c -o Card.o Card.cpp
g++ -c -o Hand.o Hand.cpp
g++ -c -o Player.o Player.cpp
g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
Can anyone tell me how the .o files are being compiled? It does not look like they are being prompted to be compiled with that g++ -c -o $.o $.cpp command anywhere in the Makefile. Nor did I state to use any .cpp files.
Thank you in advance for your help.
Edit
Thanks to all your great help, this is now the terminal output I receive when using make.
g++ -Wall -c -o Proj2.o Proj2.cpp
g++ -Wall -c -o Blackjack.o Blackjack.cpp
g++ -Wall -c -o Deck.o Deck.cpp
g++ -Wall -c -o Card.o Card.cpp
g++ -Wall -c -o Hand.o Hand.cpp
g++ -Wall -c -o Player.o Player.cpp
g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
Thank you so much to all of you who have contributed.
Make has a set of implicit rules (see here for a reference). For instance
Compiling C++ programs
`n.o' is made automatically from `n.cc' or `n.C' with a command of the form
`$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)'.
Most make's will also use this rule for .cpp files.
When make sees there's a x.o requirement for one of your targets, it will try to see if it can generate x.o using implicit rules, and in your case find it can do it starting from a .cpp file.
This Makefile uses implicit rules which are a great way to reduce duplication.
By default the first target will be built, here all. It depends on a number
of object files listed in a variable $OBJECTS, e.g. Proj2.o who's
dependencies aren't listed in the Makefile. Now if make sees an input file in the current directory
with a matching name, e.g. Proj2.cpp it will try
to build Proj2.o from it (there are other implicit rules for sources in
other languages). Proj2.o would then be built by default with the command
$(CXX) $(CXXFLAGS) -c -o Proj2.o
where $(CXX) the name of the C++ compiler (g++ in your case).
The explicit build step for all assembles all the object files into the
target executable.
Looking at above build command you'll notice a small problem in your Makefile. Since the flags to the C++ compiler are given in a variable FLAGS and not the standard CXXFLAGS no warnings will be emitted when building the object files. Using the standard name would fix this (you do want warnings, maybe even more than -Wall gives you).
I am trying to compile a program consisting of two source files:
wildcardtrie.h, wildcardtrie.cpp
using a Makefile. However, when I run GDB to debug, I get the following error:
Reading symbols from /home/meric/Documents/Random/SectionLeading/wildcardtrie...(no debugging symbols found)...done.
I have tried a number of different compiler flags, none of which worked. The thing that perplexes me is that I have used a nearly identical Makefile in other programs and missing symbols has never been a problem. I have included the Makefile below:
CC=g++
CFLAGS = -g -ggdb g++ -O0 -Wall -Wfloat-equal -Wtype-limits -Wpointer-arith -Wlogical- op -fno-diagnostics-show-option
LDFLAGS = -g -ggdb -std=c++0x
programs = wildcardtrie
all : $(programs)
clean:
rm -f $(programs) core *.o
.PHONY: clean all
I have tried removing '-g' and '-ggdb' in the compiler and linker flags, but nothing seems to work. When I call 'make', I get the following output on the terminal:
g++ -c -o wildcardtrie.o wildcardtrie.cpp
g++ -g -ggdb -std=c++0x wildcardtrie.o -o wildcardtrie
Any help would be greatly appreciated!
g++ -c -o wildcardtrie.o wildcardtrie.cpp
This clearly shows that -g is not on your compile line (which is exactly the cause of your problem).
To get -g there, either add it to CXXFLAGS (this is the preferred solution), or just write the compile rule explicitly (instead of relying on built-in make rule):
wildcardtrie.o: wildcardtrie.cpp
$(CC) $(CFLAGS) -o wildcardtrie.o wildcardtrie.cpp
I am taking a C++ course in college and they want us to manually type in all of the test files... I know, however, that there is a way to do it with out, which is how I ended up with the current(http://pastebin.com/6d9UtKM4) makefile. My question is, why is this makefile automatically removing all the .o files it uses for compiling when it is done? It's not killing me, but I would like to preserve the .o files. I have pasted the makefile here(http://pastebin.com/6d9UtKM4). I have also pasted the current result of running "make tests" here(http://pastebin.com/h3Ny3dib). (Note the part at the bottom of that page that removes all the .o files automatically.)
I would also like to be able to make it generate it like this:
g++ -o compileDir/assembler.o -c -Wall src/assembler.cpp
g++ -o compileDir/string.o -c -Wall src/string.cpp
g++ -c -Wall -o compileDir/test_assignment.o testSrc/test_assignment.cpp
g++ -o testDir/test_assignment compileDir/test_assignment.o compileDir/string.o compileDir/assembler.o
g++ -c -Wall -o compileDir/test_bracket.o testSrc/test_bracket.cpp
g++ -o testDir/test_bracket compileDir/test_bracket.o compileDir/string.o compileDir/assembler.o
testDir/test_bracket
testDir/test_assignment
In other words, I want it to compile everything, then run everything. I hope this isn't too much to ask!
Edit: Additional Information: (This is the code that does "make tests")
tests: assembler.o string.o $(test_output) $(test_stringOutput)
#echo '--- Testing complete ---'
$(testDir)%: $(compileDir)%.o string.o
g++ -o $# $< $(compileDir)string.o $(compileDir)assembler.o
$#
#echo ''
$(compileDir)%.o: $(testSourceDir)%.cpp
g++ -c -Wall -o $# $<
$(compileDir)%.o: $(testStringSrc)%.cpp
g++ -c -Wall -o $# $<
EDIT: -----------------------------------------
Resolved via comments:
Adding this line fixed it:
.PRECIOUS $(compileDir)%.o
You might add
.PRECIOUS: %.o
which should be implicit, but perhaps you've got a weird setup.
Make treats your .o files as intermediate and removes them. You can prevent automatic deletion of those by adding them a dependency of the special .SECONDARY target. See Chains of Implicit Rules for more details. Good luck!
Hi all: quick question: I'm in a situation where it would be useful to generate my C++ executable using only 'gcc' (without g++). Reason for this is that I have to submit the code to an automatic submission server which doesn't recognize the 'g++' (or 'c++', for that matter) command.
In my experiments, while I'm compiling gcc works well. Problem is, when I try to link the generated object files it gets messed up. Now, based on what I understood from the gcc man page (I may be way off, so tell me if I am), g++ is basically gcc, but it links the C++ library.
If this is true, how can I (if possible) explicitly link the C++ library without using the g++ (or c++) command?
EDIT: I'm adding the makefile to better illustrate the problem:
COMPILER = gcc
CFLAGS = -Wall -g -x c++
# MODULE COMPILATION
model: modules/model.h modules/sources/model.cpp
$(COMPILER) $(CFLAGS) -c modules/sources/model.cpp -o obj/model.o
algorithms: modules/algorithms.h modules/sources/algorithms.cpp
$(COMPILER) $(CFLAGS) -c modules/sources/algorithms.cpp -o obj/algorithms.o
io: modules/io.h modules/sources/io.cpp
$(COMPILER) $(CFLAGS) -c modules/sources/io.cpp -o obj/io.o
stopwatch: modules/stopwatch.h modules/sources/stopwatch.cpp
$(COMPILER) $(CFLAGS) -c modules/sources/stopwatch.cpp -o obj/stopwatch.o
# EXECUTABLE GENERATION
exe: model algorithms io stopwatch
$(COMPILER) $(CFLAGS) main.cpp obj/model.o obj/algorithms.o obj/io.o obj/stopwatch.o -o bin/process
# DEFAULT TEST CASE
run: exe
./bin/process -i data/nasa_small.log -a data/nasa_small.access -s data/nasa_small.stack
# CLEANING ROUTINE
clean:
rm -f obj/*
You can link the standard c++ library with the -l flag to gcc:
gcc cplusplus.o -lstdc++ -o myexe
If you run g++ with the "-v" option, it will show what command and options it uses. You should be able to deduce the correct gcc command line from there.