Creating a makefile for 3 files C++

Hello

I have 3 files

driver.cpp
hashtable.h
hashtable.hpp

hashtable.h has .hpp included. The driver.cpp has the header file included.

How can I make the MOST barebones makefile possible?

I just need it to generate an exectuable hash.x that i can run.

Im looking for something in the general format of

target: things
commands
link?:
commands
clean:
rm *.x *.o

I just dont know exactly what to type to make this work :(
The driver.cpp has the header file included.
Which header file? (Both `.hpp' and `.h' are often used for header files.)
I'm assuming some things about your files since I don't know about the difference between .h and .hpp files.
1
2
hash.x: driver.cpp hashtable.h hashtable.hpp
  $(CXX) $(OUTPUT_OPTION) $(CXXFLAGS) driver.cpp

should be sufficient. You will need to replace the two spaces of indentation with a SINGLE TAB CHARACTER; you must use a tab.

I'll leave this here: it's a pain in the ass to have to update the makefile every time you add an #include, change the name, or add a file. This can be automated. The alternative is having to do clean builds all the time, since you'll invariably forget to add some header file as a dependency of some source file.

Edit:
you want a clean target, too; yours is fine, with two exceptions -- we want to ignore errors, and clean is not a file we can create. Replace the indentation with a tab.
1
2
3
.PHONY: clean
clean:
  -rm *.x *.o
Last edited on
My issue is that every time I try to compile, I get a massive amount of errors basically all of the form

"error: shadows template parm 'class V' "
or
"error: declaration of 'class V'

Even though I have my #ifndef and everything, I have my endif,
and there are NO double declarations of templates anywhere, so I assumed it would be a linkage error, and this new makefile does not seem to fix that. Am I on the right track to solve this?
No, that's a compilation error.
If it was a linker error, that should have been reported in the message as coming from LD or whatever your linker's name is (I'm assuming you're using the GNU toolchain; that wasn't specified).

Here is one situation which can cause this issue:
1
2
template <typename V>
struct A { template <typename V> void foo() {}; };


We will be able to help much more effectively if you post some code.
Okay. I have a struct in my class but I avoided that situation specifically. The class is structured like this

#ifndef HASHTABLE_H
#define HASHTABLE_H

namespace cXXXXX;

{


template <typename K, typename V>
class HashTable
{
public:

// just functions that take K and V in parameters, no template definitions

private:

std::vector <std::list<std::pair<K, V>>> listVector;

size_t hash(const K &k) const;
void setPrimes(std::vector<unsigned long> &);

struct Node
{
K key;
V value;
Node* next;

Node() : next(NULL){
this->key = key;
this->value = value;

};

};

#include "hashtable.hpp"
}

#endif


The .hpp file that is linked to it is just full of functions formatted as

template< typename K , typname V>
function {
}

and produces errors on the every function on the template line
You really should show the code that actually produces the errors. It will get you better answers.

Regardless, this is enough for me to have a guess at the problem:
Hashtable.hpp contains template member function implementations. Normally these files end in a tpp, ipp, or similar extension, but that's besides the point.

Specifically, I guess your .hpp file contains code like:
 
template <typename K, typename V> void HashTable<K, V>::some_function(K) { blah };

The use of and K of V shadow the Hashtable's template parameters. some_function should not be declared as a template member function, because it isn't one. K and V are already visible.

Try instead something like
 
void HashTable::some_function(K) { whatever }
Last edited on
Yes, I apologize I should have included that. But yes you are exactly right about the format of the hpp file. The problem is it was given to me and I am not supposed to edit the function definitions, So I was hoping the problem was elsewhere
If you can edit hashtable.h, you can change the name of the class template parameters (e.g., to T and U) to get it to compile, and the declarations to reflect the fact that they are template member functions.

That's certainly not the best solution, but it's possibly workable.
Last edited on
Mininal makefile for that? No makefile at all. Sumply type:
 
make driver


Maybe we could add the header file dependencies and a default target for a more reasonable minimal makefile.
1
2
3
4
5
6
7
PROG = driver
SRCS = driver.cpp

all: $(PROG)

$(PROG): $(SRCS.cpp=.o) hashtable.h hashtable.hpp
    $(LINK.cc) $^ -o $@ $(LDFLAGS)

OP wanted the result to be named "hash.x", not "driver".
I don't think there is a way to do that using only implicit rules.

Also (at least in GNU Make) the first target to appear is the default, and "all" should probably be marked as a .PHONY target just in case there happens to be a file named "all" in the CWD.

Assuming G++ or Clang, we can make it more general:
1
2
3
4
CXXFLAGS += -MT $@ -MP -MMD -MF $(@:.o=.d)
hash.x: $(patsubst %.cpp,%.o,$(wildcard *.cpp))
	$(LINK.cc) $(OUTPUT_OPTION) $^
-include $(patsubst %.cpp,%.d,$(wildcard *.cpp))

Last edited on
Man make files are so confusing. I've never seen them written like that. I've always seen them written something like this (credit Bob Myers, FSU)

frac: main.o frac.o
g++ -o frac main.o frac.o

main.o: main.cpp frac.h
g++ -c main.cpp

frac.o: frac.cpp frac.h
g++ -c frac.cpp

clean:
rm *.o frac

Topic archived. No new replies allowed.