Why does undefined reference disappear after adding a .cpp file with empty main function when building shared...












0















I have makefile that builds shared library libsimpletron.so:



#shell
MKDIR_P = mkdir -p
#compiler
CC = g++
#cpp flags
FLAGS = -std=c++1z
CPPFLAGS = -fPIC -Wall -Wextra
LDFLAGS = -shared
#directories
INC_DIR = ../inc
LIB_DIR = ../lib
BIN_DIR = ../bin
OBJ_DIR = ./obj
ALG_DIR = ./algebra


SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo $(INC_DIR)/*.h)
_OBJECTS = $(SOURCES:.cpp=.o)
OBJECTS = $(patsubst %,$(OBJ_DIR)/%,$(_OBJECTS))

ALGEBRA = $(LIB_DIR)/libalgebra.so
TARGET = $(LIB_DIR)/libsimpletron.so

.PHONY: directories

all : directories $(ALGEBRA) $(TARGET)


directories: $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR)

$(OBJ_DIR):
$(MKDIR_P) $(OBJ_DIR)

$(BIN_DIR):
$(MKDIR_P) $(BIN_DIR)

$(LIB_DIR):
$(MKDIR_P) $(LIB_DIR)

$(ALGEBRA):
$(MAKE) -C $(ALG_DIR)



$(OBJ_DIR)/%.o: %.cpp $(HEADERS)
$(CC) -c $(FLAGS) $(CPPFLAGS) -o $@ $<

$(TARGET) : $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $^


.PHONY: clean
clean:
rm -f $(OBJ_DIR)/*.o


make command builds library successfully (I think) :



g++ -c -std=c++1z -fPIC -Wall -Wextra  -o obj/builder.o builder.cpp
...similar lines for each .cpp file...
g++ -shared -o ../lib/libsimpletron.so obj/builder.o obj/gradient_trainer.o obj/layer.o obj/neuron.o obj/perceptron.o obj/simpletron.o obj/trainer.o


Then I am trying to use this library. I compile my test xor as follows:



#compiler
CC = g++
#cpp flags
FLAGS = -std=c++1z
PUGI = -l pugixml
#directories
LIB_DIR = /home/lrdprdx/Projects/SimplePerceptron/lib
SIMPLETRON = -lsimpletron
ALGEBRA = -lalgebra

XOR = xor
SOURCE = xor.cpp

#config file
CONFIG = config.xml


$(XOR) : $(SOURCE) $(CONFIG)
$(CC) $(FLAGS) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR) $(SOURCE)


But when I try to compile this I get errors of undefined reference to .... OK, though I do not understand why those errors exist, I found that adding a .cpp file with an empty main function to the directory with other .cpp files fixes all the stuff:



//empty.cpp
int main()
{
return 0;
}


And after rebuild the shared library I make and execute xor successfully.
The question is: what is going on here?










share|improve this question



























    0















    I have makefile that builds shared library libsimpletron.so:



    #shell
    MKDIR_P = mkdir -p
    #compiler
    CC = g++
    #cpp flags
    FLAGS = -std=c++1z
    CPPFLAGS = -fPIC -Wall -Wextra
    LDFLAGS = -shared
    #directories
    INC_DIR = ../inc
    LIB_DIR = ../lib
    BIN_DIR = ../bin
    OBJ_DIR = ./obj
    ALG_DIR = ./algebra


    SOURCES = $(shell echo *.cpp)
    HEADERS = $(shell echo $(INC_DIR)/*.h)
    _OBJECTS = $(SOURCES:.cpp=.o)
    OBJECTS = $(patsubst %,$(OBJ_DIR)/%,$(_OBJECTS))

    ALGEBRA = $(LIB_DIR)/libalgebra.so
    TARGET = $(LIB_DIR)/libsimpletron.so

    .PHONY: directories

    all : directories $(ALGEBRA) $(TARGET)


    directories: $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR)

    $(OBJ_DIR):
    $(MKDIR_P) $(OBJ_DIR)

    $(BIN_DIR):
    $(MKDIR_P) $(BIN_DIR)

    $(LIB_DIR):
    $(MKDIR_P) $(LIB_DIR)

    $(ALGEBRA):
    $(MAKE) -C $(ALG_DIR)



    $(OBJ_DIR)/%.o: %.cpp $(HEADERS)
    $(CC) -c $(FLAGS) $(CPPFLAGS) -o $@ $<

    $(TARGET) : $(OBJECTS)
    $(CC) $(LDFLAGS) -o $@ $^


    .PHONY: clean
    clean:
    rm -f $(OBJ_DIR)/*.o


    make command builds library successfully (I think) :



    g++ -c -std=c++1z -fPIC -Wall -Wextra  -o obj/builder.o builder.cpp
    ...similar lines for each .cpp file...
    g++ -shared -o ../lib/libsimpletron.so obj/builder.o obj/gradient_trainer.o obj/layer.o obj/neuron.o obj/perceptron.o obj/simpletron.o obj/trainer.o


    Then I am trying to use this library. I compile my test xor as follows:



    #compiler
    CC = g++
    #cpp flags
    FLAGS = -std=c++1z
    PUGI = -l pugixml
    #directories
    LIB_DIR = /home/lrdprdx/Projects/SimplePerceptron/lib
    SIMPLETRON = -lsimpletron
    ALGEBRA = -lalgebra

    XOR = xor
    SOURCE = xor.cpp

    #config file
    CONFIG = config.xml


    $(XOR) : $(SOURCE) $(CONFIG)
    $(CC) $(FLAGS) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR) $(SOURCE)


    But when I try to compile this I get errors of undefined reference to .... OK, though I do not understand why those errors exist, I found that adding a .cpp file with an empty main function to the directory with other .cpp files fixes all the stuff:



    //empty.cpp
    int main()
    {
    return 0;
    }


    And after rebuild the shared library I make and execute xor successfully.
    The question is: what is going on here?










    share|improve this question

























      0












      0








      0








      I have makefile that builds shared library libsimpletron.so:



      #shell
      MKDIR_P = mkdir -p
      #compiler
      CC = g++
      #cpp flags
      FLAGS = -std=c++1z
      CPPFLAGS = -fPIC -Wall -Wextra
      LDFLAGS = -shared
      #directories
      INC_DIR = ../inc
      LIB_DIR = ../lib
      BIN_DIR = ../bin
      OBJ_DIR = ./obj
      ALG_DIR = ./algebra


      SOURCES = $(shell echo *.cpp)
      HEADERS = $(shell echo $(INC_DIR)/*.h)
      _OBJECTS = $(SOURCES:.cpp=.o)
      OBJECTS = $(patsubst %,$(OBJ_DIR)/%,$(_OBJECTS))

      ALGEBRA = $(LIB_DIR)/libalgebra.so
      TARGET = $(LIB_DIR)/libsimpletron.so

      .PHONY: directories

      all : directories $(ALGEBRA) $(TARGET)


      directories: $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR)

      $(OBJ_DIR):
      $(MKDIR_P) $(OBJ_DIR)

      $(BIN_DIR):
      $(MKDIR_P) $(BIN_DIR)

      $(LIB_DIR):
      $(MKDIR_P) $(LIB_DIR)

      $(ALGEBRA):
      $(MAKE) -C $(ALG_DIR)



      $(OBJ_DIR)/%.o: %.cpp $(HEADERS)
      $(CC) -c $(FLAGS) $(CPPFLAGS) -o $@ $<

      $(TARGET) : $(OBJECTS)
      $(CC) $(LDFLAGS) -o $@ $^


      .PHONY: clean
      clean:
      rm -f $(OBJ_DIR)/*.o


      make command builds library successfully (I think) :



      g++ -c -std=c++1z -fPIC -Wall -Wextra  -o obj/builder.o builder.cpp
      ...similar lines for each .cpp file...
      g++ -shared -o ../lib/libsimpletron.so obj/builder.o obj/gradient_trainer.o obj/layer.o obj/neuron.o obj/perceptron.o obj/simpletron.o obj/trainer.o


      Then I am trying to use this library. I compile my test xor as follows:



      #compiler
      CC = g++
      #cpp flags
      FLAGS = -std=c++1z
      PUGI = -l pugixml
      #directories
      LIB_DIR = /home/lrdprdx/Projects/SimplePerceptron/lib
      SIMPLETRON = -lsimpletron
      ALGEBRA = -lalgebra

      XOR = xor
      SOURCE = xor.cpp

      #config file
      CONFIG = config.xml


      $(XOR) : $(SOURCE) $(CONFIG)
      $(CC) $(FLAGS) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR) $(SOURCE)


      But when I try to compile this I get errors of undefined reference to .... OK, though I do not understand why those errors exist, I found that adding a .cpp file with an empty main function to the directory with other .cpp files fixes all the stuff:



      //empty.cpp
      int main()
      {
      return 0;
      }


      And after rebuild the shared library I make and execute xor successfully.
      The question is: what is going on here?










      share|improve this question














      I have makefile that builds shared library libsimpletron.so:



      #shell
      MKDIR_P = mkdir -p
      #compiler
      CC = g++
      #cpp flags
      FLAGS = -std=c++1z
      CPPFLAGS = -fPIC -Wall -Wextra
      LDFLAGS = -shared
      #directories
      INC_DIR = ../inc
      LIB_DIR = ../lib
      BIN_DIR = ../bin
      OBJ_DIR = ./obj
      ALG_DIR = ./algebra


      SOURCES = $(shell echo *.cpp)
      HEADERS = $(shell echo $(INC_DIR)/*.h)
      _OBJECTS = $(SOURCES:.cpp=.o)
      OBJECTS = $(patsubst %,$(OBJ_DIR)/%,$(_OBJECTS))

      ALGEBRA = $(LIB_DIR)/libalgebra.so
      TARGET = $(LIB_DIR)/libsimpletron.so

      .PHONY: directories

      all : directories $(ALGEBRA) $(TARGET)


      directories: $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR)

      $(OBJ_DIR):
      $(MKDIR_P) $(OBJ_DIR)

      $(BIN_DIR):
      $(MKDIR_P) $(BIN_DIR)

      $(LIB_DIR):
      $(MKDIR_P) $(LIB_DIR)

      $(ALGEBRA):
      $(MAKE) -C $(ALG_DIR)



      $(OBJ_DIR)/%.o: %.cpp $(HEADERS)
      $(CC) -c $(FLAGS) $(CPPFLAGS) -o $@ $<

      $(TARGET) : $(OBJECTS)
      $(CC) $(LDFLAGS) -o $@ $^


      .PHONY: clean
      clean:
      rm -f $(OBJ_DIR)/*.o


      make command builds library successfully (I think) :



      g++ -c -std=c++1z -fPIC -Wall -Wextra  -o obj/builder.o builder.cpp
      ...similar lines for each .cpp file...
      g++ -shared -o ../lib/libsimpletron.so obj/builder.o obj/gradient_trainer.o obj/layer.o obj/neuron.o obj/perceptron.o obj/simpletron.o obj/trainer.o


      Then I am trying to use this library. I compile my test xor as follows:



      #compiler
      CC = g++
      #cpp flags
      FLAGS = -std=c++1z
      PUGI = -l pugixml
      #directories
      LIB_DIR = /home/lrdprdx/Projects/SimplePerceptron/lib
      SIMPLETRON = -lsimpletron
      ALGEBRA = -lalgebra

      XOR = xor
      SOURCE = xor.cpp

      #config file
      CONFIG = config.xml


      $(XOR) : $(SOURCE) $(CONFIG)
      $(CC) $(FLAGS) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR) $(SOURCE)


      But when I try to compile this I get errors of undefined reference to .... OK, though I do not understand why those errors exist, I found that adding a .cpp file with an empty main function to the directory with other .cpp files fixes all the stuff:



      //empty.cpp
      int main()
      {
      return 0;
      }


      And after rebuild the shared library I make and execute xor successfully.
      The question is: what is going on here?







      makefile g++ undefined-reference






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 24 '18 at 10:41









      LRDPRDXLRDPRDX

      254312




      254312
























          1 Answer
          1






          active

          oldest

          votes


















          1














          I doubt that adding the extra file really fixed anything. Most likely some other side-effect helped.



          Your problem is that your link line is incorrect. GCC, like most UNIX linkers, is a single-pass linker. That means it only walks all the libraries one time looking for unresolved symbols. And that means that the order of the arguments to the linker is critically important: you have to ensure that if item A references symbols in item B, that A comes before B on the link line.



          In your example, you are putting all your libraries first, and your source files last. So, when make starts looking at your libraries it hasn't seen your sources yet, and there are no symbols it needs to link. By the time it compiles your sources, there are no libraries left to resolve symbols from.



          Your link line should be arranged with sources and object files first, then libraries (in referencer ... referencee order):



          $(CC) $(FLAGS) $(SOURCE) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR)





          share|improve this answer
























          • Yeah, I have already realized that.

            – LRDPRDX
            Nov 24 '18 at 16:15











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457309%2fwhy-does-undefined-reference-disappear-after-adding-a-cpp-file-with-empty-main%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          I doubt that adding the extra file really fixed anything. Most likely some other side-effect helped.



          Your problem is that your link line is incorrect. GCC, like most UNIX linkers, is a single-pass linker. That means it only walks all the libraries one time looking for unresolved symbols. And that means that the order of the arguments to the linker is critically important: you have to ensure that if item A references symbols in item B, that A comes before B on the link line.



          In your example, you are putting all your libraries first, and your source files last. So, when make starts looking at your libraries it hasn't seen your sources yet, and there are no symbols it needs to link. By the time it compiles your sources, there are no libraries left to resolve symbols from.



          Your link line should be arranged with sources and object files first, then libraries (in referencer ... referencee order):



          $(CC) $(FLAGS) $(SOURCE) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR)





          share|improve this answer
























          • Yeah, I have already realized that.

            – LRDPRDX
            Nov 24 '18 at 16:15
















          1














          I doubt that adding the extra file really fixed anything. Most likely some other side-effect helped.



          Your problem is that your link line is incorrect. GCC, like most UNIX linkers, is a single-pass linker. That means it only walks all the libraries one time looking for unresolved symbols. And that means that the order of the arguments to the linker is critically important: you have to ensure that if item A references symbols in item B, that A comes before B on the link line.



          In your example, you are putting all your libraries first, and your source files last. So, when make starts looking at your libraries it hasn't seen your sources yet, and there are no symbols it needs to link. By the time it compiles your sources, there are no libraries left to resolve symbols from.



          Your link line should be arranged with sources and object files first, then libraries (in referencer ... referencee order):



          $(CC) $(FLAGS) $(SOURCE) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR)





          share|improve this answer
























          • Yeah, I have already realized that.

            – LRDPRDX
            Nov 24 '18 at 16:15














          1












          1








          1







          I doubt that adding the extra file really fixed anything. Most likely some other side-effect helped.



          Your problem is that your link line is incorrect. GCC, like most UNIX linkers, is a single-pass linker. That means it only walks all the libraries one time looking for unresolved symbols. And that means that the order of the arguments to the linker is critically important: you have to ensure that if item A references symbols in item B, that A comes before B on the link line.



          In your example, you are putting all your libraries first, and your source files last. So, when make starts looking at your libraries it hasn't seen your sources yet, and there are no symbols it needs to link. By the time it compiles your sources, there are no libraries left to resolve symbols from.



          Your link line should be arranged with sources and object files first, then libraries (in referencer ... referencee order):



          $(CC) $(FLAGS) $(SOURCE) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR)





          share|improve this answer













          I doubt that adding the extra file really fixed anything. Most likely some other side-effect helped.



          Your problem is that your link line is incorrect. GCC, like most UNIX linkers, is a single-pass linker. That means it only walks all the libraries one time looking for unresolved symbols. And that means that the order of the arguments to the linker is critically important: you have to ensure that if item A references symbols in item B, that A comes before B on the link line.



          In your example, you are putting all your libraries first, and your source files last. So, when make starts looking at your libraries it hasn't seen your sources yet, and there are no symbols it needs to link. By the time it compiles your sources, there are no libraries left to resolve symbols from.



          Your link line should be arranged with sources and object files first, then libraries (in referencer ... referencee order):



          $(CC) $(FLAGS) $(SOURCE) -L$(LIB_DIR) $(SIMPLETRON) $(ALGEBRA) $(PUGI) -o $(XOR)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 24 '18 at 14:37









          MadScientistMadScientist

          47k55368




          47k55368













          • Yeah, I have already realized that.

            – LRDPRDX
            Nov 24 '18 at 16:15



















          • Yeah, I have already realized that.

            – LRDPRDX
            Nov 24 '18 at 16:15

















          Yeah, I have already realized that.

          – LRDPRDX
          Nov 24 '18 at 16:15





          Yeah, I have already realized that.

          – LRDPRDX
          Nov 24 '18 at 16:15




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457309%2fwhy-does-undefined-reference-disappear-after-adding-a-cpp-file-with-empty-main%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Create new schema in PostgreSQL using DBeaver

          Deepest pit of an array with Javascript: test on Codility

          Fotorealismo