The International Simutrans Forum

Simutrans Extended => Simutrans-Extended development => Topic started by: jamespetts on August 17, 2009, 07:14:22 am

Title: Help with Linux compile error
Post by: jamespetts on August 17, 2009, 07:14:22 am
I am having some difficulty in making the Linux version of Simutrans-Experimental 6.4 compile, and it is hard for me to test it properly because I use Windows and thus can only run a compile test once a day using the automated nightlies. Compiling under Linux produces the following error:

Code: [Select]
gui/convoi_detail_t.o: In function `gui_vehicleinfo_t::zeichnen(koord)':
convoi_detail_t.cc:(.text+0x421): undefined reference to `vehikel_besch_t::calc_running_cost(karte_t const*, unsigned int) const'

No error is produced under Windows. That method is properly declared in the header file, and the header file is #included in the source file (by #including another header file which, in turn, #includes the relevant part). I should be grateful for ****istance from anyone who can help. For the time being, 6.3 will remain the latest Linux version.
Title: Re: Help with Linux compile error
Post by: gerw on August 17, 2009, 08:27:06 am
Compiling simutrans, I got (I already commented this additional include-statement):
Code: [Select]
===> DEP gui/convoi_detail_t.cc
===> CXX gui/convoi_detail_t.cc
gui/../vehicle/../besch/vehikel_besch.h:307: Warnung: inline-Funktion »uint32 vehikel_besch_t::calc_running_cost(const karte_t*, uint32) const« verw
det, aber nirgendwo definiert
===> LD  sim
gui/convoi_detail_t.o: In function `gui_vehicleinfo_t::zeichnen(koord)':
convoi_detail_t.cc:(.text+0x78d): undefined reference to `vehikel_besch_t::calc_running_cost(karte_t const*, unsigned int) const'
collect2: ld gab 1 als Ende-Status zurück
make: *** [sim] Fehler 1

Thus, I think the problem is, that this function is defined inline, but it isn't defined in the headerfile.

With this changes it compiles fine:
Code: [Select]
diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h
index f0fb2fe..8bb81bb 100644
--- a/besch/vehikel_besch.h
+++ b/besch/vehikel_besch.h
@@ -304,7 +304,7 @@ public:
        bool is_available_only_as_upgrade() const { return available_only_as_upgrade; }
 
        // BG, 15.06.2009: the formula for obsolescence formerly implemented twice in get_betriebskosten() and get_fixed_maintenance()
-       inline uint32 calc_running_cost(const karte_t *welt, uint32 base_cost) const;  
+       uint32 calc_running_cost(const karte_t *welt, uint32 base_cost) const;
 
        /**
        * @return introduction year
diff --git a/gui/convoi_detail_t.cc b/gui/convoi_detail_t.cc
index 72e828f..aef4bad 100644
--- a/gui/convoi_detail_t.cc
+++ b/gui/convoi_detail_t.cc
@@ -34,7 +34,7 @@
 
 #ifndef WIN32
 // G++ seems to go wrong without this.
-#include "../besch/vehikel_besch.cc"
+// #include "../besch/vehikel_besch.cc"
 #endif
 
 

Edit: I've also found a good explanation of your mistake:

Quote
Note: It's imperative that the function's definition (the part between the {...}) be placed in a header file, unless the function is used only in a single .cpp file. In particular, if you put the inline function's definition into a .cpp file and you call it from some other .cpp file, you'll get an "unresolved external" error from the linker.
http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.6 (http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.6)
Title: Re: Help with Linux compile error
Post by: jamespetts on August 19, 2009, 09:34:50 pm
Gerw,

thank you very much for the diagnosis - that is extremely helpful.
Title: Re: Help with Linux compile error
Post by: gerw on August 24, 2009, 07:16:58 am
I'm glad I could help you.