Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Compiling with GCC


  • Please log in to reply
29 replies to this topic
xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
I have been working, recently, on compiling AHK with GCC. I have noticed a few things...

1.) The includes in stdafx.h that are under "#ifdef _MSC_VER" are important to any compiler, not specifically MSC. "-D _MSC_VER" as a compiler option works well to overcome this.

2.) MSC is much more lenient about implicit casts, with the effect being:

a.) I have to use a lot of const_cast<char*>(code that works in MSC here)
b.) The assign function sh*ts a brick, easily remedied by adding (and somebody please tell me if I'm casting to the wrong type here, I don't know what MSC implicitly casts to):
ResultType Assign(const char aValueToAssign[2]){return Assign((DWORD)(aValueToAssign));}
    ResultType Assign(long int aValueToAssign){Assign((long long int)(aValueToAssign));}
after the prototypes of the Assign functions in var.h

3.) There are some defines/includes needed for GCC that aren't needed for MSC. These I just put in stdafx.h, though they could be added where they are specifically needed.


#include <ctype.h>
#include <olectl.h>

#define __forceinline
#define LLMHF_INJECTED 0x00000001
#define IDCONTINUE 11
#define IDTRYAGAIN 10
#define MIXERCONTROL_CONTROLTYPE_BASS_BOOST     (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 0x00002277)
#define LPLVITEM LPLVITEMW
#define CF_DIBV5 17
#define TreeView_GetCheckState(hwndTV, hti) \
   ((((UINT)(SendMessageA((hwndTV), TVM_GETITEMSTATE, (WPARAM)(hti),  \
                     TVIS_STATEIMAGEMASK))) >> 12) -1)
#define SBARS_TOOLTIPS 0x0800
#define BS_TYPEMASK 0x0000000FL
#define LV_VIEW_TILE 0x0004
#define LVN_HOTTRACK (LVN_FIRST-21)
#define LVN_BEGINSCROLL (LVN_FIRST-80)
#define LVN_ENDSCROLL (LVN_FIRST-81)
#define LVN_MARQUEEBEGIN (LVN_FIRST-56)
#define MIM_BACKGROUND 2
#define MIM_APPLYTOSUBMENUS 0x80000000L

typedef struct tagTVKEYDOWN {
    NMHDR hdr;
    WORD wVKey;
    UINT flags;
} NMTVKEYDOWN, *LPNMTVKEYDOWN;


typedef DWORD *LPCOLORREF;

extern __int64 _strtoi64(const char*, char**, int);
extern __int64 _strtoui64(const char*, char**, int);


4.) MSC uses a different style of inline assembly. All the math functions need to be converted to their c equivalents ("math.h"). Also, can anyone find a non assembly version of the DynaCall function? I would like to make this compilable in MSC and GCC so I can't just convert the assembly from MSC style to GCC style.

5.) GDK+ is not included in GCC. It is a proprietary Microsoft package and requires a genuine copy of windows. Here is a link to the download. At the bottom of the page is a "Files in This Download" section that allows you to bypass the validation, if you know the system architecture you are compiling on. Once you have that file, chose custom and install only the SDK base. This will give you the files you need (All the header files that start with GdiPlus and PopPack.h)

6.) __try and __except seem to be undocumented, as such I have found code to define them for use in gcc. This header file I threw in with the proprietary Microsoft headers and I called it exception.h, after the wine header of the same name (that one didn't work, btw). This file can be found here and I would like to get a hold of the author, if anybody can find a way.

Note: I am only about half way through the conversion of the source, there may be more (or even less) things to include. This is just a basic guide for making most of the errors drop out.

Note2: I am currently compiling with the -w flag (no warnings). I fully expect a billion and one warnings to show up when I use -Wall (all warnings).

Note3: Minor changes to the GdiPlus headers must be made to get this to compile, if you are uncomfortable changing the original files, make a copy as I have done, and define an explicit path to your first header file (GdiPlus.h).

GdiplusEnums.h 534: comment out  (//enum EmfPlusRecordType)
GdiplusEnums.h 538: Comment out EmfPlusRecordType (/*(EmfPlusRecordType*/((n)...)
GdiplusImaging.h 156: PixelFormat PixelFormat; -> INT PixelFormat;
GDiplusHeaders.h 653: friend Graphics; -> friend class Graphics;


Note4: IT WORKS.
<!-- m -->http://www.autohotke...ut ... Gcc.exe<!-- m -->
Source will come when I decide what I have to leave out for legal reasons (I'm looking at you, GDI+)

A subversion repository has been set up for the source. It can be found at <!-- m -->svn://autohotkey.net/xx3nvyxx/3nvySVN<!-- m -->

Known Bugs:
DllCall does not work
A command prompt window runs with any executed script.
expressions do not work (var := 1 + 1, msgbox, % 1 + 1, etc.)


Method:
I prefer using an ide for such a large project, and especially when it's not my code. My personal preference is code::blocks, so I will describe the method I used for that. If you intend to get it yourself, be sure to get the version with mingw, as it is needed for compiling.

The first step is to create a project. Name it anything you like, it doesn't really matter that much. That will make a folder where it expects all the project files to be.

Copy all the source files into the project folder and the modified GDI+ headers into the MSC_HEADERS folder.

In code::blocks, there is a Management pane on the left hand side, that shows Workspace and under that shows your project name. Right-click on the project name and select add files recursively, then choose the project folder. This will add all the sources to your project.

Right click it again, and select build options. On the Linker Settings tab there is a button for adding libraries to link with the project. All of these libraries are in the mingw\lib folder:

libcomctl32.a
libwinmm.a
libgdi32.a
libole32.a
liboleaut32.a
libcomdlg32.a
libversion.a
libws2_32.a
libmsvcr70.a
libuuid.a

and this one is in YOUR_PROJECT_DIRECTORY\lib
GdiPlus.lib

After that, you should be able to "build and run" and watch all the warnings fly by.


~~~~

Edit 1: Request for new DynaCall function.
Edit 2: Fixed a typo.
Edit 3: Function is actually DynaCall(), originally posted just the return type.
Edit 4: Added to the list of changes to stdafx.h, added #5.
Edit 5: Incorrect link. The File I gave was a link to a dll, not the header file. Added Note3.
Edit6: Added new included header file.
Edit7: Added note4 and "Known Bugs" section.
Edit8: Added a link to the executable
Edit9: Added another known bug
Edit10: Added SVN repos
Edit11: Added changes to GDI+ headers
Edit12: Added method for compilation
Edit13: Forgot a library
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Do you expect the result to be smaller or faster? AHK won't work on any other platform than Windows, so it is usually the best to use a (free) MS compiler. They should know the best how to use their own API.

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
I expect it to conform to the C++ standard as much as possible. I want to convert the code to a form that will allow the most cross-compilation (thereby making it useful for those who just want it to work with MSC). Once I have achieved this I will begin the long and difficult process of making it work on other OSes. Or attempting to at least. I figure making it compile in a widely used open source compiler is an important step in reaching this goal.
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

Oberon
  • Members
  • 442 posts
  • Last active: Jul 03 2008 11:34 PM
  • Joined: 18 Feb 2008
gcc has a good track record of outperforming other compilers especially with arithmetic functions. I look forward to your developments xx3nvyxx, perhaps with a few modification AutoHotkey could be better adapted to Wine/Gtk for improved Linux interoperability.

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
Thank you for your support. That is almost exactly my intent. In the process of making it cross-platform I wish to convert the gui code to GTK.
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

  • Guests
  • Last active:
  • Joined: --

...I wish to convert the gui code to GTK.

...would you consider wxWidgets instead of GTK?

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005

...would you consider wxWidgets instead of GTK?


I might. I have to achieve my first goal before I will even think about how I will modify it.

Currently I am getting hung up on the DynaCall function which I am told cannot be done in anything but inline assembly. I will have to find some kind of replacement, even if it's just a "If this is being compiled with Intel syntax use this code, otherwise use this AT&T syntax code." (Even that would be a major pain to implement)

Also, in the file script_expression.cpp there are a lot of goto jumps that gcc complains about. (You aren't allowed to jump over initialization of certain variables)
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

erictheturtle
  • Members
  • 101 posts
  • Last active: Sep 04 2011 02:07 PM
  • Joined: 27 Jun 2007

Currently I am getting hung up on the DynaCall function which I am told cannot be done in anything but inline assembly. I will have to find some kind of replacement, even if it's just a "If this is being compiled with Intel syntax use this code, otherwise use this AT&T syntax code." (Even that would be a major pain to implement)

I agree that there's really no way around using some inline assembly, or equivalent, since you have to fiddle with the stack.

Some time ago I worked on creating an abstract "functor" design. I successfully managed to dynamically create function pointers that would in turn call another function with one additional parameter on the stack (being the context, of course). I got it working with both stdcall and cdecl.

My goal was to use the least amount of assembly. I didn't use inline assembly, but instead compiled the assembly and put the byte-codes into a small array. I also tried to fiddle with the stack in the least possible way. As such I think it should work regardless of compiler.

Of course replacing the current DynaCall with this approach probably means re-implementing the whole thing. But if you're interested, PM me (with an email or whatnot) and I'll send you what I have.

Also, I fully approve of this thread.
-m35

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
That sounds great. Unfortunately in order to make this work in as many scenarios as possible I am forced to use more abstract methods than byte codes. If I only had to worry about intel architecture it would be a simple task to take it to the base level, however not everybody uses intel. With that in mind, using byte codes is a sure way to generate incompatibilities.

However, I would still like to see it, if only for my own furthering of knowledge. You can send it to xx3nvyxx [AT] gmail [dot] com. (Take that, spam bots!)
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
ONE MORE TO GO!

Now I just have the file script_expression.cpp to fix. I have changed the inline assembly from Intel style to AT&T style. In order to maintain cross compilation, I have included each in blocks like so:

#ifdef _MSC_VER

//MSC specific code here (intel syntax assembly)

#else

//gcc specific code here (AT&T syntax assembly)

#endif

So that's all taken care of. I've also added some code I found to handle the seemingly undocumented __try and __except blocks.

If anybody wants to help, they can help me sort through goto errors in the file I mentioned above.
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
It compiles. Great. Now if it would just link. The code I took to replace the __try and __catch wouldn't link without the associated c file (well duh, right?) but that file has compiler errors.

So I get to choose between compiler errors and linking errors.
Now the world has gone to bed,
Darkness won't engulf my head,
I can see by infra-red,
How I hate the night.

Now I lay me down to sleep,
Try to count electric sheep,
Sweet dream wishes you can keep,
How I hate the night.

  • Guests
  • Last active:
  • Joined: --
Bump :wink:
Just to let you know there is continuing interest in this project.

Good coding!

  • Guests
  • Last active:
  • Joined: --
Bump!

Maybe someone who can help will see this.

The masses of 'guest' posters are still waiting! ;)

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
it would be nice to use code coverage with gcc.
there is no free msvc code coverage.

anxious
  • Guests
  • Last active:
  • Joined: --
Is there any news/progress on this worthy project :?: