I've been working on porting one of my games to Linux and can't seem to figure out the reasons for the errors I'm received. The game was originally written in Visual Studio 2010 and I have extracted all of the needed content (headers, cpp, textures) and am trying to compile.
Compilation of files using g++ -c -o exampleFile.o exampleFile.cpp works fine without any errors. However upon linking I am greeted with hundreds of errors regarding std functions, an example:
Bmp.o: In function `Image::Bmp::Bmp()':
Bmp.cpp:(.text+0x58): undefined reference to `std::allocator<char>::allocator()'
Bmp.cpp:(.text+0x74): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
Bmp.cpp:(.text+0x80): undefined reference to `std::allocator<char>::~allocator()'
Bmp.cpp:(.text+0x91): undefined reference to `std::allocator<char>::~allocator()'
Full output can be found on PasteBin
The Bmp.cpp file is a library function written by someone else, it can be found here The code eluded to above is:
#include <fstream>
#include <iostream>
#include <cstring>
#include "Bmp.h"
using std::ifstream;
using std::ofstream;
using std::ios;
using std::cout;
using std::endl;
using namespace Image;
///////////////////////////////////////////////////////////////////////////////
// default constructor
///////////////////////////////////////////////////////////////////////////////
Bmp::Bmp() : width(0), height(0), bitCount(0), dataSize(0), data(0), dataRGB(0),
errorMessage("No error.")
{
}
Bmp::Bmp(const Bmp &rhs)
{
// copy member variables from right-hand-side object
width = rhs.getWidth();
height = rhs.getHeight();
bitCount = rhs.getBitCount();
dataSize = rhs.getDataSize();
errorMessage = rhs.getError();
if(rhs.getData()) // allocate memory only if the pointer is not NULL
{
data = new unsigned char[dataSize];
memcpy(data, rhs.getData(), dataSize); // deep copy
}
else
data = 0; // array is not allocated yet, set to 0
if(rhs.getDataRGB()) // allocate memory only if the pointer is not NULL
{
dataRGB = new unsigned char[dataSize];
memcpy(dataRGB, rhs.getDataRGB(), dataSize); // deep copy
}
else
dataRGB = 0; // array is not allocated yet, set to 0
}
Not really sure what the issue is, but it strikes me that the linker can't reach the std functions? Thanks in advance for any help.
Edit Linking command: gcc -o LDTux Bmp.o character.o chickenList.o chicken.o farmList.o farm.o fieldList.o field.o generall_utils.o landscape.o object.o SZ_NumberList.o SZ_Sprite.o worm.o wormList.o wormSpawn.o wormSpawnList.o GameWorld.o HelloOpenGL.o -lGL -lglut -lm
As pointed out earlier by Dietmar Kühl in the comments,
you should change the linker command from gcc to g++.
As pointed out by Dietmar Kühl in the comments, I was using gcc to link, rather than g++.
Upon amending the linking command, I received ...undefined reference to 'gluLookAt' which was fixed by adding -lGLU.
Related
I'm trying to port over a game that I made using Allegro 5.0 (from Windows to a Raspberry Pi running Raspian). I installed Allegro and moved over all my source files, but when I try to compile using: *g++ -std=c++0x .cpp -o SpaceFighter $(pkg-config --libs allegro-5) I get the following:
/tmp/ccBliSky.o: In function main':
main.cpp:(.text+0x130): undefined reference toal_show_native_message_box'
main.cpp:(.text+0x160): undefined reference to al_init_font_addon'
main.cpp:(.text+0x164): undefined reference toal_init_ttf_addon'
main.cpp:(.text+0x168): undefined reference to al_init_image_addon'
main.cpp:(.text+0x1a4): undefined reference toal_load_ttf_font'
main.cpp:(.text+0x574): undefined reference to al_draw_textf'
/tmp/ccBMyqom.o: In functionMenuItem::MenuItem()':
MenuItem.cpp:(.text+0xa0): undefined reference to al_load_ttf_font'
/tmp/ccBMyqom.o: In functionMenuItem::~MenuItem()':
MenuItem.cpp:(.text+0x1ac): undefined reference to al_destroy_font'
/tmp/ccBMyqom.o: In functionMenuItem::Draw(GameTime const*)':
MenuItem.cpp:(.text+0x2fc): undefined reference to al_draw_text'
/tmp/ccKXP3ds.o: In functionPlayerShip::SetAudioSample(std::string)':
PlayerShip.cpp:(.text+0x604): undefined reference to al_destroy_sample'
PlayerShip.cpp:(.text+0x64c): undefined reference toal_load_sample'
collect2: error: ld returned 1 exit status
AND NO THIS IS NOT A DUPLICATE OF "What are undefined reference/unresolved external symbol errors? What are common causes and how to fix/prevent them?"
I know what usually causes most undefined reference errors. This question is specific to the allegro library I'm using.
Here's a bit of code (I'm obviously not going to post the whole game):
#include <allegro5/allegro.h>
#include <allegro5/allegro_native_dialog.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_image.h>
#include <iostream>
#include "Game.h"
int main(int argc, char *argv[])
{
const char errorType[] = "Initialization Error";
const int flags = ALLEGRO_MESSAGEBOX_ERROR;
// Initialize Allegro
if (!al_init())
{
const char message[] = "Failed to initialize Allegro Library.";
//al_show_native_message_box(nullptr, "Error", errorType, message, nullptr, flags);
return -1;
}
Game game;
// Initialize a new window for gameplay.
int screenWidth = Game::GetScreenWidth();
int screenHeight = Game::GetScreenHeight();
Thanks in advance for any help!
Alegro divides its functionality across several modules. Your pkg-config line must include all the modules you are using. Try the following:
pkg-config --libs allegro-5 allegro_font-5 allegro_image-5 allegro_ttf-5
I had the same problem with the al_show_native_message_box function and I solved it by adding the following flag:
-lallegro_dialog
The problem I'm facing is difficult to describe and explain, but let's try...
Enrivornment: Ubuntu, C++ and g++
So I have an hierarchy of c++ projects and namespaces:
main: My main program - that calls....
objectaccess: Access objects (read, write, update, delete) - that calls...
commonaccess: Encapsulate access to sqlite3 functions (sqlite3_open, sqlite3_exec, etc.) - that calls...
sqlite3.so: The Sqlite3 library.
So, an example call code would be:
#include "objectaccess.hpp"
#include "commonaccess.hpp"
int main()
{
int id = 10;
myobjecttype mo = objectaccess::get(id);
}
At objectaccess I have:
#include "commonaccess.hpp"
namespace objectaccess {
myobjecttype get(int id)
{
myobjecttype mo = commonaccess::getFromTableX(id);
return mo;
}
}
At commonaccess I have:
#include <sqlite3.h>
namespace commonaccess {
myobjecttype getFromTableX(int id)
{
sqlite3_init(whatever...);
sqlite3_exe(whatever...);
myobjecttype retobject;
retobject.whatever = data1;
return retobject;
}
}
The code runs fine and is tested, except for one problem. All three namespaces are in different projects delivering a dynamic library (commonaccess.so and objectaccess.so) except for the main program that returns a binary executable.
My problem is:
At main, if I make a call to any of commonaccess functions, I get the following errors on linking:
g++ -L"/home/workspace/objectaccess/Debug"
-L"/home/workspace/commonaccess/Debug"
-L/usr/lib/i386-linux-gnu -Xlinker -rpath="./" -o "test" ./src/test.o
-lsqlite3 -lobjectaccess -lcommonaccess
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_close'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_exec'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_free'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_errmsg'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_open'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_last_insert_rowid'
collect2: error: ld returned 1 exit status
This is simply solved adding at main() a call to any function of commonaccess, like:
#include "objectaccess.hpp"
#include "commonaccess.hpp"
int main()
{
commonaccess::dummycall();
int id = 10;
myobjecttype mo = objectaccess::get(id);
}
Actually calling a dummy function is not desired, so:
a) Why the linker is not being able to solve these references without directly calling any of the commonaccess functions?
b) Why only adding a call to the lower hierarchy namespace in the main program "teaches" the linker about real reference to sqlite3 functions?
Switch the order of libraries being linked. GNU linker can't reorder them, nor keeps references to calls not used so far, so -lsqlite3 is currently useless. Put it after the library that actually uses sqlite3 calls, something like g++ -L"/home/workspace/objectaccess/Debug" -L"/home/workspace/commonaccess/Debug" -L/usr/lib/i386-linux-gnu -Xlinker -rpath="./" -o "test" ./src/test.o -lobjectaccess -lcommonaccess -lsqlite3
I'm trying to simulate a C17 logic circuit in C++ using a Library called LibLCS. Click here to see an example of a digital circuit made with this lib. But isnt working. I cant compile the code and I have no idea why.
#include <lcs/lcs.h>
#include <lcs/nand.h>
#include <lcs/simul.h>
#include <lcs/tester.h>
#include <lcs/changeMonitor.h>
// All libLCS constructs are defined under
// the namespace lcs.
using namespace lcs;
int main()
{
Bus<1> a, b, c, d, e, ga, gb, gc, gd, ge, gf;
Nand<2> nandGate1(ga, (a,b)), nandGate2(gb, (b,d));
Nand<2> nandGate3(gc, (c,gb)), nandGate4(gd, (gb,e));
Nand<2> nandGate5(ge, (ga,gc)), nandGate6(gf, (gc,gd));
ChangeMonitor<5> inputMonitor((a,b,c,d,e), "Input", DUMP_ON);
ChangeMonitor<2> outputMonitor((ge,gf), "Output", DUMP_ON);
Tester<5> tester((a,b,c,d,e));
Simulation::setStopTime(4000); // Set the stop time.
Simulation::start(); // Start the simulation.
return 0;
}
I got the following compilation error:
g++ -o c17 c17.cpp /tmp/cc5TeFfF.o: In function main':
c17.cpp:(.text+0x50a): undefined reference to lcs::Simulation::setStopTime(unsigned int)'
c17.cpp:(.text+0x50f): undefined reference to lcs::Simulation::start()' /tmp/cc5TeFfF.o: In function lcs::Bus<(1)+(1)> const lcs::Bus<1>::operator,<1>(lcs::Bus<1> const&) const':
c17.cpp(.text._ZNK3lcs3BusILi1EEcmILi1EEEKNS0_IXplT_Li1EEEERKNS0_IXT_EEE[_ZNK3lcs3BusILi1EEcmILi1EEEKNS0_IXplT_Li1EEEERKNS0_IXT_EEE]+0x75):
And many more...
From your errors trace that you gave us in comments, I may tell you that you forgot to link your program with your lib.
If your lib is called liblcs.so or liblcs.a, so add this flags to your g++ compilation :
g++ -o c17 c17.cpp -llcs -L"path to the lib folder"
It should works. Or at least it should solve this problem.
Here's my code. I'm just testing Boost::process so I'll be able to use it if/when I need to. I don't know why I'm getting the linking error that I am getting. I'm a rather novice C++ programmer. I know the concepts, but I make frequent errors in practice and am bad at debugging. I appreciate any help I can get with this.
#include<iostream>
#include<boost/process.hpp>
#include<boost/iostreams/device/file_descriptor.hpp>
namespace bp = ::boost::process;
namespace bpi = ::boost::process::initializers;
namespace bio = ::boost::iostreams;
int main(int argc, char *argv[])
{
bp::pipe p = bp::create_pipe();
bio::file_descriptor_sink sink(p.sink, bio::close_handle);
bp::execute(
bpi::run_exe("/usr/bin/ls"),
bpi::bind_stdout(sink)
);
return(0);
}
And here is my error…
/tmp/cc7cmrV8.o: In function `main':
test.cpp:(.text+0x2b): undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(int, boost::iostreams::file_descriptor_flags)'
/tmp/cc7cmrV8.o: In function `boost::process::posix::initializers::bind_stdout::bind_stdout(boost::iostreams::file_descriptor_sink const&)':
test.cpp:(.text._ZN5boost7process5posix12initializers11bind_stdoutC2ERKNS_9iostreams20file_descriptor_sinkE[_ZN5boost7process5posix12initializers11bind_stdoutC5ERKNS_9iostreams20file_descriptor_sinkE]+0x2b): undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(boost::iostreams::file_descriptor_sink const&)'
/tmp/cc7cmrV8.o: In function `void boost::process::posix::initializers::bind_stdout::on_exec_setup<boost::process::posix::executor>(boost::process::posix::executor&) const':
test.cpp:(.text._ZNK5boost7process5posix12initializers11bind_stdout13on_exec_setupINS1_8executorEEEvRT_[_ZNK5boost7process5posix12initializers11bind_stdout13on_exec_setupINS1_8executorEEEvRT_]+0x18): undefined reference to `boost::iostreams::file_descriptor::handle() const'
collect2: error: ld returned 1 exit status
Platform: Linux 64-bit
Boost: 1.55 (installed via pacman)
Boost::process: 0.5
Compile command: g++ -Wall test.cpp -o spegh.elf -lboost_system
A simple search threw me at -This-.
Seeing you posted your compile command, I'm guessing you are simply missing -lboost_iostreams in your linker settings.
I'm lost here. I've been compiling my program successfully on LLVM on my Mac, but when I went to a Linux server and attempted to use g++ to compile, I got a boat load of linker errors.
Here's an excerpt:
/tmp/ccGbgd6T.o: In function `Scene::setBackgroundImage(String)':
Project.cpp:(.text+0x166): undefined reference to `Graph_lib::Image::Image(Point, String, Graph_lib::Suffix::Encoding)'
/tmp/ccGbgd6T.o: In function `Graph_lib::Window::~Window()':
Project.cpp:(.text._ZN9Graph_lib6WindowD2Ev[_ZN9Graph_lib6WindowD5Ev]+0xc): undefined reference to `vtable for Graph_lib::Window'
/tmp/ccGbgd6T.o: In function `Graph_lib::Shape::~Shape()':
Project.cpp:(.text._ZN9Graph_lib5ShapeD2Ev[_ZN9Graph_lib5ShapeD5Ev]+0xb): undefined reference to `vtable for Graph_lib::Shape'
/tmp/ccGbgd6T.o: In function `Graph_lib::Text::Text(Point, String const&)':
Project.cpp:(.text._ZN9Graph_lib4TextC2E5PointRK6String[_ZN9Graph_lib4TextC5E5PointRK6String]+0xe): undefined reference to `Graph_lib::Shape::Shape()'
Project.cpp:(.text._ZN9Graph_lib4TextC2E5PointRK6String[_ZN9Graph_lib4TextC5E5PointRK6String]+0x17): undefined reference to `vtable for Graph_lib::Text'
Project.cpp:(.text._ZN9Graph_lib4TextC2E5PointRK6String[_ZN9Graph_lib4TextC5E5PointRK6String]+0x67): undefined reference to `Graph_lib::Shape::add(Point)'
/tmp/ccGbgd6T.o: In function `Graph_lib::Button::Button(Point, int, int, String const&, void (*)(void*, void*))':
Project.cpp:(.text._ZN9Graph_lib6ButtonC2E5PointiiRK6StringPFvPvS5_E[_ZN9Graph_lib6ButtonC5E5PointiiRK6StringPFvPvS5_E]+0x40): undefined reference to `vtable for Graph_lib::Button'
This scared me, but then I noticed that all the errors are coming from the same class: Graph_lib. Here's an extremely cut out version of what Graph.h looks like: (note, this is not my class)
#ifndef GRAPH_GUARD
#define GRAPH_GUARD 1
#include <...system stuff...>
namespace Graph_lib {
// lots of other classes in here
// this is just one
struct Image : Shape {
Image(Point xy, string file_name, Suffix::Encoding e = Suffix::none);
//rest of class
}
}
What could be going wrong here?
Edit: this is the command I'm using to compile:
g++-4.6 -std=c++0x *.cpp -lfltk -lfltk_images
It appears as though you have forgotten to link your project with Graph.cpp, or whatever file(s) hold the implementations of the Graph_lib class methods.
Looks like your Graph library is missing.
When linking using g++, use -l <Graph lib>