What's the best compiler to use for Windows programming with wxWindows?
Can I use an Integrated Development Environment?
How can I use wxWindows with Borland C++?
How can I use wxWindows with Turbo C++ 3.1?
How can I use wxWindows with Borland C++ 3.1?
Why do I get "data segment overflow error" when linking using Borland compiler?
My Windows compiler doesn't contain all the required .lib files.
Is it possible to use multithreaded library with wxWindows under MS-Windows?
Can I use wxWindows with Watcom C++?
How can I compile PROLOGIO with Borland C++?
I get a compilation error in wb_item.cpp using Borland C++.
Can I use DJGPP with wxWindows?
Can I use GNU-WIN32 with wxWindows?
Can I make a DLL out of wxWindows to reduce executable size?
There will be a variety of views on this, but here's my view (Julian Smart).
Borland C++ 4.x generates a lot of mailing list traffic with people experiencing a bewildering variety of problems. The size and scope of wxWindows exacerbates any problems with a Windows compiler, and Borland is no exception (see later sections for more details). The debugger is particularly bad, but then this is a general problem with Windows compilers. Borland has the major advantages of wide use and 32-bit WIN32S, but I would not recommend it over Visual C++ 1.x if you are starting out with a choice and do not need 32-bit compilation.
Visual C7 should work with wxWindows but I'd recommend upgrading.
Visual C++ 1.5 is what I use for wxWindows and therefore the makefiles are the most developed, and there will be least trouble in using wxWindows with Visual C++ 1.5. The CodeView debugger, while boring, is at least reliable and functional unlike many of the others. However, for 32-bit compilation you'll need a separate compiler (e.g. VC++ 2.x which comes with VC++ 1.5 on the same CD-ROM). I haven't used VC++ 2.x but it sounds at least as reliable as 1.5.
Watcom C++ 10.0 is famous for its generated code speed and ability to compile in 32-bit mode. Users have spent some time and trouble making Watcom C++ and wxWindows see eye-to-eye, although there are still a few wrinkles to be resolved. However 16-bit wxWindows compilation with Watcom is a no-no in my experience. The text-mode debugger seems OK but flashes like mad between text screen and Windows screen so CodeView looks like heaven in comparison. It's possible that your video card, if not your eyes, would give up the ghost after a lot of this kind od switching. The Windows-hosted debugger is itself to buggy to use, unfortunately. Watcom boasts a wide range of targets for the compiler, including 16-bit Windows, 32-bit standard Windows API, 32-bit WIN32 and WIN32s API, and even OS/2 if you purchase more kit from IBM for Presentation Manager programming. Unfortunately you won't be able to debug WIN32s programs under Windows 3.1: you'll need Windows 95 or NT for that. Watcom compile speed is effectively very slow because the precompiled header criteria are too strict to be practical; but this is partially compensated for by quick link times. So if you're doing small changes to the source and lots of linking, Watcom is much better than Visual C++.
Symantec C++ I have no experience of, though some people use it with wxWindows. It has a famously nice IDE, but so far I've avoided IDEs because of their lack of flexibility compared with makefiles, and they have a habit of multitasking badly.
DJGPP (a port of GNU G++) is not a contender (see section on this below).
In summary: if you want to be reasonably sure of reliability and compatibility with future versions of Windows and wxWindows, I would recommend going for Microsoft's VC++ 2.x (a 32-bit compiler with 16-bit VC++ 1.5 included). Not because I enjoy swelling Microsoft's profits, but I believe this is the most reliable and hassle-free solution. If your application doesn't need 32-bits or fancy controls, then you could do worse than compile 16-bit applications using VC++ 1.5 ensuring that they'll run under NT/Windows 95; and then make the switch to 32-bit compilation when you know most people can run your 32-bit applications.
With the hassles implicit in GUI programming, the last thing you need is an unreliable compiler, so with compiler prices dropping, I'd recommend that you treat yourself to a decent compiler.
It is possible to use an existing IDE for writing code, but the project file settings are tricky and often the IDEs do not allow the flexibility that wxWindows requires, with its little libraries tucked away in odd places. By adding enough switches, it should be possible.
In particular, some IDEs (such as Microsoft's) do not like C++ source files to have .cpp extensions, so renaming of .cpp files is necessary.
Here are some tips for using Borland C++ with wxWindows.
If you are not sure about which files must be included, look into a makefile, if it exists, for the sources. Don't worry about libraries, BC4 has its own windows libraries.
The IDE can read version 3.1 *.prj files, and then convert them to the new format. You must repeat item 1 (above) each time you read a *.prj file, and sometimes you'll have to select the .cpp files in the project window, and drop them on the target file (.exe or .lib), in order to obtain little bullets in left of the project window (ie. to make the IDE recognize the files). If there are no many .cpp files, I recomend to create a new *.ide file.
Now the wxWindows distribution includes Borland makefiles. The file "makefile.bcc" from samples\minimal directory could be used as a template.
Build wx.lib with the supplied makefiles. If you want to use the IDE for your new applications:
Example files for minimal example:
minimal[.exe] -minimal.cpp -minimal.rc -minimal.def -wx.lib
Copy wx_panel.cpp, wx_utils.cpp, wx_dialg.cpp, wx_timer.cpp and wx_clipb.cpp to corresponding .cpp files. You need not change the names in the makefile. BCC will compile the .cpp modules.
Hopefully this workaround will be made redundant at some point in the future.
From: leif@danmos.dk
Date: Wed, 2 Apr 97 02:36 WST
To: wxwin-users@babbage.eng.nene.ac.uk
Subject: Borland C++ 5.0 and wxString problem
Hi Pasquale and others,
On Fri, 21 Mar 1997 Pasquale Foggia wrote:
> leif@danmos.dk writes:
> [...]
> > Borland C++/5.0. I am using wxString and wxRegex from 'contrib', which
> > works fine in Windows 3.11 and Linux. Now I get a memory access violation
> > using wxString::Index (wxRegex (" \n\t]+", 0). I have tracked it down to
> [...]
> > I have now tracked the problem down to being a question of signed/
> > unsigned char's. I am using an .ide to generate all the libraries, and
> > I have here marked 'Borland extentions' in the 'Compiler|Source code'
> > option. This seems *not* to set the define __STDC__ which is needed in
> > wxregex.cpp module. I tried to mark 'ANSI' instead, which made quite
> > a bit of difference. Now wxRegex worked :-). BUT, if I compile the
> > whole library with this 'ANSI' marked, I get an error in winreg.h :-(.
> >
> > I also tried to compile all of the libraries using the makefile.b32,
> > which generated a library having the first problem (wxRegex not working).
> >
> [...]
>
> The Borland C (correctly?) doesn't define __STDC__ when you enable the
> Borland extensions, because in this mode there are non-ANSI keywords like
> far (if you are compiling a 16 bit app) or _export that may be non compatible
> with a valid ANSI C program. The problem is that such keywords are needed
> to compile <windows.h>, so you must set the Borland extensions checkbox
> in your project. The solution to your problem is simply putting
>
> #if !defined(__STDC__) && defined(__BORLANDC__)
> #define __STDC__ 1
> #endif
>
> at the beginning of every file that may need it.
This was really a great help. I had a hard time, however, to track
down which files needed this, until I just tried to put '__STDC__=1' in
Options|Project|Compiler|Defines in the .ide as a general define for
compiling the whole library (it corresponds to the makefile.b32 file).
Then everything worked (and still does :-).
Maybe it was an idea to put this '#define __STDC__ 1' thing into
the standard makefile.b32 !?
Thanks,
Leif Jensen (leif@danmos.dk)
If Borland crashes or runs out of memory during a compile, you may need to configure your DPMI swap file: see P. 21 of the Borland 4.0 User Guide. This is particularly necessary if you only have 8MB of physical memory.
For precompiled headers to work properly on the wxWindows library, you will need to uncomment the first
// #include "wx.h"line in each file in src/base. Yes, this does look like some files will be included three times: but they won't really. The line has to be before any pragmas of ifdefs, or the precompilation doesn't work.
If you don't recompile wx.lib often, this editing is not necessary.
Here are the settings you need to make in Turbo C++ 3.1:
Compiler Code Generation: Model = Large Assume SS=DS = Never Defines = wx_msw Options = Treate enums as int Dup Strings merged Advanced Code Generation Options = Generate underbars Auto Far Data - Far data threshhold = 4 Make Run Librarian C++ Options C++ Always Link Libraries Container Class = none Object Windows Lib = none Standard Run Time Lib = StaticYou will probably need to turn off many components in wx_setup.h.
The simple answer is probably "don't try, get a more recent compiler", but if you really need to, here are some tips to at least get it compiled, albeit with a GPF when running the samples.
From Daniel Schmitz (dschmitz@ch.hp.com):
Well, just in case you have users that still have Borland C++ 3.1 AND windows 3.x... src/makefile.bcc Change the Borland version to 3.1. I'm not sure this has any affect. wb_timer.cpp bcc 3.1 does NOT put underscores before timezone or the other variable. msw/makefile.bcc make kept screwing up when recusive making wxstring. It turns out that you pass the command-line option: DEBUG="0" make kept complaining that it couldn't find the target 0. So I modified this makefile to pass: -DDEBUG="0" and it went through wxstring ok. I double checked the command line options being passed to make. They were valid, so there must be a bug in this version of make. wx_setup.h There aren't any libraries that provide the SQL functions. Set the flag USE_ODBC to 0. wx.lib My stupid stupid stupid... copy of tlib absolutely refused to create a library larger than 1MB. It didn't matter what values I gave to the -P option. I could build a 990K library, then try to add one 20K object and it would instantly complain: Out of Memory I have 14MB free for tlib to add that extra object file so I don't think it's a ram limitation. I went around this by splitting wx.lib into 5 libraries, wx1.lib...wx5.lib. Before linking sample programs, I modified their makefiles to link against all of the wx libraries I built. erase f1 f2 f3... The makefile.bcc files in the following contrib directories gave multiple filename patterns to the erase command for the clean targets. This is not allowed. wxstring, gague, itsybits, fafa.
You have a number of switches in compiler configuration that may need adjusting. In order of my own preference:
IDE:
Command line:
DrawBacks: All functions that are exported to Windows must be explicitly declared so, and MakeProcInstance() call is neccessary. (This is done in wxWin, just take care of your own callbacks).
For version 150k you have to uncomment one MakeProcInstance() in src/msw/wx_main.c (or wx_win.c - don't remember exactly). The patch is sent to Julian.
IDE:
Command line:
Drawbacks: All C++ libraries and objects must be compiled with the same settings of this switch or you'll get "undefined symbol" link errors. Put this is in your default configuration file and recompile everything to save yourself from trouble later.
IDE:
Command line:
Drawbacks: you can't run more than one instance of your program anymore. This is architectural flaw in MS-Windows. If you need to, make several copies of your .exe under different names and run one copy of each.
IDE:
Command line:
Drawbacks: Not available with Borland 3.1. You probably wan't be able to modify any of these strings, since they are in code segments. If windows does not prohibit write access to code segments, then this will cause hard to find bugs. (Code segments are marked as discardable and can be thrown away and reloaded from .exe file at any moment). (I did not tried it myself yet).
Some compilers seem to be shipped without libraries such as ddeml.lib, shell.lib, and commdlg.lib. Use implib to generate corresponding .lib files, e.g.
implib commdlg.lib c:\windows\system\commdlg.dll
Yes, if you do it carefully. First of all make sure that your compiler does not make any unreasonable assumptions about stack segment, and better still it makes no assumptions about stack segment at all. Make sure that both the library and your program are compiled this way.
Do not expect wxWindows to be reentrant because MS-Windows is not. Most probably your thread implementation does not use preemptive scheduler, so MS-Windows reentrancy is not a big problem.
Derive your member from "Bool wxApp::OnIdle(void)" and put a pthread_yield() call there. If you use dialogs, take care about yielding to threads while in a dialog.
Yes, Watcom C++ can be used in WIN386 (32-bit) mode and WIN32s mode. However, there seems to be a problem running wxWindows programs compiled in 16-bit mode.
To compile with Watcom in WIN386, set USE_ODBC to 0 in wx_setup.h. All the other settings should work. A fix to allow the ODBC classes to be used with Watcom (similar to that which allows CTL3D to be used) will probably be released shortly.
Don't forget to set the INCLUDE and PATH variables appropriate to the mode of compilation. For WIN386 compilation, these are:
PATH F:\WATCOM\BIN;F:\WATCOM\BINW;F:\WATCOM\BINB;<the rest of your path> SET INCLUDE=F:\WATCOM\H;F:\WATCOM\H\winFor WIN32 (NT) target compilation:
PATH F:\WATCOM\BINNT;F:\WATCOM\BINB;F:\WATCOM\BINW;F:\WATCOM\BIN;<the rest of your path> SET INCLUDE=F:\WATCOM\H;F:\WATCOM\H\NTEdit the file wx/src/makewat.env and set the WATCOM, WXDIR and MODE variables appropriately (see comments).
You will probably want to set up some batch files to switch between settings, if you are targetting more than one platform. If you can't find the BINNT directory, you probably didn't check the Windows NT target option when installing. The naming is confusing, since you're probably not targetting 'genuine NT', but WIN32s.
Under WIN32s (NT) compilation, we unfortunately lose CTL3D and ODBC capabilities. There may be a way of linking with libraries: watch this space. When running the hello.exe demo in WIN386, copying a metafile to the clipboard produces a fairly catastrophic crash (often exiting Windows or hanging completely). The culprit appears to be wxMetaFile::SetClipboard and the calls to GlobalAlloc, GlobalLock and the subsequent memory access. All the other functionality of hello.exe appears to work under Watcom C++, and the crash does not occur in WIN32s mode.
Results with some of the other samples in WIN386 and WIN32s modes:
Borland users have been finding that it's impossible to compile the LEX and YACC-generated parser files in PROLOGIO from wxWindows 1.50. PROLOGIO is required for compiling wxBuilder.
Peter Trattler and Edward Zimmermann have improved PROLOGIO to allow FLEX to be optionally used instead of LEX; see the PROLOGIO manual for more details. If you have FLEX (the default Linux lexical analyser generator), you can generate a lex_yy.c which compiles more cleanly.
LEX and FLEX-generated versions of lex_yy.c are supplied, as lexyy.c and flexyy.c respectively.
FLEX and YACC are freely available for DOS; most major DOS ftp sites should have them.
Remember not to compile lex_yy.c explicitly. It's included by y_tab.c.
In release 1.50 k there's a bug: edit wb_item.cpp, go down to the wxbRadioBox constructor and replace
#ifndef _turbocwith
#ifndef __BORLANDC__
No. Although there is now a Windows 3.1 version of RSXDK which allows limited 32-bit Windows compilation under Windows using DJGPP, it doesn't have enough functionality to be useful for wxWindows. This has been checked out by Arjen Duursma (arjen@capints.uucp).
Yes. Thanks to Keith Garry Boyce, from 1.66E onwards wxWindows supports GNU-WIN32, with a few patches to the compiler headers. See install.txt for more details.
Unfortunately, this is not yet possible. However, an attempt has been made for VC++ 4.0. The following reproduces the file docs/dll.txt.
Attempt to create a DLL of wxWindows using VC++ 4.0
---------------------------------------------------
The wxWindows source has been changed for a nearly (!) successful
attempt to create a DLL out of wxWindows, in order to substantially reduce
executable size (and link time).
Perhaps someone else will be able to fathom what I'm doing wrong.
To compile for DLL
------------------
Edit wx_setup.h and src/msw/makefile.unx and set
MINIMAL_WXWINDOWS_SETUP to 1 in both files.
Compiling library:
> cd c:\wx\src\msw
> nmake -f makefile.nt dll ; Makes c:\wx\lib\wx166.dll/.lib
> nmake -f pch ; Makes dummy.obj and wx.pch for apps
; to use
Compiling samples:
Edit samples/minimal/makefile.nt and set WXUSINGDLL to 1 just before
including ntwxwin.mak.
> nmake -f makefile.nt ; Make minimal.exe
> copy c:\wx\lib\wx166.dll .
> minimal.exe
Similarly for hello.
What goes wrong
---------------
When running minimal.exe (which is a gratifying 80K or so in size),
the button and message do not appear.
On tracing the code, it seems that in SetSize, a call to
GetWindowText to get the message or button label, doesn't work.
It copies zero characters to the buffer. Therefore the size
is miscalculated and the height is zero - so the items don't show.
The extended error code is 120, which means 'This function is
only valid in Win32 mode', according to winerror.h.
The mystery is why this function should not work. Hunting through
on-line help, there is a comment about Set/GetWindowText not working
across applications (but we're not using it across apps) and
something in the Knowledge Base about SetWindowText not working properly
across threads. Nothing very relevant for DLL usage.
When running hello.exe, there's a kernel GPF when calling the
constructor for the subwindow. Unfortunately there's absolutely
no indication of what the error might be caused by.
Notes on making the DLL
-----------------------
I've added a WXDLLEXPORT definition (defined in wx_defs.h) and
sprinkled class and function declarations liberally with this
keyword, as per VC++ documentation. This changes according to
whether the DLL is being made (WXMAKINGDLL defined) or being
used by an app (WXUSINGDLL defined).
For an app to indicate that it's using the DLL version instead
of the statically linked version, you just need to put
WXUSINGDLL=1
in the makefile _before_ you include ntwxwin.mak.
Note that the symbols defined in wb_data.obj remain undefined
when linking with wx166.lib, so I've had to duplicate them
in dummy.cpp, whose object will be linked to the application in order
to conform with precompiled header rules. Perhaps someone can
find a way of eliminating this requirement - possibly the module
is not linked properly because it doesn't have any functions in it?
Similarly, WinMain has to be defined in an object linked statically
to the app, so this is in dummy.cpp too.
If anyone can finish the job, I'll be delighted and will ensure that
future versions of wxWindows will be DLL-friendly, at least for
32-bit VC++.
Good luck!
Julian Smart
2nd October 1996