0

All i found in Stackoverflow, nothing help in my case, maybe there is something that my eyes can't see? undefined reference to symbol occurs, when i include these headers #include <boost/log/expressions.hpp> #include <boost/log/utility/setup/file.hpp>

$ echo $LD_LIBRARY_PATH

/usr/lib/x86_64-linux-gnu/

PROGNAME := "program"
SOURCESWITHMAIN := $(wildcard src/*.cpp)
HEADERS := $(wildcard src/*.hpp)
HEADERS := $(patsubst src/%.hpp, inc/%.hpp, $(HEADERS))
SOURCES := $(patsubst main.cpp, , $(SOURCESWITHMAIN))
OBJECTS := $(patsubst src/%.cpp, obj/%.o, $(SOURCES))
DEPENDS := $(patsubst src/%.cpp, obj/%.dep, $(SOURCESWITHMAIN))

bin/PROGNAME: ./bin lib/libStat.a src/main.cpp $(HEADERS)
    @g++ -std=c++11 src/main.cpp -DBOOST_ALL_DYN_LINK -pthread -lboost_log -lboost_thread -lboost_system -lboost_log_setup -L lib -l Stat -o bin/$(PROGNAME) -I /inc -I /usr/include/boost/log/utility/setup
    @echo "Succesfully..."
inc/%.hpp: src/%.hpp ./inc
    @ln -f $< $@
./inc:
    @echo "inc folder created..."
    @mkdir -p inc
./bin:
    @mkdir -p bin
    @echo "bin folder created..."
lib/libStat.a: ./lib $(OBJECTS)
    @ar rc lib/libStat.a $(OBJECTS)
    @echo "static lib created..."
./lib:
    @mkdir -p lib
    @echo "lib folder created..."
obj/%.o: src/%.cpp
    @mkdir -p obj
    @g++ -std=c++11 -DBOOST_ALL_DYN_LINK -pthread -lboost_log -lboost_thread -lboost_system -lboost_log_setup -lboost_filesystem -c $< -o $@

obj/%.dep: src/%.cpp
    @mkdir -p obj
    @g++ -MM $< -MT "$@ $(patsubst %.dep, %.o, $@)" -o $@
-include $(DEPENDS)

.PHONY: clean
clean:
    @rm -rf bin/ lib/ obj/ inc/
    @echo "Cleaning..."

.PHONY: push
push:
    @git add .
    @git commit -m"some changes"
    @git push origin master

.PHONY: help
help:
    @echo "type make for compiling"
    @echo "type make clean for cleaning"
    @echo "type make push for fast pushing to repo"
  • You are not linking the library or object file that defines the symbol. – Jesper Juhl May 04 '20 at 20:53
  • @JesperJuhl, what do you mean saying defines the symbol ? –  May 04 '20 at 21:00
  • 1
    @leon a header file you `#include` just contains (usually) *declarations*. That tells the compiler that certain things *exist* but nothing more. To be able to both compile *and link* your program you need to also provide files that actually implement (aka define) the things your declarations promised the compiler would eventually exist. Just including a header is not enough to build a program. It's enough for the compiler, but not for the linker - it needs the actual object or library file. – Jesper Juhl May 04 '20 at 21:05
  • @JesperJuhl, i am not just included header files, i wrote a function that creates a file, if it doesn't exists, then logs write in that file, with this format `[%TimeStamp%]` `[%ThreadID%]` `[%Severity%]` `[%ProcessID%]` `[%LineID%]` `%Message%` –  May 04 '20 at 21:14

1 Answers1

0

Oh my. You have many problems here. As Jesper said, linker issues are normally not related to #include files.

First, you should never add libraries to your compile lines: that is, lines that create object files (lines that use the -c compiler option). So this rule:

obj/%.o: src/%.cpp
        @mkdir -p obj
        @g++ -std=c++11 -DBOOST_ALL_DYN_LINK -pthread -lboost_log -lboost_thread -lboost_system -lboost_log_setup -lboost_filesystem -c $< -o $@

is wrong: you should not have any library options here (-l or -L). It should just be:

obj/%.o: src/%.cpp
        @mkdir -p obj
        @g++ -std=c++11 -DBOOST_ALL_DYN_LINK -c $< -o $@

However, all of this is irrelevant because none of this makefile is actually used except for one rule: the one that creates the program. You've created a bunch of variables that are never used, and a bunch of pattern rules which are ever used.

Next, you should never use quotes inside a makefile variable unless that variable contains an entire shell script that requires quotes. Make itself doesn't care about quotes, it just treats them the same as any other character. So, you should use:

PROGNAME := program

Next you should use the variable in the target, else it has no purpose:

bin/$(PROGNAME): ./bin lib/libStat.a src/main.cpp $(HEADERS)

And in your recipe you should use $@ to refer to the target.

Next, the order in which libraries are listed on the link line is critically important, and it must be more general libraries first, and libraries they depend on afterwards. So for example, your library Stat should come first, followed by Boost libraries, and finally at the end system libraries:

@g++ -std=c++11 src/main.cpp -DBOOST_ALL_DYN_LINK -pthread -L lib -l Stat -lboost_log -lboost_log_setup -lboost_thread -lboost_system -o bin/$(PROGNAME) -I /inc -I /usr/include/boost/log/utility/setup

Note that your -I option is wrong; you wrote -I /inc but you want (I assume) -I ./inc.

I have no idea why you're linking files from the source directory to the include directory. Maybe if you fix your -I option, you won't need to do this anymore.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • yeah, it works, can you share some useful links how correctly and professionally write Makefile, or maybe some of yours, that you wrote, i must carefully read, what you wrote to understand all of the details, that in future can help me)) –  May 04 '20 at 21:23
  • I don't really follow online tutorials, etc. I haven't seen any that I think are really good. I typically just use the GNU make manual to answer questions: https://www.gnu.org/software/make/manual/html_node/index.html There are some decent books out there if you're interested in that. Basically you should (a) use make variables as much as reasonable, (b) use make facilities like functions, pattern rules, etc. to avoid duplicating content. – MadScientist May 05 '20 at 13:21
  • thank you very much, i will read that, do you have a github account? –  May 05 '20 at 22:16
  • Yes, but there's not much on it because I do most of my hacking for GNU and the FSF. – MadScientist May 05 '20 at 23:47