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
It compiles. It links. It works.

Upon Titan's suggestion I removed the dynacall function. For those who don't know, that is what handles the dll calls. After building it complained about a missing msvcr70.dll, so I found a copy and put it in the folder with the executable. I ran a simple "msgbox, 1" script and it worked.
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.

danalec
  • Members
  • 225 posts
  • Last active: Oct 03 2014 05:31 PM
  • Joined: 20 Jul 2006
YAYZ!

*pops a champagne*

source please :D

                                  [ profile ]


polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Awesome! I don't have msvcr70.dll on my Vista install so I copied and renamed msvcr71.dll. Expressions crash the script, but everything else seems to be fine.

I'll also be waiting for your source code ;)

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
I filled the MSC_HEADERS folder with the required gdiplus, popPack.h and exception.h files.
then in cygwin I did
gcc -w AutoHotkey.cpp

I get a bunch of errors about undeclared function stri_cmp
as well as these:
util.h: In function `char* StrToTitleCase(char*)':
util.h:60: error: `isspace' undeclared (first use this function)
util.h:60: error: (Each undeclared identifier is reported only once
ction it appears in.)
util.h: In function `bool IsHex(char*)':
util.h:313: error: `isxdigit' undeclared (first use this function)
util.h: In function `long long int ATOI64(char*)':
util.h:339: error: `_strtoi64' undeclared (first use this function)
util.h:339: error: `_atoi64' undeclared (first use this function)
util.h: In function `long long unsigned int ATOU64(char*)':
util.h:344: error: `_strtoui64' undeclared (first use this function)
util.h: In function `double ATOF(char*)':
util.h:373: error: `_strtoi64' undeclared (first use this function)
util.h: In function `char* ITOA(int, char*)':
util.h:388: error: `_itoa' undeclared (first use this function)
util.h: In function `char* ITOA64(long long int, char*)':
util.h:405: error: `_i64toa' undeclared (first use this function)
util.h: In function `char* UTOA(long unsigned int, char*)':
util.h:419: error: `_ultoa' undeclared (first use this function)

any suggestions?
Thanks

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
I'm not sure if it will compile on cygwin gcc. It's still too windows based to use cygwin. I would recommend trying with mingw, at least until I get around to testing compilation on cygwin.
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.

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
ok, i tried again with mingw,
g++ -w AutoHotkey.cpp
and got these errors:
do you have a makefile?
In file included from var.h:23,
                 from script.h:24,
                 from hotkey.h:21,
                 from hook.h:21,
                 from globaldata.h:20,
                 from AutoHotkey.cpp:18:
util.h: In function 'char* StrToTitleCase(char*)':
util.h:53: error: cast from 'CHAR*' to 'char' loses precision
util.h:57: error: cast from 'CHAR*' to 'char' loses precision
In file included from script.h:24,
                 from hotkey.h:21,
                 from hook.h:21,
                 from globaldata.h:20,
                 from AutoHotkey.cpp:18:
var.h: In constructor 'Var::Var(char*, void*, bool)':
var.h:353: error: cast from 'void*' to 'VarTypeType' loses precision
In file included from hotkey.h:21,
                 from hook.h:21,
                 from globaldata.h:20,
                 from AutoHotkey.cpp:18:
script.h: At global scope:
script.h:537: error: extra qualification 'Line::' on member 'PerformLoop'
script.h:539: error: extra qualification 'Line::' on member 'PerformLoopFilePattern'
script.h:543: error: extra qualification 'Line::' on member 'PerformLoopParseCSV'
script.h:1906: error: extra qualification 'ScriptTimer::' on member 'Disable'
In file included from globaldata.h:20,
                 from AutoHotkey.cpp:18:
hook.h:205: error: extra qualification 'input_type::' on member 'input_type'

the exception.h file i made created from the link you gave
#ifndef SEH_EXCEPTIONS_H
#define SEH_EXCEPTIONS_H

#include <setjmp.h>
#include <windows.h>

#ifdef __cplusplus
extern "C" {
#endif

struct __seh_data
{
struct __seh_data *prev;
jmp_buf env;
EXCEPTION_RECORD erec;
CONTEXT ctx;
struct _EXCEPTION_POINTERS ep;
};

#define GetExceptionCode() (__ehd.erec.ExceptionCode)
#define GetExceptionInformation() (&__ehd.ep)

int __seh_init (void);
void __seh_push_handler (struct __seh_data *d);
void __seh_pop_handler (struct __seh_data *d);
void __seh_restore_context (CONTEXT* cxt);

#define __TRY \
do { \
struct __seh_data __ehd; \
memset (&__ehd, 0, sizeof (__ehd)); \
volatile int __in_else = 1; \
volatile int __in_finally = 0; \
volatile int __have_finally = 0; \
(void)__have_finally; \
(void)__in_finally; \
while (1) /* 1 */ \
if (!__in_else) /* 2 */ { \
do {

#define __EXCEPT(...) \
} while(0); \
__seh_pop_handler (&__ehd); \
break; \
} else /* 2 */ { \
__in_else = 0; \
__seh_push_handler (&__ehd); \
if (setjmp(__ehd.env)) /* 3 */ { \
int filter_res; \
__ehd.ep.ContextRecord = &__ehd.ctx; \
__ehd.ep.ExceptionRecord = &__ehd.erec; \
filter_res = (__VA_ARGS__); \
if (filter_res == EXCEPTION_CONTINUE_EXECUTION) \
__seh_restore_context (&__ehd.ctx); \
__seh_pop_handler(&__ehd); \
if (filter_res == EXCEPTION_CONTINUE_SEARCH) \
__seh_restore_context (&__ehd.ctx); \
else if (filter_res == EXCEPTION_EXECUTE_HANDLER) \
do {

#define __FINALLY \
} while(0); \
__seh_pop_handler(&__ehd); \
__in_finally = 1; \
__in_else = 1; \
} else /* 2 */ { \
__in_else = 0; \
__have_finally = 1; \
if (!__in_finally) \
__seh_push_handler (&__ehd); \
if (__in_finally || setjmp(__ehd.env)) /* 3 */ { \
__seh_pop_handler (&__ehd); \
do {

#define __END_TRY \
} while (0); \
if (__have_finally && !__in_finally) \
__seh_restore_context (&__ehd.ctx); \
break /* 1 */; \
} /* 3 */ \
} /* 2 */ \
} while (0);

#ifdef __cplusplus
}
#endif

#endif
#include <windows.h>

#include "exceptions.h"

#define UNUSED __attribute__((unused))

static DWORD handler_tls = TLS_OUT_OF_INDEXES;

void
__seh_push_handler (struct __seh_data *d)
{
d->prev = TlsGetValue (handler_tls);
TlsSetValue (handler_tls, d);
}

void
__seh_pop_handler (struct __seh_data *d)
{
TlsSetValue (handler_tls, d->prev);
}

int
__seh_init (void)
{
handler_tls = TlsAlloc ();
if (handler_tls == TLS_OUT_OF_INDEXES)
/* GetLastError for more info. */
return -1;

return 0;
}

struct _DISPATCHER_CONTEXT;

/* Mark it as used, as we register it for use in the __asm__ block below. */
static EXCEPTION_DISPOSITION
eh_handler (struct _EXCEPTION_RECORD *,
void *,
struct _CONTEXT *,
struct _DISPATCHER_CONTEXT *)
__attribute__((used));

static EXCEPTION_DISPOSITION
eh_handler (struct _EXCEPTION_RECORD *ExceptionRecord UNUSED,
void *EstablisherFrame UNUSED,
struct _CONTEXT *ContextRecord,
struct _DISPATCHER_CONTEXT *DispatcherContext UNUSED)
{
struct __seh_data *d = TlsGetValue (handler_tls);

if (d != NULL)
{
d->ctx = *ContextRecord;
d->erec = *ExceptionRecord;
ContextRecord->Pc = (DWORD)longjmp;
ContextRecord->R0 = (DWORD)d->env;
ContextRecord->R1 = 1;
return ExceptionContinueExecution;
}

/* Unexpected, perhaps there is another handler installed. */
return ExceptionContinueSearch;
}

__asm__(
/* Data to be placed at start of .text section. The .init section
is placed before .text with the default linker script. */
"\t.section .init\n"
"\t.word eh_handler\n"
"\t.word 0\n"
"start_eh_text:\n"

/* Data for exception handler. */
"\t.section .pdata\n"
"\t.word start_eh_text\n"
/* max of 22 bits for number of instructions. */
"\t.word 0xc0000002 | (0xFFFFF << 8)\n"

/* Switch back. */
"\t.text\n"
);
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#include "exceptions.h"

static void
bad ()
{
int *zero;
int result;

zero = 0;
result = *zero + *zero;
}

static int
filter (unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
puts("in filter.");

printf("Exception: Code:%x Flags:%x Addr:%x "
"SP:%x LR:%x R0:%x R1:%x R2:%x R3:%x R4:%x R5:%x R12:%x Pc:%x\n\n",
code,
(unsigned)ep->ExceptionRecord->ExceptionFlags,
(unsigned)ep->ExceptionRecord->ExceptionAddress,
(unsigned)ep->ContextRecord->Sp,
(unsigned)ep->ContextRecord->Lr,
(unsigned)ep->ContextRecord->R0,
(unsigned)ep->ContextRecord->R1,
(unsigned)ep->ContextRecord->R2,
(unsigned)ep->ContextRecord->R3,
(unsigned)ep->ContextRecord->R4,
(unsigned)ep->ContextRecord->R5,
(unsigned)ep->ContextRecord->R12,
(unsigned)ep->ContextRecord->Pc
);

if (code == EXCEPTION_ACCESS_VIOLATION)
{
puts("caught AV as expected.\n");
return EXCEPTION_EXECUTE_HANDLER;
}

puts("didn't catch AV, unexpected.\n");
return EXCEPTION_CONTINUE_SEARCH;
}

#define __try __TRY
#define __finally __FINALLY
#define __except __EXCEPT
#define __endtry __END_TRY

static void
test_eh (int i)
{
/* The ; at the end of endtry isn't strictly need, but I put it to
keep emacs happy. */

printf ("test 1\n");

printf ("arg i = %d\n", i);

__TRY
{
__TRY
{
bad();
}
__EXCEPT (filter (GetExceptionCode (), GetExceptionInformation ()))
{
printf ("except block 1 reached\n");
}
__END_TRY;
}
__EXCEPT (EXCEPTION_EXECUTE_HANDLER)
{
printf ("except block 2 reached ????\n");
}
__END_TRY;

printf ("test 2\n");

__TRY
{
__TRY
{
printf ("bad try block\n");

bad();

printf ("bad try block ended ?\n");
}
__EXCEPT (EXCEPTION_CONTINUE_SEARCH)
{
printf ("in cont search block!?!\n");
}
__END_TRY;
}
__EXCEPT (EXCEPTION_EXECUTE_HANDLER)
{
printf ("except block 2 reached\n");
}
__END_TRY;

printf ("arg i = %d\n", i);

__try
{
__try
{
printf ("bad try block\n");

bad();

printf ("bad try block ended ?\n");
}
__finally
{
printf ("in finally\n");
}
__endtry;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf ("except block 2 reached\n");
}
__endtry;

printf ("arg i = %d\n", i);

printf ("tests done\n");
}

int
main ()
{
__seh_init ();

test_eh (123);

return 0;
}
/* ANSI concatenation macros. */
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a##b

#ifndef __USER_LABEL_PREFIX__
#error __USER_LABEL_PREFIX__ not defined
#endif

#define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)

#ifdef __ELF__
#define TYPE(x) .type SYM(x),function
#define SIZE(x) .size SYM(x), . - SYM(x)
#else
#define TYPE(x) .def SYM(x); .scl 2; .type 32; .endef
#define SIZE(x)
#endif
what are the minor changes to gdiplus.h you mention that are required?


xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
Oh, I see your problem. Ignore the exceptions.h and exceptions.[whatever else]. Also, comment out the body of the DynaCall function. Because the exception handler never really worked, I was forced to ditch DynaCall.

Edit: Don't I have the modified source on the svn? E.g. with dynacall commented out and a clear lack of need for expressins.h?
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.

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
I am still having problems compiling with mingw on windows.
Can you tell how exactly you are compiling?

xx3nvyxx
  • Members
  • 93 posts
  • Last active: Jan 21 2016 09:33 AM
  • Joined: 05 Sep 2005
Updated the first page with the build method I use. I hope people can figure it out from that.
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.

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
Hi followed the instructions for using codeblocks.
Still getting these same 8 errors:
Compiling: AutoHotkey.cpp
gccahk\/util.h: In function 'char* StrToTitleCase(char*)':
gccahk\/util.h:53: error: cast from 'CHAR*' to 'char' loses precision
gccahk\/util.h:57: error: cast from 'CHAR*' to 'char' loses precision
gccahk\/var.h: In constructor 'Var::Var(char*, void*, bool)':
gccahk\/var.h:353: error: cast from 'void*' to 'VarTypeType' loses precision
gccahk\/script.h: At global scope:
gccahk\/script.h:537: error: extra qualification 'Line::' on member 'PerformLoop'
gccahk\/script.h:539: error: extra qualification 'Line::' on member 'PerformLoopFilePattern'
gccahk\/script.h:543: error: extra qualification 'Line::' on member 'PerformLoopParseCSV'
gccahk\/script.h:1906: error: extra qualification 'ScriptTimer::' on member 'Disable'
gccahk\/hook.h:205: error: extra qualification 'input_type::' on member 'input_type'
Process terminated with status 1 (0 minutes, 1 seconds)
8 errors, 0 warnings

when i fix these, i get more downstream errors...

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
I was finally able to understand xx3nvyxx's instructions.
had to make a few more changes to get it to work
removed a bunch of #defines from gdiplus that force compiler warnings / errors
GdiPlusEnums.h:543:// enum EmfPlusRecordType;   # ahkgcc
GdiPlusEnums.h:548:// # ahkgcc
GdiPlusImaging.h:163:    INT PixelFormat; // PixelFormat # ahkgcc changed type
GdiplusFlat.h:2347:                     ImageCodecInfo *decoders); // ahkgcc removed  __out_bcount(size)
GdiplusFlat.h:2355:                    ImageCodecInfo *encoders); // ahkgcc removed  __out_bcount(size)
GdiplusFlat.h:2388:        LPWSTR    name,  // ahkgcc removed __out_ecount(LF_FACESIZE)
GdiplusFontFamily.h:123:     LPWSTR    name, // ahkgcc removed __out_ecount(LF_FACESIZE)
GdiplusFontFamily.h:124:     WCHAR                     language // ahkgcc replaced    IN LANGID    with WCHAR
GdiplusHeaders.h:196:         LPWSTR    name,  // ahkgcc removed __out_ecount(LF_FACESIZE)
GdiplusHeaders.h:197:        WCHAR                        language = 0 // ahkgcc replaced IN LANGID    with WCHAR
GdiplusHeaders.h:707:  friend class Graphics;  // # ahkgcc  although line numbers didn't match
GdiplusTypes.h:744:    BYTE* Types;  // ahkgcc removed  __field_ecount_opt(Count)

// removed mscvr70 dependency: libmsvcr70.a

// in util.h, added
#define _strtoi64 strtoll // ahkgcc to remove msvcrt dep
#define _strtoui64 strtoull  // ahkgcc to remove msvcrt dep
also using git instead of subversion: source :D
Thanks xx3nvyxx !!

wiseley
  • Members
  • 29 posts
  • Last active: Sep 30 2011 11:12 PM
  • Joined: 22 Apr 2009
This is great news, tinku99 :D
so you mean it's possible to compile a full functionable ahk with codeBlock?
thanks for your great contributions

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007

so you mean it's possible to compile a full functionable ahk with codeBlock?

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.)

These issues still apply. I will try to address them.

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007

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)

you can just move the initialization of those variables to the top of the function.
The additional complication was that these were pseudoinitializations as the variable in question was just an alias and the initialization was masked in a preprocessor macro. (references).
So I just used a regular variable instead of an alias...
download
changes to script_expression.cpp: diff

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
I just compiled the dynacall function by itself with some minor modification with msvc, and then link it with the rest of ahkmingw... source
Minor issues:
A_LastError is not updated... will address it later.
Should probably link statically rather than dynamically... will change at some point.