compile on x86_64 fails due to log4cpp

Questions, problems and discussion about compiling FreeOrion.

Moderator: Oberlus

Message
Author
tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

compile on x86_64 fails due to log4cpp

#1 Post by tomboy64 »

Alright.
I managed to install GiGi and freeorion starts compiling. Yet, after some time, it aborts, with the following errors.

Using log4cpp 0.3.4b or 0.3.5_rc3 I get:

Code: Select all

g++ -o util/AppInterface-server.o -c -pthread -Wall -O2 -D_GNU_SOURCE=1 -D_REENTRANT -DFREEORION_LINUX -DENABLE_BINRELOC -DFREEORION_BUILD_SERVER -I/usr/include/python2.4 -I/var/tmp/portage/games-strategy/freeorion-9999_pre2/image/usr/include -I/usr/include/SDL -I/usr/include/boost -I/usr/include/freetype2 -I/usr/include/graphviz -I/usr/include/log4cpp -I/usr/include/GG -Inetwork util/AppInterface.cpp
g++ -o freeoriond -pthread combat/Combat.o Empire/Empire.o Empire/EmpireManager.o Empire/ResourcePool.o network/Message.o network/MessageQueue.o network/Networking.o network/boost/error_code.o UI/StringTable.o universe/Building.o universe/Condition.o universe/ConditionParser1.o universe/ConditionParser2.o universe/ConditionParser.o universe/Effect.o universe/EffectParser.o universe/Enums.o universe/Fleet.o universe/Meter.o universe/ParserUtil.o universe/Planet.o universe/PopCenter.o universe/Predicates.o universe/ResourceCenter.o universe/Ship.o universe/ShipDesign.o universe/Special.o universe/System.o universe/Tech.o universe/TopLevelParsers.o universe/UniverseObject.o universe/ValueRef.o universe/ValueRefParser.o util/DataTable.o util/GZStream.o util/MultiplayerCommon.o util/OptionsDB.o util/Order.o util/OrderSet.o util/Process.o util/Random.o util/Serialize.o util/SitRepEntry.o util/VarText.o util/Version.o util/binreloc.o util/Directories.o util/XMLDoc.o combat/CombatSystem-server.o network/ServerNetworking-server.o server/SaveLoad-server.o server/ServerApp-server.o server/ServerFSM-server.o server/dmain-server.o universe/Universe-server.o util/AppInterface-server.o -L/usr/lib64 -L/var/tmp/portage/games-strategy/freeorion-9999_pre2/image/usr/lib -L/usr/lib -lpython2.4 -lGiGiSDL -lGiGi -lboost_serialization -lboost_iostreams -lboost_python -lboost_signals -lboost_filesystem -lboost_thread -lGL -lGLU -lSDL -lpthread -lz -lfreetype -lIL -lILU -lILUT -lalut -lopenal -lvorbisfile -lvorbis -lm -logg -lgraph -lcdt -lgvc
Empire/Empire.o: In function `Empire::ConquerBuildsAtLocation(int)':
Empire.cpp:(.text+0x5c0a): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
Empire.cpp:(.text+0x64ca): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
Empire/Empire.o: In function `Empire::PlaceBuildInQueue(BuildType, int, int, int, int)':
Empire.cpp:(.text+0x8a19): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
Empire.cpp:(.text+0x8e52): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
Empire/Empire.o: In function `Empire::PlaceBuildInQueue(BuildType, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, int)':
Empire.cpp:(.text+0xc136): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
Empire/Empire.o:Empire.cpp:(.text+0xc5d5): more undefined references to `log4cpp::CategoryStream::~CategoryStream()' follow
server/ServerApp-server.o: In function `ServerApp::~ServerApp()':
ServerApp.cpp:(.text+0x4012): undefined reference to `log4cpp::Category::shutdown()'
server/ServerApp-server.o: In function `ServerApp::~ServerApp()':
ServerApp.cpp:(.text+0x42c2): undefined reference to `log4cpp::Category::shutdown()'
server/ServerApp-server.o: In function `ServerApp::ServerApp()':
ServerApp.cpp:(.text+0x4b8e): undefined reference to `log4cpp::Category::getRoot()'
ServerApp.cpp:(.text+0x4ffc): undefined reference to `log4cpp::FileAppender::FileAppender(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, unsigned int)'
ServerApp.cpp:(.text+0x5019): undefined reference to `log4cpp::PatternLayout::PatternLayout()'
server/ServerApp-server.o: In function `ServerApp::ServerApp()':
ServerApp.cpp:(.text+0x5d1e): undefined reference to `log4cpp::Category::getRoot()'
ServerApp.cpp:(.text+0x618c): undefined reference to `log4cpp::FileAppender::FileAppender(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, unsigned int)'
ServerApp.cpp:(.text+0x61a9): undefined reference to `log4cpp::PatternLayout::PatternLayout()'
server/ServerApp-server.o: In function `ServerApp::ProcessTurns()':
ServerApp.cpp:(.text+0x9374): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
ServerApp.cpp:(.text+0x9973): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
ServerApp.cpp:(.text+0x99e1): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
ServerApp.cpp:(.text+0x9ac0): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
ServerApp.cpp:(.text+0x9ad5): undefined reference to `log4cpp::CategoryStream::~CategoryStream()'
server/ServerApp-server.o:ServerApp.cpp:(.text+0xa156): more undefined references to `log4cpp::CategoryStream::~CategoryStream()' follow
util/AppInterface-server.o: In function `Logger()':
AppInterface.cpp:(.text+0x41): undefined reference to `log4cpp::Category::getRoot()'
collect2: ld returned 1 exit status
scons: *** [freeoriond] Error 1
scons: building terminated because of errors.
When using log4cpp-1.0 it dies even sooner with:

Code: Select all

universe/Universe.cpp: In member function 'void Universe::GenerateEmpires(int, std::vector<int, std::allocator<int> >&, const std::map<int, PlayerSetupData, std::less<int>, std::allocator<std::pair<const int, PlayerSetupData> > >&)':
universe/Universe.cpp:2768: error: 'FloatClr' is not a member of 'GG'
scons: *** [universe/Universe-server.o] Error 1
scons: building terminated because of errors.
Hints? Suggestions?

Edit: hummm ... i just noticed configure spat out

Code: Select all

Checking for log4cpp >= 0.3.4b... no
Checking log4cpp version == 0.3.4b... (cached) yes
Checking for C++ header file log4cpp/Category.hh... yes

User avatar
loonycyborg
Compilation Expert
Posts: 219
Joined: Thu Jul 06, 2006 10:30 pm
Location: Russia/Moscow

Re: compile on x86_64 fails due to log4cpp

#2 Post by loonycyborg »

I don't see -llog4cpp in linker command.
tomboy64 wrote: Edit: hummm ... i just noticed configure spat out

Code: Select all

Checking for log4cpp >= 0.3.4b... no
This check tries to detect log4cpp with pkg-config. This fails because log4cpp-config must be used instead.

Code: Select all

Checking for C++ header file log4cpp/Category.hh... yes
This check is successful and should add -llog4cpp to LIBS. I have no idea why it doesn't do this in your case.
In Soviet Russia, forum posts YOU!!

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#3 Post by tomboy64 »

mhmmm

well, at least now i know what the problem is ... i think.

now how would i go about that? any hints? ideas? suggestions?


EDIT: well, it seems that log4cpp-1.0 has the log4cpp.pc package-config is missing. BUT (as stated above) with log4cpp-1.0 it crashes even earlier xD

User avatar
loonycyborg
Compilation Expert
Posts: 219
Joined: Thu Jul 06, 2006 10:30 pm
Location: Russia/Moscow

Re: compile on x86_64 fails due to log4cpp

#4 Post by loonycyborg »

You can modify SConstruct to use log4cpp-config to get linker flags:

Code: Select all

@@ -431,8 +434,7 @@
         AppendPackagePaths('log4cpp', env)
         found_it_with_pkg_config = False
         if pkg_config:
-            if conf.CheckPkg('log4cpp', log4cpp_version):
-                env.ParseConfig('pkg-config --cflags --libs log4cpp')
+                env.ParseConfig('log4cpp-config --cflags --libs')
                 found_it_with_pkg_config = True
         if not found_it_with_pkg_config:
             version_regex = re.compile(r'LOG4CPP_VERSION\s*\"([^"]*)\"', re.DOTALL)
log4cpp doesn't provide .pc files, at least on Gentoo. It provides log4cpp-config script instead.
In Soviet Russia, forum posts YOU!!

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#5 Post by tomboy64 »

log4cpp does provide this file since 1.0.

now trying your patch.

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#6 Post by tomboy64 »

You patch works, thanks. I am able to compile freeorion and play it.

There's one issue left, though:
When I start freeorion it gives the error

Code: Select all

GG exception (subclass GG::Font::BadFile) caught in GUI::Run(): Face object created from '/home/tomboy/DejaVuSans.ttf' was invalid
(where /home/tomboy is my ${PWD})

I'm not quite sure if that's an issue i will resolve via my package-manager or patch the sources ... we'll see.

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: compile on x86_64 fails due to log4cpp

#7 Post by Geoff the Medio »

Looks like it can't find the indicated font file... You could try copying the relevant file to the location you're running from, but I'm guessing it'd then die trying to find some other file. So, could you try running from the directory where all the freeorion data files are located? I believe this directory should contain the font files and a subdir called "default".

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#8 Post by tomboy64 »

forgot to mention:
freeorion works quite fine the way you suggest. it even has /home/tomboy/.freeorion... located as the proper location for savegames. ^^

i asked the person responsible for my distro's game-package and he told me it was freeorion's fault.
might this be related to scons-options? or would this indeed be a coding error?

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: compile on x86_64 fails due to log4cpp

#9 Post by Geoff the Medio »

OK... so if it works, what is the problem?

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#10 Post by tomboy64 »

It wants to be started from the datadir - i want it to start from wherever I am.

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: compile on x86_64 fails due to log4cpp

#11 Post by Geoff the Medio »

You're not the first to note / complain about this. For reasons I'm not entirely clear on, tzlaine doesn't want to change the code, however I did some work on it last summer (see below), though I'm not sure if this was in a working state, or if more recent changes will have broken it.

Also, further modifications should be made to move the font files from the binary directory into the "default" directory, and updating the code to look for them in the new location.

(Moving the fonts and accordingly updating the code would actually allow you to run freeorion from anywhere without any more changes, but it would die later when trying to spawn a server process that it currently expects to be located in the working directory... The patch below was supposed to fix that part as well)

Code: Select all

Index: server/dmain.cpp
===================================================================
--- server/dmain.cpp	(revision 2221)
+++ server/dmain.cpp	(working copy)
@@ -8,7 +8,7 @@
 extern "C" // use C-linkage, as required by SDL
 int main(int argc, char* argv[])
 {
-    InitDirs();
+    InitDirs(argv[0]);
 
     try {
         GetOptionsDB().AddFlag('h', "help", "Print this help message.");
Index: util/Directories.cpp
===================================================================
--- util/Directories.cpp	(revision 2221)
+++ util/Directories.cpp	(working copy)
@@ -12,20 +12,23 @@
 
 namespace {
     bool g_initialized = false;
+    fs::path bin_dir = fs::initial_path();
 }
 
 #if defined(FREEORION_LINUX)
 #include "binreloc.h"
 
-void InitDirs()
+void InitBinDir(const std::string& argv0);
+
+void InitDirs(const std::string& argv0)
 {
     if (g_initialized)
         return;
 
-    if (fs::path::default_name_check_writable())
-        fs::path::default_name_check(fs::native);
-
-    // store working dir
+    /* store working dir.  some implimentations get the value of initial_path from the value of
+       current_path the first time initial_path is called, so it is necessary to call initial_path
+       as soon as possible after starting the program, so that current_path doesn't have a chance
+       to change before initial_path is initialized. */
     fs::initial_path();
 
     br_init(0);
@@ -40,6 +43,8 @@
         fs::create_directories(p);
     }
 
+    InitBinDir(argv0);
+
     g_initialized = true;
 }
 
@@ -53,7 +58,7 @@
 
 const fs::path GetGlobalDir()
 {
-    if (!g_initialized) InitDirs();
+    if (!g_initialized) InitDirs("");
     char* dir_name = br_find_data_dir("/usr/local/share");
     fs::path p(dir_name);
     std::free(dir_name);
@@ -68,27 +73,48 @@
 
 const fs::path GetBinDir()
 {
-    if (!g_initialized) InitDirs();
-    char* dir_name = br_find_bin_dir("/usr/local/bin");
-    fs::path p(dir_name);
-    std::free(dir_name);
-    // if the path does not exist, we fall back to the working directory
-    if (!exists(p)) {
-        return fs::initial_path();
-    } else {
-        return p;
+    if (!g_initialized) InitDirs("");
+    return bin_dir;    
+}
+
+void InitBinDir(const std::string& argv0)
+{
+    bool problem = false;
+    try
+    {
+        fs::path binary_file = fs::system_complete(fs::path(argv0));
+        bin_dir = binary_file.branch_path();
     }
+    catch (fs::filesystem_error err)
+    {
+        problem = true;
+    }
+
+    if (problem || !exists(bin)dir)
+    {
+        // failed trying to parse the call path, so try hard-coded standard location...
+        char* dir_name = br_find_bin_dir("/usr/local/bin");
+        fs::path p(dir_name);
+        std::free(dir_name);
+
+        // if the path does not exist, we fall back to the working directory...
+        if (!exists(p)) {
+            bin_dir = fs::initial_path();
+        } else {
+            bin_dir = p;
+        }
+    }
 }
 
 #elif defined(FREEORION_WIN32)
 
-void InitDirs()
+void InitBinDir(const std::string& argv0);
+
+void InitDirs(const std::string& argv0)
 {
     if (g_initialized)
         return;
 
-    fs::path::default_name_check(fs::native);
-
     fs::path local_dir = GetLocalDir();
     if (!exists(local_dir))
         fs::create_directories(local_dir);
@@ -97,6 +123,8 @@
     if (!exists(p))
         fs::create_directories(p);
 
+    InitBinDir(argv0);
+
     g_initialized = true;
 }
 
@@ -115,9 +143,23 @@
 
 const fs::path GetBinDir()
 {
-    return fs::initial_path();
+    if (!g_initialized) InitDirs("");
+    return bin_dir;
 }
 
+void InitBinDir(const std::string& argv0)
+{
+    try
+    {
+        fs::path binary_file = fs::system_complete(fs::path(argv0));
+        bin_dir = binary_file.branch_path();
+    }
+    catch (fs::filesystem_error err)
+    {
+        bin_dir = fs::initial_path();
+    }
+}
+
 #else
 #  error Neither FREEORION_LINUX nor FREEORION_WIN32 set
 #endif
Index: util/Directories.h
===================================================================
--- util/Directories.h	(revision 2221)
+++ util/Directories.h	(working copy)
@@ -8,7 +8,7 @@
 /** This function must be called before any Get*Dir function is called. It stores the current working directory as well
     as creating local directories if they do not yet exist.
  */
-void InitDirs();
+void InitDirs(const std::string& argv0);
 
 /** This function returns the directory where FreeOrion should store user specific data, like the configuration file and
     savegames.  Under Unix, this would be <tt>~/.freeorion</tt>, under Windows, this might be something along the lines
Index: UI/ClientUI.cpp
===================================================================
--- UI/ClientUI.cpp	(revision 2221)
+++ UI/ClientUI.cpp	(working copy)
@@ -45,11 +45,11 @@
 fs::path ClientUI::ArtDir()                    { return GetSettingsDir() / "data" / "art"; }
 fs::path ClientUI::SoundDir()                  { return GetSettingsDir() / "data" / "sound"; }
 
-std::string ClientUI::Font()                   { return (GetGlobalDir() / GetOptionsDB().Get<std::string>("UI.font")).native_file_string(); }
-std::string ClientUI::FontBold()               { return (GetGlobalDir() / GetOptionsDB().Get<std::string>("UI.font-bold")).native_file_string(); }
-std::string ClientUI::FontItalic()             { return (GetGlobalDir() / GetOptionsDB().Get<std::string>("UI.font-italic")).native_file_string(); }
-std::string ClientUI::FontBoldItalic()         { return (GetGlobalDir() / GetOptionsDB().Get<std::string>("UI.font-bold-italic")).native_file_string(); }
-std::string ClientUI::TitleFont()              { return (GetGlobalDir() / GetOptionsDB().Get<std::string>("UI.title-font")).native_file_string(); }
+std::string ClientUI::Font()                   { return (GetBinDir() / GetOptionsDB().Get<std::string>("UI.font")).native_file_string(); }
+std::string ClientUI::FontBold()               { return (GetBinDir() / GetOptionsDB().Get<std::string>("UI.font-bold")).native_file_string(); }
+std::string ClientUI::FontItalic()             { return (GetBinDir() / GetOptionsDB().Get<std::string>("UI.font-italic")).native_file_string(); }
+std::string ClientUI::FontBoldItalic()         { return (GetBinDir() / GetOptionsDB().Get<std::string>("UI.font-bold-italic")).native_file_string(); }
+std::string ClientUI::TitleFont()              { return (GetBinDir() / GetOptionsDB().Get<std::string>("UI.title-font")).native_file_string(); }
 
 int         ClientUI::Pts()                    { return GetOptionsDB().Get<int>("UI.font-size"); }
 int         ClientUI::TitlePts()               { return GetOptionsDB().Get<int>("UI.title-font-size"); }
Index: client/human/chmain.cpp
===================================================================
--- client/human/chmain.cpp	(revision 2221)
+++ client/human/chmain.cpp	(working copy)
@@ -15,7 +15,7 @@
 extern "C" // use C-linkage, as required by SDL
 int main(int argc, char* argv[])
 {
-    InitDirs();
+    InitDirs(argv[0]);
 
     // read and process command-line arguments, if any
     try {
Index: client/AI/camain.cpp
===================================================================
--- client/AI/camain.cpp	(revision 2221)
+++ client/AI/camain.cpp	(working copy)
@@ -7,7 +7,7 @@
 extern "C" // use C-linkage, as required by SDL
 int main(int argc, char* argv[])
 {
-    InitDirs();
+    InitDirs(argv[0]);
     try {
         GetOptionsDB().SetFromCommandLine(argc, argv);
         AIClientApp g_app(argc, argv);

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#12 Post by tomboy64 »

Great!
Thanks!

Let's see ...

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#13 Post by tomboy64 »

somehow i'm not able to use the patch directly from the forum. :evil:
and i must admit i'm a bit lazy right now :oops:

would you mind pasting it to rafb.net/paste or put it online somewhere?

thanks!

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: compile on x86_64 fails due to log4cpp

#14 Post by Geoff the Medio »

Pasted... though I'm not sure what difference that will make... You'll still need to apply the patch to the code. Do you have more difficulty cutting and pasting into a text file from the forums than that site?

tomboy64
Space Floater
Posts: 23
Joined: Mon Jan 07, 2008 5:14 pm

Re: compile on x86_64 fails due to log4cpp

#15 Post by tomboy64 »

mah ... dunno.
i can't apply your patch. had to completely retype it - it just was not accepted :/

anyway, you might wanna correct the (red) typo in the following chunk to the green written one.
@@ -68,27 +72,48 @@

const fs::path GetBinDir()
{
- if (!g_initialized) InitDirs();
- char* dir_name = br_find_bin_dir("/usr/local/bin");
- fs::path p(dir_name);
- std::free(dir_name);
- // if the path does not exist, we fall back to the working directory
- if (!exists(p)) {
- return fs::initial_path();
- } else {
- return p;
+ if (!g_initialized) InitDirs("");
+ return bin_dir;
+}
+
+void InitBinDir(const std::string& argv0)
+{
+ bool problem = false;
+ try
+ {
+ fs::path binary_file = fs::system_complete(fs::path(argv0));
+ bin_dir = binary_file.branch_path();
}
+ catch (fs::filesystem_error err)
+ {
+ problem = true;
+ }
+
+ if (problem || !exists(bin)dir)
+ if (problem || !exists(bin_dir))
+ {
+ // failed trying to parse the call path, so try hard-coded standard location...
+ char* dir_name = br_find_bin_dir("/usr/local/bin");
+ fs::path p(dir_name);
+ std::free(dir_name);
+
+ // if the path does not exist, we fall back to the working directory...
+ if (!exists(p)) {
+ bin_dir = fs::initial_path();
+ } else {
+ bin_dir = p;
+ }
+ }
}

#elif defined(FREEORION_WIN32)

-void InitDirs()
+void InitBinDir(const std::string& argv0);
+
+void InitDirs(const std::string& argv0)
{
if (g_initialized)
return;

- fs::path::default_name_check(fs::native);
-
fs::path local_dir = GetLocalDir();
if (!exists(local_dir))
fs::create_directories(local_dir);

Post Reply