简体   繁体   中英

How do I properly compile C++ with header using Makefile?

I'm trying to build a program on macOS terminal with a header file. I have included the header on my cpp file. But I encountered error :

Error :

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Here's the file I try to run

#include <iostream>
#include <opencv2/opencv.hpp>
#include "plot.h" //Header File 

using namespace cv;
using namespace std;

int PlotGraph(Mat & data) {

    //converting the Mat to CV_64F
    data.convertTo(data, CV_64F);
    Mat plot_result;

    Ptr<plot::Plot2d> plot = plot::Plot2d::create(data);
    plot->setPlotBackgroundColor(Scalar(50, 50, 50));
    plot->setPlotLineColor(Scalar(50, 50, 255));
    plot->render(plot_result);

    imshow("Graph", plot_result);
    waitKey();

    return 0;
}

I have tried change the compiler using -c , but still encounter the same error. Here's my makefile

Makefile :

BIN_DIR= .
CC = g++
CFLAGS = -std=c++11 $(shell pkg-config --cflags opencv)
LIBS = $(shell pkg-config --libs opencv)

all: $(BIN_DIR)/trial1

$(BIN_DIR)/trial1: trial1.o
    ${CC} -o $(BIN_DIR)/trial1 trial1.o $(LIBS)

trial1.o: trial1.cpp
    ${CC} $(CFLAGS) -c trial1.cpp

clean:
    rm -f *.o
    rm -f $(BIN_DIR)/trial1

allclean:
    rm -f *.o
    rm -f $(BIN_DIR)/trial1
    rm -f Makefile

I tried with other simple program like "Hello World" and it compiled properly, but not this one. Any advice ?

Assuming the code you've put in your question is the entirety of trail1.cpp and judging from the linker error it seems you're missing a pretty simple thing...

int main() {
    return 0;
}

This function is required in every c/c++ program, and it must be called main (ie you can't change it to PlotGraph , you can make a separate function PlotGraph that gets called from main() but it's no substitute). You also have two options for main. As an alternative for the one above, you can do:

int main(int argc, const char** argv) {
    return 0;
}

(there's some freedom with how you define the const depending on how convenient vs how precise you want to be... ie you could also use char const * const * const argv , but that's another story)

As a final hint, you should probably make a backup of your Makefile as it looks like after you run make allclean your makefile will be gone and you will not be able to run make again due to the last line being rm -f Makefile

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM