I'm trying to test a library that I've done (Calculus), in QTCreator for Windows.
I've created a main file, and a class in a separate file for the testing. If I compile the example found in http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-test-suite.html it works, and so the example found in http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-nullary-test-case.html also works.
But when I try to compile my project I've a lot (over 500) errors of multiple definitions. Below you can find my files. As you can see I've also tried to put some guard around boost headers, but it does not work. What am I doing wrong?
main.cpp
#include "testcalculus.h"
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
using namespace boost::unit_test;
test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
WRayTesting::TestCalculus xTestCalculus;
test_suite* pxTestSuiteCalculus = BOOST_TEST_SUITE("Test Calculus");
pxTestSuiteCalculus->add(BOOST_TEST_CASE( boost::bind(&WRayTesting::TestCalculus::testCartesianPoint2D, &xTestCalculus)));
framework::master_test_suite().add(pxTestSuiteCalculus);
return 0;
}
testcalculus.h
#ifndef TESTCALCULUS_H
#define TESTCALCULUS_H
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
#include "cartesianpoint2d.h"
#include "cartesianvector2d.h"
namespace WRayTesting
{
/** Class for testing the Calculus project */
class TestCalculus
{
public:
//! Constructor
TestCalculus();
//! Testing class point
void testCartesianPoint2D();
private:
};
} // namespace WRayTesting
#endif // TESTCALCULUS_H
testcalculus.cpp
#include "testcalculus.h"
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
namespace WRayTesting
{
using ::Calculus::CartesianPoint2D;
using namespace boost::unit_test;
/**
* Constructor
*/
TestCalculus::TestCalculus()
{
}
/**
* Test the CartesianPoint2D class.
*/
void TestCalculus::testCartesianPoint2D()
{
// Default constructor
CartesianPoint2D xTestingPoint;
BOOST_CHECK(0.0 == xTestingPoint.getX());
BOOST_CHECK(0.0 == xTestingPoint.getY());
}
} // namespace WRayTesting
Compile output
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:62: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_start(std::ostream&, unsigned long)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:62: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:72: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_finish(std::ostream&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:72: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:80: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_build_info(std::ostream&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:80: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:93: multiple definition of `boost::unit_test::output::compiler_log_formatter::test_unit_start(std::ostream&, boost::unit_test::test_unit const&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:93: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:103: multiple definition of `boost::unit_test::output::compiler_log_formatter::test_unit_finish(std::ostream&, boost::unit_test::test_unit const&, unsigned long)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:103: first defined here
...........
You cannot include #include in multiple files within the same test module. You either need to switch to library or put everything inside single file
Related
I am reading a book (C++ for dummies) as well as watching youtube videos to learn how to code. I am currently struggling with very simple class functions.
Main.cpp
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include "Test.h"
using namespace std;
int x;
int main(int nNumberofArgs, char* pszArgs[])
{
combat fight;
cout << x;
fight.dodmg();
cout << x;
return 0;
}
Test.h my header file with the class
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
int dodmg();
void zero_out();
private:
int x;
};
#endif // TEST_H_INCLUDED
Test.cpp class functions
#include "Test.h"
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20
}
I tried to make this very simplistic just to figure out how to work a class.
I included a lot of #includes just to try and make sure it wasn't something stupid like I needed strings.
I am not sure why but the videos I watched simply had the header say
ifndef TEST_H (of their respective code, mine has an _INCLUDE as well, I tried deleting it and it still didn't work.
My unfortunate errors
on line 14 of main.cpp fight.dodmg(); it says
\Beginning_Programming-CPP\Playing_with_class\main.cpp|14|undefined reference to `combat::dodmg()'|
then below that
||error: ld returned 1 exit status|
How are you compiling this? I think this is an issue because you arent compiling your Test.cpp file. If you arent already, try compiling with the command:
g++ main.cpp Test.cpp -o MyProgram
UPDATE:
Few things, you dont have a closing statement to your #ifndef directive in Text.h, you will need a constructor to set the value of x so i added one to the combat class also you were missing a semicolon in the zero_out function. I added comments to all the lines I changed.
Okay try this:
Test.h
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
combat(); // added constructor
int dodmg();
void zero_out();
private:
int x;
};
#endif // closed #ifndef
Text.cpp
#include "Test.h"
combat::combat() // implemented constructor
{
x = 20;
}
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20; // added ';'
}
Hope this helps,
Final edit: I dont think you really need your header guards in this scenario, you could remove the "#ifndef, #define, and the #endif" lines and not see a difference really
It sounds like you provide the wrong arguments for the compiler. Your header file (Test.h) simply provides signatures for the methods, but the implementations are given in the source file (Test.cpp).
This is an important part of writing C++ (or C) code. Your compiler does not automatically search for source files, so you need to tell it where to look, e.g.:
g++ -std=c++11 main.cpp Test.cpp -o main
I'm having an error I don't know how to fix in my large Operating Systems homework. The error I'm getting is "42 duplicate symbols for architecture x86_64". I presume this is to do with my global variables file "global.h". I have 3 global variables I use and "global.h" is included in an abstract class called "PageReplacementAlgorithm.cpp". I have around 6 classes that are derived from the PageReplacementAlgorithm class and they utilize these global variables. I think the problem comes in when I include all these derived classes in my "main.cpp" as I need to make new instances of them. How can I fix the implementation of the global variables?
Global.h
#include "PageTableEntry.h"
using namespace std;
#ifndef Global_H
#define Global_H
extern PageTableEntry pageTable[64];
extern int* frameTable;
extern int framesCount;
#endif
PageReplacementAlgorithm.h
#include "Global.h"
using namespace std;
#ifndef PageReplacementAlgorithm_H
#define PageReplacementAlgorithm_H
class PageReplacementAlgorithm {
public:
virtual int selectFrame(PageTableEntry &p) = 0;
};
#endif
Example Derived Class (FIFO)
include "PageReplacementAlgorithm.h"
using namespace std;
#ifndef FIFO_H
#define FIFO_H
class FIFO : public PageReplacementAlgorithm {
public:
FIFO();
int selectFrame(PageTableEntry &p);
private:
int entries;
};
#endif
Main.cpp
#include "Aging.cpp"
#include "Clock.cpp"
#include "FIFO.cpp"
#include "MMU.cpp"
#include "NRU.cpp"
#include "Random.cpp"
#include "SecondChance.cpp"
Why do you include all cpp files in main.cpp? I think they contain same includes, right? Even you have the guards there, you do additional includes before that guards and that is probably the source of problems. The main.cpp could contain just main() function and import headers of your classes, there is no need to include cpp.
Also, you can modify your header files to look like this (for sake of extreme safety):
#ifndef PageReplacementAlgorithm_H
#define PageReplacementAlgorithm_H
#include "Global.h"
using namespace std;
...
#endif
I recommend you to look at answer C++ #include guards
If you get rid of #include "(anything).cpp, things should work much better. When you build the project, or run the compiler e.g. g++ main.cpp foo.cpp, that's when those .cpp files get built and linked into your program.
I am writing a plugin for Autodesk Maya using C++ and have a linker error.
My main class is Maya_Search_Plugin.cpp
#include <Utilities.h>
DeclareSimpleCommand( search_face, PLUGIN_COMPANY, "4.5");
//doIt method is entry point for plugin
MStatus search_face::doIt( const MArgList& )
{
//calls to Maya types/functions and Utilities functions
}
Then I have a Utilities class containing some static methods with header looking like this
#ifndef __Maya_CPP_Plugin__Utilities__
#define __Maya_CPP_Plugin__Utilities__
//#pragma once
//standard libs
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include <math.h>
//maya libs
#include <maya/MDagPath.h>
#include <maya/MFn.h>
#include <maya/MFileIO.h>
#include <maya/MIOStream.h>
#include <maya/MFnMesh.h>
#include <maya/MFnTransform.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
#include <maya/MSimple.h>
#include <maya/MTypes.h>
#include <maya/MPointArray.h>
#include <maya/MObjectArray.h>
class Utilities{
public: static const int max_mov = 50;
public:
static double get_mesh_error(MPointArray, MPointArray, int);
static MStatus translateManipulator(double amount, MObject *path);
static void GetSelected(MObjectArray* objects, MFn::Type type);
};
#endif /* defined(__Maya_CPP_Plugin__Utilities__) */
with the implementation like this
#include <Utilities.h>
double Utilities::get_mesh_error(MPointArray a, MPointArray b, int vertexCount){
...
}
MStatus Utilities::translateManipulator(double amount, MObject *path){
...
}
void Utilities::GetSelected(MObjectArray* objects, MFn::Type type) {
...
}
However I am getting the following error
duplicate symbol _MApiVersion in:
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Maya_Search_Plugin.o
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Utilities.o
ld: 1 duplicate symbol for architecture x86_64
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld failed with exit code 1
Which I presume is a linking error and there is some circular reference somewhere, but I can't work out where it is.
Any help appreciated.
Thanks.
I know this is a year old. But I stumbled on this again a couple minutes ago...
Add
#define MNoVersionString
#define MNoPluginEntry
#include <maya/MFnPlugin.h>
to your header or cpp files where you wrote your plugin code. Include
#include <maya/MFnPlugin.h>
directly in your main.cpp that initializes the plugin.
Most of the examples in maya have the following string:
// This is added to prevent multiple definitions of the MApiVersion string.
#define _MApiVersion
before including anything. For example here.
The issue may happen if you have multiple files which include MFnPlugin.h
I don't know why I can't access the function clearConsole() from my .cpp file from the header files, I guess I'm calling it wrong? How do I target the main file from a header file? I try to call the clearConsole() function after the user input in the addCustomer() functinon in customer.h.
Main.cpp
// OTS.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
#include "customer.h"
// Clear function specific to Windows
// Cross platform alternatives are more convoluted to reach desired effect, so have not been included
void clearConsole()
{
#ifdef _WIN32
system("cls");
#endif
}
Customer.h
//customer.H
//The object class customer
class customer
{
//...
clearConsole();
}
If your files are linked together, a forward declaration of the functions should be enough.
Customer.h
//customer.H
//The object class customer
void clearConsole(); // <--- declare function
class customer
{
//....
};
But this structure looks wrong. I would declare the function in a different header, inside a namespace, and define it in a corresponding implementation file:
clearconsole.h
namespace ConsoleUtils
{
void clearConsole();
}
clearconsole.cpp
namespace ConsoleUtils
{
void clearConsole()
{
}
}
Move your clearConsole() method to the header file (I think is not under discussion the implementation under .header files that I actually disagree, but anyway...), and change the system message to the specific one you need, as follows:
#ifndef _WIN32
#include <syscall.h>
#endif
void clearConsole(){
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
I also had this problem in my kernel that I'm writing in C,C++, and Assembly. I was able to fix this problem by telling the ld command to allow shared variables and functions using the -shared flag. In gcc you would just do the same thing because gcc is a linker, assembly, c compiler and a c++ compiler.
#ifndef _MY_OPENCLPLATFORM_
#define _MY_OPENCLPLATFORM_
#include "OpenCL.h"
namespace my
{
class OpenCLPlatform
{
cl_platform_id mplatformID;
cl_uint mnumDevices;
std::vector<OpenCLDevice> mdevices; // OpenCLDevice was not declared in this scope
public:
OpenCLPlatform(cl_platform_id platformID);
void getDevices();
void printInfo();
cl_platform_id& getPlatformID();
};
}
#endif
#ifndef _MY_OPENCLDEVICE_
#define _MY_OPENCLDEVICE_
#include "OpenCL.h"
namespace my
{
class OpenCLDevice
{
cl_device_id mdeviceID;
public:
OpenCLDevice(cl_device_id device);
void printInfo();
void printDeviceType(cl_device_type deviceType);
};
}
#endif
#ifndef _MY_OPENCL_
#define _MY_OPENCL_
#if defined(__APPLE__) || defined(MACOSX)
#include <OpenCL/opencl.h> // This works only for XCODE compiler
#else
#include <CL/cl.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
#include "Exception.h"
#include "OpenCLDevice.h"
#include "OpenCLPlatform.h"
namespace my {
class OpenCLDevice;
class OpenCLPlatform;
class OpenCL;
class OpenCL
{
cl_uint mnumPlatforms;
std::vector<OpenCLPlatform> mplatforms;
void getPlatforms();
public:
OpenCL();
~OpenCL();
void quickSetup();
void printPlatformVersions();
};
}
#endif
Does the the ordering "class OpenCLDevice; class OpenCLPlatform; class OpenCL;" matter? Sometimes, header files depend on each other which can lead to "hard to follow" or convoluted inclusions...Do you have a "one way" technique to deal with convoluted inclusions that you use all the time?
Edit:
I changed the code to match my real problem. If you look at the code above, the compiler is saying that 'OpenCLDevice was not declared in this scope'.
Edit:
I finally got the code to work, and this is what I did:
1. add #include "OpenCLDevice.h"in OpenCLPlatform.h
2. compile
3. remove #include "OpenCLDevice.h"in OpenCLPlatform.h
4. compile
It works now!
Edit:
I cleaned the project and removed all dependencies, and I'm getting the same errors again.
Edit:
I think compiler did something to the code. It may have chose to not include libraries that aren't used in the header and source file, but are used in other headers and source codes
Since you are including classa.h and classb.h where both classes are (presumably) defined, you shouldn't even need the forward declaration.
However, if you did not include them, then no, order of the declarations wouldn't matter. As long as as a class is forward declared before it is used you should be OK.
I see two potential issues:
Your #include "OpenCL.h" may not include the file you expect (yours), but instead some system file.
Forward declarations can't be used in your case. It works only when you have pointers or references to class instances. Your vector<OpenCLPlatform> requires the class declaration (i.e. inclusion of the corresponding header).