Author Topic: Complete solution found for Borland C++ 5.5 linkage errors  (Read 14816 times)

Offline driftcode

  • Single posting newcomer
  • *
  • Posts: 4
Complete solution found for Borland C++ 5.5 linkage errors
« on: August 21, 2010, 03:46:05 am »
After a few hours of fiddlin', I've finally arrived at a total solution (and moreover, an explanation) for the "unresolved external symbol" difficulty faced when attempting to use Borland's free BCB5.5 compiler through the C::B IDE.

First the problem statement.  Even after properly configuring the 2 recommended .cfg files and/or setting up the appropriate global variables inside C::B, people find that when building their projects they receive numerous "unresolved external symbol" errors from the linker, ilink32.exe.  When the same file is built from the command-line (with bcc32.exe), the exe is created without issue.

The problem lies with the linker itself.  It's flat-out dumb, or at least not as smart as mingw and openwatcom's linkers.  Even with the library directories set up properly, the linker requires EXPLICIT naming of needed libraries.  When implicitly called from bcc32, the appropriate libs are included.  But not when the "Build" command is given inside the IDE.  This means that a user must know exactly which libraries are required by the project.   As I'm not an expert on libraries (or anything really ^^), I was completely dumbfounded.  How the hell am I supposed to know what built-in libraries are needed even by a simple "Hello, World" program?  Or even what each library is for?  Thankfully, a little research goes a long way.

http://docwiki.embarcadero.com/RADStudio/en/Static_Runtime_Libraries lists all the main libraries included with BCB55 (and more.)  A little more searching turned up that all Windows programs must include import32.lib, even console apps.  For simple programs, the only other lib needed is cw32.lib, the static runtime library.  Thus armed, it is surprisingly easy to get BCB55 to work correctly:

(for C::B 10.05)
Settings > Compiler and Debugger... > (select) Borland C++ Compiler (5.5, 5.82)

under Linker settings tab, add the following to "Link libraries" (order is important according to borland docs):
import32
cw32

That's it.  The "Build" command will function as expected provided that the program isn't too complex (uses internet functionality or directx, for example.)  If that utility is needed, I'd recommend adding the appropriate library under "Project > Build options...", so as not to include it with every new BCB55 project.  The other option, of course, is to simply add the name of every available library in the global settings (this was one of the recommended solutions I found on this forum, but it didn't tell me WHY it was needed.)

While, I'm at it, I'll suggest adding one more thing to the Linker settings.  Under "Other linker options" add the text "/x/c/Gn" without quotes.  This tells the linker not to generate the extraneous files it normally would.

I hope this helps the few people old-fashioned enough to want to use BCB55 in the first place. ^,^

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5496
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #1 on: August 21, 2010, 03:23:12 pm »
very well done, and thank you very much for sharing this information  :P

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #2 on: August 23, 2010, 01:49:50 am »
Since I enjoy using this toolchain myself let me add some more info that might be useful.

While it's true that those are the typical libraries you need to link with with your program, there are actually several versions of it. e.g. multithreaded vs single-threaded, dynamic runtime vs statically linked runtime, wide-chars vs byte chars.

The trick is to realized that bcc32 already knows which runtime libraries are needed when you're building your program. Thusly, instead of calling ilink32 directly by C::B just have it call bcc32 for the linking process as well. This idea is actually used by gcc toolchain too. Linker for gcc is never actually invoked directly by C::B but is invoked indirectly by calling one of the 'frontend' command lines like gcc-c++.

This will simplify somethings by not having to remember which lib files to include. Instead you just specify what kind of program you're compiling by supplying the proper options. bcc32 will take care of the rest by telling ilink32 which lib files it should include.

Just for reference here's a quick list of options that you'll want to pass to bcc32 depending on what your building:

Code
-tW         Windows GUI program
-tWC       win32 Console program
-tWM       Multi threaded program
-tWD       build as DLL shared library
-tWR       Dynamically link the runtime to program

As an example, let say you want to compile your program as a console multithreaded application and you want dynamically runtime linkage to make your executable smaller1. The commandline you want C::B to invoke should look something like this:

For each C/C++ source in your project compile as:
bcc32 -tWM -c -Iyour include directories  -oyourobjfile.obj -c yoursrcfilename.cpp

Link all compiled translation units together like this:
bcc32 -tWC -tWM -tWR -Lyour library directories -eexecutablename.exe srcobjfile1.obj srcobjfile2.obj srcobjfileN.obj extra library files

Supply import library files in the extra library files section. If your program, for example, depends on or uses 3rd party API like say wxwidgets or SDL, this is where you would include it2.

All in all, this is a really nice toolchain. Sure it may be old but it doesn't mean it isn't functional. I particularly like how fast it's able to compile code. Just to compare, I was able to build the SDL API from source in just ~5seconds w/o using parallel-build. This 5 seconds includes:

  • compiling all the SDL source
  • linking objects together to produce SDL.dll
  • compiling SDLmain.lib
  • compiling and linking of all the test demo programs supplied.

MSVC9 compiler took ~8seconds to do the same thing. Now the really fun part is if I enable 4 parallel builds then that entire process gets reduced down to just 2 seconds!

1. Note that your program will need the cc32xx.dll runtime if you do link it dynamically.
2. Note that bcc32 already supplies the needed runtime cw.lib and import32.lib files to the linker. So you do not need to include it here.
« Last Edit: August 23, 2010, 02:05:26 am by Greatwolf »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #3 on: August 23, 2010, 06:56:47 am »
I'd say this better should make it into the WiKi, otherwise it'll be hard to find.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline driftcode

  • Single posting newcomer
  • *
  • Posts: 4
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #4 on: August 24, 2010, 01:53:07 am »
... let me add some more info that might be useful.
snip


Great idea.  The one problem I can see with this method is programs that have resource (.res) files.
Apparently, bcc32 does not have an option to pass them straight to the linker, so ilink32 must be
called explicitly, and thus information about used libraries, etc, must be known.  I have read that
there is a borland pragma, namely #pragma resource "app_name.res", that you can put in your main
source file that will instruct bcc32 to include and pass "app_name.res" to ilink32.  However, I've not
bothered to test it.  Greatwolf, you seem to have more experience with the toolchain than I.  Have
you tried this pragma?

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #5 on: August 29, 2010, 06:51:34 am »
It's true compiled resources can't be passed to the linker in this fashion. The method of using #pragma works perfectly fine as far as I could tell and that's the method I use whenever I need to link resources into my program. I found it to be the most straight forward way of doing it.

What I have done is put the #pragma resource line in the resource.h header file. It doesn't seem like the linker minds having multiple reference to link the same resource file:

//resource.h
Code
#ifndef __RESOURCE_H__
#define __RESOURCE_H__

#define APPICON    1
#pragma resource "resource.res"

#endif

//resource.rc
Code
#include "resource.h"

APPICON ICON "sample.ico"

//main.cpp
Code
#include "resource.h"

using namespace std;

//or WinMain if it's windows GUI app
int main()
{
    //code that does something useful goes here
    return 0;
}

Hope that helps

Offline emanahmed

  • Single posting newcomer
  • *
  • Posts: 8
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #6 on: August 29, 2010, 11:03:25 pm »
thanks alot for help

Offline StevePRGM

  • Single posting newcomer
  • *
  • Posts: 2
Re: Complete solution found for Borland C++ 5.5 linkage errors
« Reply #7 on: April 27, 2012, 10:14:07 pm »
Supposedly, this isn't supposed to be in this forum (Reason: post is about compiler issues)
Here's links to forums for Borland compiler information (which i have found after searching)

about #pragma | DaniWeb
http://www.daniweb.com/software-development/cpp/threads/8862/about-pragma

Borland pragma to add a library - DevX.com Forums
http://forums.devx.com/showthread.php?t=92861

PS.
Note: I have referenced this in forums.devx.com as a place for information about the Borland compiler..