Reputation: 1
I write a Makefile to compile my C++ program, the Makefile code is as follow:
1 TARGET = main
2
3 CXX = g++
4 CXXFLAGS = -Wall -g
5 HEADER = $(wildcard ./*.h)
6 SRCS = $(wildcard *.cpp)
7 OBJS = $(patsubst %.cpp, %.o, $(SRCS))
8 RM = rm -f
9
10 $(TARGET):$(OBJS)
11 $(CXX) -o $@ $^
12
13 $(OBJS):$(SRCS)
14 $(CXX) $(CXXFLAGS) $< -o $@
15
16
17 .PHONY:clean
18 clean:
19 $(RM) $(OBJS) $(TARGET)
The file structure of the current directory is as follow:
.
├── main.cpp
├── Makefile
├── MyQueue.cpp
└── MyQueue.h
0 directories, 4 files
I use g++ main.cpp MyQueue.cpp -o queue
to compile the program, the result is right; BUT I use make
to compile the program the results are as follows:
g++ -Wall -g main.cpp -o main.o
/tmp/ccA6CmCE.o: In function `main':
/home/tzk/DSA/main.cpp:7: undefined reference to `MyQueue::MyQueue(int)'
collect2: error: ld returned 1 exit status
make: *** [main.o] Error 1
I have defined the MyQueue(int)
!The code of MyQueue.h
,MyQueue.cpp
and main.cpp
are as follows:
MyQueue.h
1 #ifndef MYQUEUE_H_
2 #define MYQUEUE_H_
3 class MyQueue
4 {
5 public:
6 MyQueue(int queueCapacity);
7 virtual ~MyQueue();
8 void ClearQueue();
9 bool QueueEmpty() const;
10 bool QueueFull() const;
11 int QueueLength() const;
12 bool EnQueue(int element);
13 bool DeQueue(int& element);
14 void QueueTraverse();
15
16 private:
17 int *m_pQueue;
18 int m_iQueueLen;
19 int m_iQueueCapacity;
20 int m_iHead;
21 int m_iTail;
22 };
23
24 #endif
MyQueue.cpp
1 #include "MyQueue.h"
2 #include <iostream>
3 using namespace std;
4
5 MyQueue::MyQueue(int queueCapacity)
6 {
7 m_iQueueCapacity = queueCapacity;
8 m_iHead = 0;
9 m_iTail = 0;
10 m_iQueueLen = 0;
11 m_pQueue = new int[m_iQueueCapacity];
12 }
main.cpp
1 #include <iostream>
2 #include <cstdlib>
3 #include "MyQueue.h"
4
5 int main(void)
6 {
7 MyQueue *p = new MyQueue(4);
8
9 delete p;
10 p = NULL;
11
12 return 0;
13 }
So What's wrong with my program or Makefile ?
==========================================================
I try to add -c
to the command as follows:
13 $(OBJS):$(SRCS)
14 $(CXX) $(CXXFLAGS) -c $< -o $@
But, the result still wrong:
g++ -Wall -g -c main.cpp -o main.o
g++ -Wall -g -c main.cpp -o MyQueue.o
g++ -o main main.o MyQueue.o
MyQueue.o: In function `main':
/home/tzk/DSA/main.cpp:6: multiple definition of `main'
main.o:/home/tzk/DSA/main.cpp:6: first defined here
main.o: In function `main':
main.cpp:(.text+0x21): undefined reference to `MyQueue::MyQueue(int)'
MyQueue.o: In function `main':
main.cpp:(.text+0x21): undefined reference to `MyQueue::MyQueue(int)'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
Upvotes: 0
Views: 114
Reputation: 409176
When you create object files you need the -c
option. You don't have it, which means g++
tries to create and link the executable file main.o
.
Your target to build object files is also wrong. It should be e.g.
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
Upvotes: 4
Reputation: 3172
You have to use the -c
flag to turn source files in object files.
Like in
$(OBJS):$(SRCS)
$(CXX) $(CXXFLAGS) -c $< -o $@
Upvotes: 2