0

My Makefile:

CXX = g++
CXXFLAGS = -g -Wall -std=c++14
LDFLAGS = -lboost_system -lcrypto -lssl -lcpprest -lpthread

SRC := $(shell find . -name *.cpp)
OBJ = $(SRC:%.cpp=%.o)
BIN = run

all: $(BIN)

$(BIN): $(OBJ)
    $(CXX) $(LDFLAGS)

%.o: %.cpp
    $(CXX) -c $(CXXFLAGS) $< -o $@

clean:
    find . -name *.o -delete
    rm -f $(BIN)

It scans for all files *.cpp files in all subdirectories and creates corresponding *.o files. Then it tries to link everything into a final binary, but I get the following error. I don't have any idea how to resolve this issue.

/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.1/../../../../lib/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'

Directory structure:

Makefile
sources/
    directory1
        ...cpp
    directory2
        ...cpp
    ...
    main.cpp

main.cpp content:

#include <iostream>

#include <signal.h>

#include "application/application_launcher.hpp"

Alastriona::Application::Launcher launcher;

void shutdown(int signal);

int main(int argc, const char * argv[])
{
    struct sigaction sa;
    sa.sa_handler = &::shutdown;
    sa.sa_flags = SA_RESTART;
    sigfillset(&sa.sa_mask);

    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGQUIT, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

    launcher.loadArguments(argc, argv);
    launcher.loadConfiguration();
    launcher.startApplication();
}

void shutdown(int signal)
{
    launcher.stopApplication();
}
CorellianAle
  • 645
  • 8
  • 16

1 Answers1

1
int main(int argc, const char * argv[])

Is an overload due to the constness, which is not allowed, and considered ill formed §2 by the standard. The signature you need to use is

int main(int argc, char * argv[])

Edit : Your are not using any prerequisite when trying to build the target. You should have

$(BIN): $(OBJ)
    $(CXX) $^ $(LDFLAGS)
UmNyobe
  • 22,539
  • 9
  • 61
  • 90
  • But why did compiler allowed it in the first place? – CorellianAle Jan 15 '18 at 11:21
  • see https://stackoverflow.com/tags/undefined-behavior/info . may not compile, may compile and not link, may link but produce unexpected result, may link and produce expected results are possible scenarios of ub – UmNyobe Jan 15 '18 at 11:22
  • It is not disallowed by the standard. The standard says that `main` can have any implementation defined signature as long as it returns an `int` and that any implementation **must** support two signatures being `int main()` and `int main(char**)`. So it is not banned by the standard, just non-portable. – Galik Jan 15 '18 at 11:27
  • I've fixed main prototype but it is still not compiling. https://gist.github.com/CorellianAle/e1424bc1d16a08b4acbee17a94f4da55 I am sorry but I still can't see my error. Maybe now that `main.cpp` is correct something is wrong in a `Makefile`? – CorellianAle Jan 15 '18 at 11:31
  • @Galik `A program *shall* contain` is the term used. ill-formed - the program has syntax errors or diagnosable semantic errors. A conforming C++ compiler is required to issue a diagnostic, even if it defines a language extension that assigns meaning to such code (such as with variable-length arrays). The text of the standard uses shall, shall not, and ill-formed to indicate these requirements. http://en.cppreference.com/w/cpp/language/ub – UmNyobe Jan 15 '18 at 11:31
  • I see nothing in the standard that says the program is ill formed. It says the signature of `main` is *implementation defined*. These words: *"it shall have a declared return type of type int, but otherwise its type is implementation-defined"*. – Galik Jan 15 '18 at 11:35
  • This answer seems relevant. It quotes `C++98` standard but the wording has hardly changed in `C++17` https://stackoverflow.com/questions/1621574/can-the-arguments-of-mains-signature-in-c-have-the-unsiged-and-const-qualifie – Galik Jan 15 '18 at 11:41