It is currently Mon Oct 20, 2014 4:38 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Feb 18, 2011 2:19 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
A good few months ago, I decided to upgrade my MinGW installation to the latest version, as I noticed that it was now using GCC 4. This caused me a lot of problems as BeebAsm would no longer build, and eventually I gave up, and started to use Visual C++ 2010 Express to build it (which works fine!).

Now, today, out of curiosity, I decided to try again. The latest version of MinGW is using GCC 4.5.2, and I was pleased to see that (after correcting a few missing header includes in the source code) BeebAsm compiles and links fine. The problem is that it doesn't run - instead it bombs out instantly with:
BeebAsm wrote:
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

Now, the most striking difference between GCC 4 and older versions is that the C/C++ runtime code has been moved into a DLL, when before it was statically linked. I have a feeling that this crash is probably due to it not dynamically linking with the runtime, but I can't really be sure. The DLL I assume it needs is accessible from the Windows PATH (although I even tried moving it into the same directory as the executable, with no success).

Various sources out there in interwebland suggest linking the project with the switches -static-libstdc++ and -static-libgcc, but these don't appear to be supported by the GCC 4.5.2 port in MinGW. So basically, I'm stuck on this one.

Has anyone used GCC 4 in MinGW with any success? Does any of this sound familiar? I haven't used MinGW for a while now (and this is largely the reason why), but it's a shame, as I always liked the fact that it was available on pretty much every platform, and felt like a good way to compile cross-platform code.


Top
 
PostPosted: Fri Feb 18, 2011 3:06 pm 
Offline
 Profile

Joined: Sat Sep 04, 2010 5:28 pm
Posts: 92
I use mingw for a selection of small programs (all my saga compression stuff was compiled with mingw). The version I have installed is running GCC 4.5.2

One major difference though is I normally program in C rather than C++. If I compile a program with MinGW and then open it in PE Explorer, it only uses kernel32.dll and msvcrt.dll (both located in c:\windows\system32). I'm also only running Win XP.

I've tried compiling BeebASM, but I can't get it to link - this may be my set up though.

Is this just BeebASM crashing or can you compile anything else and run it successfully, e.g. try a simple:
Code:
#include <stdio.h>
void main(void)
{
   int i;
   for (i=0; i < 20; i++)
      printf("%d\n",i);
}


Top
 
PostPosted: Fri Feb 18, 2011 4:28 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Hmmm, the plot thickens. The executable *does* run and exits gracefully if launched, for example, with no parameters.

The problem seems to be that exceptions are not being caught properly by the code, and I have no idea why. This worked fine in previous versions. BeebAsm uses a lot of exceptions (it actually relies on them as part of the code flow when an unknown symbol occurs in the first pass, which admittedly is horrible - I don't really know what I was thinking when I wrote it, although I did write it quickly...).

When assembling the demo.asm program bundled with BeebAsm, an unknown symbol exception is thrown by LineParser::GetValue(), which is then not being caught by the LineParser::EvaluateExpression() method. The error is the typical one you get when a C++ exception isn't being caught by the code and instead is propagated all the way up to the top.

I have no idea on this - have you or anyone ever experienced oddities with GCC 4.5.2 regarding exception handling? Google doesn't give me anything, and, as hard as I try, I don't see any error in my code (other than that this is a horrible way of handling unknown symbols!). I've also knocked up a small test program with some simple exception handling which compiles and runs fine, although obviously not of the complexity of BeebAsm.

I'm also sure that the runtime C++ libs are being dynamically linked, because if I rename the file, it pops up an error when I run BeebAsm.

I'm baffled. Has some default switch maybe changed in GCC 4.5.2 which disables run-time type info, or something else which might stop it from correctly identifying the type of the exception and matching it to the catch() clause?


Top
 
PostPosted: Sat Feb 19, 2011 2:30 pm 
Offline
User avatar
 WWW  Profile

Joined: Thu Jan 10, 2008 7:45 pm
Posts: 472
Location: Treddle's Wharf, Chigley
If you've read the arse I made of trying to compile B-Em, you'll realise I know bugger all about this, but this rings a vague bell with something about a bug someone posted on a list I read a while back. Have you tried compiling the code in debug level and seeing if the exception caught then?


Top
 
PostPosted: Sat Feb 19, 2011 6:26 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Yeah, I tried compiling without optimisations, and still had the same problem.

I found a bug in Bugzilla for GCC 4.5 - 'Throw not being caught' - which appears to be the problem I have. The workaround he suggested didn't seem to work for me though, and worse of all, this seems to be a platform-specific bug. I'm going to have a little play and see if I can isolate precisely the problem.

But, so far, I'd have to say that MinGW+GCC 4 seems to be rather unreliable. If I get any further, I'll update you here!


Top
 
PostPosted: Sat Feb 19, 2011 6:45 pm 
Offline
 Profile

Joined: Sat Sep 04, 2010 5:28 pm
Posts: 92
I've just tried it again to try and get it to link. I just used the simple:
Code:
g++ -o beebasmw *.cpp


Then copied over some beebasm files and ran it. It worked perfectly!


Top
 
PostPosted: Sat Feb 19, 2011 7:01 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Yeah, I also noticed that letting the compiler suite do all the building work, it would work ok. But I really don't like the solution, because I like the dependencies to be built correctly, and prefer to have more control over the build process.

Anyway, for now I've cracked it - although I don't entirely understand the solution. Adding -static to the linker flags (LDFLAGS) in the Makefile makes it statically link with the runtime libs, and all works fine again. Curiously, if I try to force it to dynamically link by using -shared, it produces a binary which Windows won't even run.

I'm not particularly impressed with the fact that the resulting executable is 739k in size (I would expect it to be much less). GCC 4 clearly is quite bloaty, and I think it's still better to use MS Visual Studio to compile native C++ apps for Windows - I will release a new version of BeebAsm sometime soon with a couple of bugfixes, and a Visual Studio project included in the package. An XCode project could probably be added there too for all the MacOS folks.

Anyway, all's well that ends well. If anyone can expand on exactly *why* this is fixing it, I'd be interested to hear theories!


Top
 
PostPosted: Sun Feb 20, 2011 5:25 am 
Offline
User avatar
 WWW  Profile

Joined: Thu Jan 10, 2008 7:45 pm
Posts: 472
Location: Treddle's Wharf, Chigley
RichTW wrote:
I'm not particularly impressed with the fact that the resulting executable is 739k in size

You're not the only one, but there do seem to be some work arounds:

http://www.cplusplus.com/forum/windows/3430/


Top
 
PostPosted: Wed Feb 23, 2011 2:35 am 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
I tested this out tonight - adding the -static parameter to the linker flags (LDFLAGS) in the Makefile stops the build working under Linux (gcc 4.4.5). If this is a MinGW-specific flag as it appears to be, perhaps it should be included in the Makefile based on a $OSTYPE conditional? This would require MinGW users to build with

Code:
OSTYPE=$OSTYPE make code

But that's already how Linux users have to do it (if they use the Linux 1.04 patch I just added to the wiki), to stop the executable being named with Windows conventions. As the "default" environment will continue to be MSVC++ on Windows, I don't think expecting MinGW users to specify $OSTYPE as well is much of a big deal, and we should try to keep the releases building on Linux and Mac OS X as well.

I spent a lot of time tonight trying to find a better way of doing a conditional in a Makefile based on the operating system but I didn't find anything better than $OSTYPE, which doesn't seem to be passed to make from the environment automatically. Bleugh.

Sam.


Top
 
PostPosted: Thu Feb 24, 2011 9:18 pm 
Offline
User avatar
 WWW  Profile

Joined: Thu Apr 03, 2008 2:49 pm
Posts: 277
Location: Antarctica
Samwise wrote:
I spent a lot of time tonight trying to find a better way of doing a conditional in a Makefile based on the operating system but I didn't find anything better than $OSTYPE, which doesn't seem to be passed to make from the environment automatically. Bleugh.

Probably got the wrong end of the stick here, but in my Mountain Panic makefile I do:
Code:
ifeq ("$(OS)","Windows_NT")
BEEBASM    := "c:/dev/beebasm/beebasm.exe"
else
BEEBASM    := "/Users/Dave/development/beebasm/beebasm.exe"
endif


Top
 
PostPosted: Thu Feb 24, 2011 10:18 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Unfortunately, that variable doesn't exist on any other platforms, only Windows. So all you're doing there is identifying whether the platform is Windows or not - not actually identifying whether it's Linux, Max OS X etc.

$OSTYPE is the equivalent variable that should work across platforms - but by default, the shells don't usually pass that to make, which is annoying.

Code:
OSTYPE=$OSTYPE make code

is the closest I could come to an option that will work across platforms.

Well, without involving ./configure - I assume that would normally handle this kind of issue for larger projects, or setting the variable in the Makefile itself and expecting the user to uncomment the appropriate setting.

Sam.


Top
 
PostPosted: Sat Feb 26, 2011 11:00 pm 
Offline
User avatar
 WWW  Profile

Joined: Thu Apr 03, 2008 2:49 pm
Posts: 277
Location: Antarctica
OK, so keep the windows bit in, then in the else clause, perhaps something like this?

Reports 'Darwin' here on OS X.


Top
 
PostPosted: Sun Feb 27, 2011 12:33 am 
Offline
User avatar
 WWW  Profile

Joined: Mon Mar 15, 2010 2:28 pm
Posts: 42
Location: Minehead, Somerset (UK)
Have a look back from from last year but didn't I already go through this? Sometime around about this time last year? I never ended up submitting anything as there really wasn't much interest at the time and I ended up distracted after the VCF.

I certainly remember going through the whole needing to differ the make between OS's

[EDIT] OS X is using GCC 4.2.1 incidentally.


Top
 
PostPosted: Sun Feb 27, 2011 1:07 am 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
@DaveF, that could work. I've checked it with MinGW and Linux and that seems to work. If it works for Macs, that could be the answer.

@MartinW. I did go over your old posts, but I think you were just proposing ppl should manually edit the makefile or pass it in as a parameter, which is effectively what was being proposed here. Unless I missed another alternative?

If DaveF's suggestion works on all three supported platforms, that would be preferable, I assume. Can anyone check on Mac?

Sam.


Top
 
PostPosted: Sun Feb 27, 2011 10:29 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
I just tried this; my Cygwin installation provides uname (it is not native to Windows), and the return value I get is 'CYGWIN_NT-6.1-WOW64' which seems far too specific to be of very much use.

According to the make documentation, environment variables are exported into the make environment automatically, so I don't understand why $(OSTYPE) wasn't visible in the Makefile under Linux/MacOS. Of course, in Windows the environment variable isn't defined, so this won't work.

Anyway, as ever, the easiest way to deal with this, is to insist without ambiguity that the platform type is passed on the make command line. I will add code which tries to deduce it automatically from any imported OSTYPE variable, but otherwise it'll be:
Code:
make all PLATFORM=mingw
...or whatever.

If nothing is passed, and nothing could be deduced, it'll abort with the help message, indicating the possible platforms.


Top
 
PostPosted: Sun Feb 27, 2011 10:59 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Just to add that uname -s reports 'Cygwin' on my PC, which is far more useful. I don't have MSYS installed with MinGW, but I assume that were I to have that rather than Cygwin, it'd probably report 'MSYS' or 'MinGW'. Anyone care to try it?


Top
 
PostPosted: Sun Feb 27, 2011 11:20 am 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Makefile code:
Code:
   echo $(shell uname)
   echo $(shell uname -s)
   exit;


MinGW output in msys console:
Code:
echo MINGW32_NT-6.1
MINGW32_NT-6.1
echo MINGW32_NT-6.1
MINGW32_NT-6.1
exit;


Output in Linux:
Code:
echo Linux
Linux
echo Linux
Linux
exit;


Rich,

Gnu Make will, as you say, use any variables which are passed to it by the shell - but by default OSTYPE isn't one of the variables that the shell exports. To pass it through to make you either have to run an "export OSTYPE" first, or use the "OSTYPE=$OSTYPE make code" syntax.

Sam.


Top
 
PostPosted: Sun Feb 27, 2011 12:51 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Samwise wrote:
OSTYPE=$OSTYPE make code

This seems like a strange Linuxism to me - does
Quote:
make code OSTYPE=$OSTYPE
work equally well?

I have TortoiseHg running fine btw... I will commit a GCC 4 compliant build with target platform selection in the makefile a little later on! Then, I'll add a few extra features and bugfixes - maybe I'll roll the Basic tokenisation functionality into BeebAsm after all; it is quite easy to integrate Thomas's code, and I am *just about* sold on it... :D


Top
 
PostPosted: Sun Feb 27, 2011 2:03 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
RichTW wrote:
This seems like a strange Linuxism to me - does
Quote:
make code OSTYPE=$OSTYPE
work equally well?

Nothing to do with Linux per se - it's a shell thing, which is why it works on MinGW etc. too. Writing it the above way works just as well.

RichTW wrote:
I have TortoiseHg running fine btw... I will commit a GCC 4 compliant build with target platform selection in the makefile a little later on!

Great stuff. I don't think it really matters how you choose to do it, so long as the instructions are clear and we have a way to put in the OS-specific changes. There's not really been any special requirements for Linux so far, assuming you add the stuff Murray first described, so most of that will be Martin's Mac contributions.

RichTW wrote:
Then, I'll add a few extra features and bugfixes - maybe I'll roll the Basic tokenisation functionality into BeebAsm after all; it is quite easy to integrate Thomas's code, and I am *just about* sold on it... :D

Aye ... I have spent a bit more time on the separate binary, but not quite cracked adding a non-BASIC file yet which is what I wanted to get working before posting it. I'm afraid I'm snowed under atm at work and with preparations for when I'm away. Might not get round to it until I get back now ...

Sam.


Top
 
PostPosted: Sun Feb 27, 2011 2:05 pm 
Offline
 Profile

Joined: Sat Sep 04, 2010 5:28 pm
Posts: 92
RichTW wrote:
Samwise wrote:
OSTYPE=$OSTYPE make code

This seems like a strange Linuxism to me - does
Quote:
make code OSTYPE=$OSTYPE
work equally well?


It's a feature of shell from way back in the bourne shell days (the late 1970s): if you define a variable, you can include a following command by only using a space. This is because the parsing of variables is done by the shell and then removed from the command line before its parsed again and sent to the command.

Doing the second will not work as OSTYPE=$OSTYPE will be passed to the make command (actually it'll be "make code OSTYPE=<contents of $OSTYPE>")

But, OSTYPE=$OSTYPE probably won't work as it'll just set OSTYPE to the contents of itself; you probably just need to export it first.


Top
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron