C++ Compiles in Windows, multiple definition error in Linux - c++

let me start by saying that I am not the best C++ and I know very little in ways of Linux. For a class project we had to implement a heap so I coded everything on my Windows PC assuming I could just upload the files to the Linux repository the school has. [Perhaps this is where I went wrong and this cannot be done this simply.] My codes compiles and clears all test cases provided on my Windows pc. When I upload the files to Linux, I created a makefile and when I use the make command I get back a laundry list of multiple definition errors. One error per function that I am using. I have done some searching and I am more confused then when I started.
My files are: main.cpp, main.h, heap.cpp, heap.h, util.cpp, and util.h.
I think the issue is with my include statements but I am not 100% sure.
Here is an example of the files.
main.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "util.cpp"
#include "heap.cpp"
#include <fstream>
using namespace std;
main.h is blank.
heap.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"
#include <cmath>
#include <math.h>
using namespace std;
//expanded functions found in the heap.h file
heap.h
//2 structs
//9 functions
util.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
using namespace std;
//expanded functions found in util.h
util.h
//1 function
Between heap.h and util.h I have 10 function and upon running the make command I get a warning about all ten:
multiple definition of 'FUNCTIONNAME'
main.o:main.cpp:(.text+0x1b7): first defined here
I am assuming the 0x1b7 is a memory location because they are each different.
Any help would be greatly appreciated.

You haven't shown the Makefile, but most likely, it includes this or a similar rule
program: main.o heap.o util.o
$(CXX) $(CXXFLAGS) -o program main.o heap.o util.o
What happens now, the compiler builds the three object files main.o, heap.o and util.o. Next the object files are linked together to build program.
The linker sees definitions of the various functions defined in both main.o and heap.o, or main.o and util.o respectively. This is why it complains about "multiple definition of 'FUNCTIONNAME'"
Why are these functions defined more than once?
When you include a file into another source, it is as if you copy the contents at the location of the #include. This means a function defined in heap.cpp:
void create_heap(int size)
{
// create a heap ...
}
is copied verbatim into main.cpp where the line
#include "heap.cpp"
is.
Because heap.cpp has the definition of create_heap() and main.cpp #includes the contents of heap.cpp, both contain their own copy of create_heap(). Now you compile both heap.o and main.o, and link them together. Each object file has a copy of create_heap() and this is where the linker is confused and complains
multiple definition of 'create_heap'
main.o:main.cpp:(.text+0x1b7): first defined here
To fix this, simply replace the lines including the cpp sources, e.g.
#include "util.cpp"
#include "heap.cpp"
with their respective header files
#include "util.h"
#include "heap.h"
Only keep the function definitions relevant to main.cpp, nothing else. Now main.cpp has no function definitions belonging to util.cpp or heap.cpp, and the linker errors are gone.
Presumably, this worked on Windows, because only main.cpp was included in the project file, and so only one definition (from main.o) was in the resulting executable.
If you had included all sources as in the Linux Makefile, the error could be seen in Windows as well.

Related

What is the correct way to compile multiple test sources with Catch2?

I have the following project structure:
test_main.cc
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
test1.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
test_utils.hpp
#pragma once
#include <iostream>
void something_great() {
std::cout << ":)\n";
}
If I compile using something like clang++ -std=c++17 test_main.cc test1.cc test2.cc, the function something_great is defined in both test1.o and test2.o. This leads to an error like
duplicate symbol __Z15something_greatv in:
test1.cc.o
test2.cc.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
In the Scaling Up section of the Catch2 documentation, they mention that in order to split up your tests you may want to
Use as many additional cpp files (or whatever you call your
implementation files) as you need for your tests, partitioned however
makes most sense for your way of working. Each additional file need
only #include "catch.hpp"
but in the examples section of the documentation I don't see a use case like mine. I read this blog post which describes three solutions which don't appeal to me: defining functions as macros, or making functions static or inline.
Is there another way to compile these files which yield a single executable with the main function defined by test_main.cc?
This actually has nothing to do with Catch or testing. When you #include a file in C++, it gets copy-pasted at the #include line verbatim. If you put free function definitions in headers, you would see this problem building your actual program, etc.
The underlying problem is that #include is not the same kind of import-a-module directive as is the equivalent directive (import, require, etc.) in most languages, which do the sane thing in a situation like this (confirm that the header is the same one we've already seen and ignore the repeated method definition).
The commenter that suggested you write inline is technically correct, in the sense that this will "solve your problem" because your compiler won't generate object code for the method multiple times. However, it doesn't really explain what's going on or address the underlying issue.
The clean solution is:
In test_utils.hpp, replace the method definition with a method declaration: void something_great();.
Create test_utils.cc with the definition of the method (which you currently have in the .hpp).
clang++ -std=c++17 test1.cc -c
clang++ -std=c++17 test2.cc -c
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_utils.cc -c
clang++ -std=c++17 test1.o test2.o test_utils.o test_main.o
I also recommend you read this: What is the difference between a definition and a declaration?
Explicitly:
// test_utils.hpp
#pragma once
// This tells the compiler that when the final executable is linked,
// there will be a method named something_great which takes no arguments
// and returns void defined; the definition lives in test_utils.o in our
// case, although in practice the definition could live in any .o file
// in the final linking clang++ call.
void something_great();
And:
// test_utils.cpp
#include "test_utils.hpp"
#include <iostream>
// Generates a DEFINITION for something_great, which
// will get put in test_utils.o.
void something_great() { std::cout << "Hi\n"; }
It seems you are worried about "recompiling Catch" every time you make a change to a test. I hate to break it to you, but you are in C++ land now: you are going to be recompiling stuff pointlessly a lot. Header-only libraries like Catch MUST be "recompiled" to some extent when a source file including them changes, because for better or worse, if the source file or a header file included transitively from the source file includes catch2.hpp, then the source code of catch2.hpp will get parsed by the compiler when that source file is read.
After some experimentation, I found a reasonable solution which doesn't require you to fully recompile Catch any time you make a change to a test.
Define test_main.cc in the same way as before:
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
Add another .cc file, test_root which includes your test files as headers:
#include "test1.hpp"
#include "test2.hpp"
Change your test sources to headers:
test1.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
Compile separately
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_root.cc -c
clang++ test_main.o test_root.o
Where test_main.cc needs only be compiled once. test_root.cc will need to be recompiled whenever you change your tests and of course you must relink the two object files.
I will leave this answer unaccepted for now in case there are better solutions.

C++ Shared library: Creation and usage

I am trying to build a shared object to later use a function DoSomethingUseful() from the shared object in other projects.
It uses external libraries as well as a bunch of headers that I am using across multiple projects.
Using CMake, I created a project MySharedLib with a header file called
library.h:
#ifndef MYSHAREDLIB_LIBRARY_H
#define MYSHAREDLIB_LIBRARY_H
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cstdio>
// own header files
#include <header1.h>
#include <header2.h>
#define PI 3.14159265
//tesseract
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
//openCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
//face detection
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
void DoSomethingUseul(int[] inparray);
#endif
With library.cpp as
#include "library.h"
void DoSomethingUseful(int[] inparray){...}
My CMake file is as such:
cmake_minimum_required(VERSION 3.10)
project(MYSHAREDLIB)
find_package( OpenCV REQUIRED )
set(CMAKE_CXX_STANDARD 11)
set(MY_INCLUDE_DIR ../source/)
set(MY_OPENCV_CASCADES /opencvpath/openCV34/opencv/sources/data/haarcascades/)
include_directories(${MY_INCLUDE_DIR} ${MY_OPENCV_CASCADES} /usr/include)
link_directories(${MY_INCLUDE_DIR})
add_library(MYSHAREDLIB SHARED library.cpp library.h
${MY_INCLUDE_DIR}header1.cpp
${MY_INCLUDE_DIR}header1.h
${MY_INCLUDE_DIR}header2.cpp
${MY_INCLUDE_DIR}header2.h
)
set_target_properties(MYSHAREDLIB PROPERTIES VERSION 3.10)
set_target_properties(MYSHAREDLIB PROPERTIES SOVERSION 1)
target_link_libraries(MYSHAREDLIB lept tesseract ${OpenCV_LIBS})
The *.so file is created sucessfully, i. e. using Clion, no errors are thrown and the file libMySharedLib.so is there.
However, when I want to use the function DoSomethingUseful() in another file DoSomething.cpp:
#include <iostream>
#include "library.h"
using namespace std;
int main()
{
int[2] myarray; myarray[0]=1; myarray[1] =2;
DoSomethingUseful(myarray);
return 0;
}
And
g++ -g -Wall -o DoSomething DoSomething.cpp -I ../source/ -L. libMYSHAREDLIB.so
When I execute
./DoSomething
I get:
./DoSomething: error while loading shared libraries: libMYSHAREDLIB.so: cannot open shared object file: No such file or directory
Before, I compiled without -I ../source/ yielding:
In file included from DoSomething.cpp:8:0:
library.h:19:10: fatal error: header1.h: No such file or directory
#include <header1.h>
I find many threads dealing with this issue in general, and I gathered already a lot of knowledge about shared objects from those issues, also suceeding in getting examples from various tutorials running.
However, I do not suceed with my own project.
This is just one of many questions, but I hope I can get help here and maybe also general hints. Thank you a lot for any help.
Assuming Linux (amend question if wrong). When running an executable, shared libraries are loaded from paths listed in /etc/ld.so.conf only. If you want to load from somewhere else (.) , you have to set the LD_LIBRARY_PATH environment variable, e.g. LD_LIBRARY_PATH=. ./DoSomething

g++ "does not name a type" error

I'm working on a little project for my structures class and have run into an issue even the TA couldn't figure out. It was suggested that I post about it on here and I might get some help. So here it goes:
Overview:
I'm using g++ to compile a project containing a number of header (.h) files along with their corresponding implementation (.cpp) files. The project involves 3 separate structures and running a timing comparison between them. The structures being implemented and compared are a binary min heap, a leftist heap, and a skew heap. The min heap implementation is complete and is compiling just fine. However now that I'm moving onto the other structures I'm running into what I assume (I know) is a compiler error.
The Issue
I'm fleshing out the stub files for the leftist heap and have hit a brick wall as far as the compiler is concerned. In particular I'm getting an error that reads:
leftHeap.cpp:15:1: error: ‘LeftistHeap’ does not name a type
The Code
Here's a look at relevant code:
leftHeap.h
#ifdef LEFTHEAP_H
#define LEFTHEAP_H
class LeftistHeap{
public:
int *root;
LeftistHeap();
~LeftistHeap();
};
#endif
leftHeap.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include <math.h>
#include "leftHeap.h"
using namespace std;
//Constuctor
LeftistHeap::LeftistHeap(){
root = NULL;
}
The only other place that leftHeap.h is included is in the main.cpp
main.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include <math.h>
#include "minHeap.h"
#include "leftHeap.h"
#include "skewHeap.h"
using namespace std;
int main(){
...
here's the makefile I'm using:
makefile
all: lab10
lab10: comparison.o minHeap.o leftHeap.o skewHeap.o
g++ comparison.o minHeap.o leftHeap.o skewHeap.o -o lab10
comparison.o: comparison.cpp
g++ -c comparison.cpp
minHeap.o: minHeap.h minHeap.cpp
g++ -c minHeap.h minHeap.cpp
leftHeap.o: leftHeap.h leftHeap.cpp
g++ -c leftHeap.h leftHeap.cpp
skewHeap.o: skewHeap.h skewHeap.cpp
g++ -c skewHeap.h skewHeap.cpp
clean:
rm lab10 *.o
and just to be extra thorough I've also tried a more minimalist makefile
makefile (2)
test:
g++ minHeap.h leftHeap.h skewHeap.h comparison.cpp minHeap.cpp leftHeap.cpp skewHeap.cpp -o lab10
clean:
rm lab10 *.o
I hope that's not info overload. Please let me know if anyone has any ideas on this. I've looked at the other g++ "does not name a type" issues on here (and a couple of full page of google searches as well) but haven't found anything that may account for this. I have this sneaking suspicion that it may be something simple I've overlooked but any help would be greatly appreciated.
Thanks!
Look at your include guard really carefully: #ifdef LEFTHEAP_H.
This is just a typo (assuming it is transcribed accurately):
#ifdef LEFTHEAP_H
#define LEFTHEAP_H
in leftHeap.h should be #ifndef
#ifndef LEFTHEAP_H
#define LEFTHEAP_H

Confusion between including header files and source files in main program

I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx

Compiling Multiple C++ OpenGL

I'm writing a simple C++, opengl program and I'm having difficulty producing the executable from the object files. I can create object files of each .cpp without error using:
g++ -c filename.cpp ----> filename.o
Each .cpp creates an object, which leads me to assume that it is finding the opengl headers fine, but when I attempt to create the executable from the objects, it outputs:
g++ -o OUTPUT Main.o Time.o Map.o Vehicle.o
Main.o: In function `init()':
Main.cpp:(.text+0x12a): undefined reference to `glEnable'
Main.cpp:(.text+0x134): undefined reference to `glShadeModel'
Main.cpp:(.text+0x14d): undefined reference to `glViewport'
Main.cpp:(.text+0x157): undefined reference to `glMatrixMode'
Main.cpp:(.text+0x15c): undefined reference to `glLoadIdentity'
I realize that the g++ is telling me that it can't find the OpenGL functions anywhere, which means it is not linking to glu.h, gl.h etc. But why do the objects files get created without similar error, but I can't make my executable? Wouldn't the object files suffer from the same linking error as the .exe? I've tried -I and g++ -o RUN Time.o Main.o Map.o Vehicle.o -L/usr/include/GL/ -lGL -lGLU, and I've also verified the path of the OpenGL directory.
The headers of each files are below:
libgl.h:
#ifndef LIBGL_H
#define LIBGL_H
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include "Time.h"
#include "Link.h"
#endif
Time.h:
#ifndef TIME_H
#define TIME_H
extern float GLOBAL_TIME;
#endif
Map.h
#ifndef MAP_H
#define MAP_H
#include "libgl.h"
....
#endif
Vehicle.h:
#ifndef VEHICLE_H
#define VEHICLE_H
#include "libgl.h"
...
#endif
Main.cpp:
#include "libgl.h"
#include "Map.h"
#include "Vehicle.h"
...
There is something that I'm missing regarding my headers/linking and compiling, if anybody has any suggestions I would be much obliged.
You need to link with the OpenGL libraries: probably pass -lgl to the last g++ invocation.
If your system has pkg-config you can use pkg-config --cflags --libs gl to get all the right flags.
For future reference, an "undefined reference" is a linker error, and it always means the same thing: you missed an object file or a library. It only shows up when linking, never when simply compiling (i.e. using -c)