Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined reference to `hmdf::HeteroVector::clear()' #56

Closed
Trento89 opened this issue Feb 29, 2020 · 18 comments
Closed

Undefined reference to `hmdf::HeteroVector::clear()' #56

Trento89 opened this issue Feb 29, 2020 · 18 comments

Comments

@Trento89
Copy link

When I tried to smoke test my code, I found that even trying to declare a dataframe resulted in an error at compile time. Am I missing a header file?

I'm running Debian 10 and am not using an IDE - I'm simply using g++ (I will create a Makefile once my code makes it past the smoke test). Below is the command I am using and the corresponding error.

username@system:/tmp/smoke_test$ g++ test_dataframe.cpp -I DataFrame/include/ -std=gnu++17 -o test_dataframe
/usr/bin/ld: /tmp/ccjU2Oy0.o: in function hmdf::HeteroVector::~HeteroVector()': test_dataframe.cpp:(.text._ZN4hmdf12HeteroVectorD2Ev[_ZN4hmdf12HeteroVectorD5Ev]+0x14): undefined reference to hmdf::HeteroVector::clear()'
collect2: error: ld returned 1 exit status

test_dataframe.cpp.txt

@hosseinmoein
Copy link
Owner

You are getting this error because you are not linking with the DataFrame library.
DataFrame is almost a header-only project. But there are some amount of code that has to be compiled into a library and then linked with.

If you follow the build instructions with cmake in the README section, it will build the DataFrame library and test executables. I would recommend that. After you build it, you can link with the library when building your example.
If you rather doing the whole thing in your own makefiles, take a look at my private make file in https://github.com/hosseinmoein/DataFrame/tree/master/src to get some guidelines.

@Trento89
Copy link
Author

Trento89 commented Mar 1, 2020

Thank you for your reply. I followed the instructions for installing the library using cmake, and it now appears that I was successful in installing the library. However, I'm still getting the undefined reference errors when I try to compile the .cpp file using g++. For the purpose of just getting this very trivial program to compile and successfully instantiate the StdDataFrame (and thus passing the smoke test), is there a specific change that I should be making to the libraries that I am #including or to the arguments I'm passing to g++ in the Bash terminal?

@hosseinmoein
Copy link
Owner

hosseinmoein commented Mar 1, 2020

There is nothing wrong with your #include. You are not failing at compiling your program. You are failing at linking your program. That means you are failing to link to DataFrame library to resolve all the external symbols.
Now that you have successfully made the DataFrame you have to link with its library on your compiling command line. So change your command line to something like

g++ test_dataframe.cpp -I DataFrame/include/ -std=gnu++17 -Bstatic  -L<Path to where DataFrame Library is> -lDataFrame -lpthread -ldl -lm -lstdc++ -o test_dataframe

That is a typical command line to compile and link any C++ program using a library, whether it is a very simple program or very complicated.

Hope that helps

@Trento89
Copy link
Author

Trento89 commented Mar 1, 2020

It works! Thank you!

@Trento89
Copy link
Author

Trento89 commented Mar 8, 2020

I'm sorry to bother you with this again, but I'm getting error messages again when I try to compile from multiple source files (and use header files) and then link the objects together into an executable. Is the problem the Makefile, the .cpp files, or the header file? And shouldn't the #pragma once directive prevent the read_data.h file, as well as the library headers, from being read multiple times which is what leads to multiple reference errors?

I've tried making multiple changes to the #include directives in the .cpp files and the header files and nothing seems to have worked. What am I missing here?

main.cpp.txt
Makefile.txt
read_data.cpp.txt
read_data.h.txt
sample_data.csv.txt
shell_screenshot

@hosseinmoein
Copy link
Owner

I can see a few problems, but you may have more.

  1. You have defined DataFrame_t multiple times
  2. In your makefile, when compiling source code into object file you are also linking with DataFrame library. That might be the cause of your multiple definitions
  3. Your DataFrame library location seems to be incorrect
  4. You have not built and link with the boost library?

It is hard to debug remotely.
Instead of I pointing out mistakes in a few lines, I suggest you read up on compilers and makefiles and understand the stages a compiler goes through to get a text source file to a binary executable. This way, you will have a much broader view of what is going on.

@Trento89
Copy link
Author

Trento89 commented Mar 9, 2020

I accidentally posted a later iteration of what I was working with after a series of trial-and-error attempts, and I apologize for loading the wrong file there. I corrected the problems you mentioned, but I'm still getting errors and I'm not sure why this keeps happening.

I understand that the C/C++ compiling process consists of: preprocessing, where the compiler follows preprocessing directives such as expanding macros and including libraries and header files; compiling the C/C++ files (while following preprocessing directives) into assembly language code; assembling the assembly language code into binary object files; and linking the binary object files into a binary executable that contains direct instructions that the computer can then execute. The Makefile contains a series of instructions to the compiler so that for a large program whose source code is spread across (for example) 20 files, the programmer does not have to manually type 20 different instructions into the shell to create the object files before linking them together into the binary executable.

So far the only way that I have stopped getting errors has been to #include read_data.cpp from the main.cpp file, but I know that this is a sloppy kludge and considered very bad style; I also know that such a "solution" will break as soon as I add more .cpp files.

What I'm having trouble understanding now, after having applied the changes, is why I'm getting a multiple definition error for hmdf::gen_bernoulli_dist() when 1) the #include directive to use the library file containing it exists only in the read_data.h file and nowhere else and 2) the header file read_data.h has a #pragma once directive. I'm also not sure why there is an undefined reference error for hmdf::HeteroVector::HeteroVector() when the header file has an explicit #include <DataFrame/Vectors/HeteroVector.h> directive on Line 16.

What did I enter incorrectly for the DataFrame library location? I thought the Makefile was pointing to the location where it's installed.

Any help you could provide here would be much appreciated. Not being able to compile the code due to these errors seems to be the main bottleneck in my project.

main.cpp.txt
Makefile.txt
read_data.cpp.txt
read_data.h.txt
sample_data.csv.txt
shell_screenshot

@hosseinmoein
Copy link
Owner

hosseinmoein commented Mar 9, 2020

Your understanding of the compile process is incorrect. Also, your understanding of what role header files play is incorrect. I still suggest you put some time aside to read up on them.

I still see problems:

  1. The location of DataFrame library is specified as /usr/local/include/DataFrame/. I highly doubt that is where the library is. And if it is there somehow, it shouldn't be.
  2. You are still specifying and linking with the library when compiling object files.

This is a typical line for compiling an object file

/usr/bin/g++ -g -I. -I../../include -DP_THREADS -D_POSIX_PTHREAD_SEMANTICS -std=c++17 -c ../test/dataframe_tester.cc -o ../obj/Linux.GCC64D/dataframe_tester.o

And this is a typical line to link an executable

/usr/bin/g++ -o ../bin/Linux.GCC64D/dataframe_tester ../obj/Linux.GCC64D/dataframe_tester.o  -Bstatic -L../lib/Linux.GCC64D -lDataFrame -lpthread -ldl -lm -lstdc++

@Trento89
Copy link
Author

Trento89 commented Mar 9, 2020

Thank you. I will try to implement your suggestions.

If I followed your installation instructions correctly, where should the library be located on a Linux machine?

@hosseinmoein
Copy link
Owner

CMake decides dynamically. But I imagine in your system it would somewhere under /usr/local/lib probably under DataFrame. Also look at /usr/lib.

@Trento89
Copy link
Author

Trento89 commented Mar 9, 2020

I based the path on the output of the installation process. I followed your installation instructions to the letter (or at least I think I did) and the locations are shown below.

screenshot

@Trento89
Copy link
Author

Trento89 commented Mar 9, 2020

Your understanding of the compile process is incorrect. Also, your understanding of what role header files play is incorrect. I still suggest you put some time aside to read up on them.

I still see problems:

1. The location of DataFrame library is specified as `/usr/local/include/DataFrame/`. I highly doubt that is where the library is. And if it is there somehow, it shouldn't be.

2. You are still specifying and linking with the library when compiling object files.

This is a typical line for compiling an object file

/usr/bin/g++ -g -I. -I../../include -DP_THREADS -D_POSIX_PTHREAD_SEMANTICS -std=c++17 -c ../test/dataframe_tester.cc -o ../obj/Linux.GCC64D/dataframe_tester.o

And this is a typical line to link an executable

/usr/bin/g++ -o ../bin/Linux.GCC64D/dataframe_tester ../obj/Linux.GCC64D/dataframe_tester.o  -Bstatic -L../lib/Linux.GCC64D -lDataFrame -lpthread -ldl -lm -lstdc++

Just to clarify, is the issue now solely the Makefile, or are there still problems with the .cpp files and the read_data.h header file?

@hosseinmoein
Copy link
Owner

From my cursory look, there is nothing wrong in the source code

@Trento89
Copy link
Author

Trento89 commented Mar 9, 2020

Thank you. This clarification will save me a lot of time!

@yegorrr
Copy link

yegorrr commented Jul 26, 2022

i'm compiling under MSVC 2022 with DataFrame.lib (i got it via vcpkg) but it gives me "Undefined reference to `hmdf::HeteroVector::clear()" error

@hosseinmoein
Copy link
Owner

Most probably because when you are linking your executable, you are not linking with the DataFrame library

@yegorrr
Copy link

yegorrr commented Jul 26, 2022

other than DataFrame.lib?

@yegorrr
Copy link

yegorrr commented Jul 26, 2022

other than DataFrame.lib?

there must be something wrong with vcpkg, i built everything from github repo and now it works fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants