$VER: SPOT'S PORTING FOR DUMMIES 1.7.8
======================================


INDEX
=====

00) Quick Reference
01) Why should I read this? I can't code!
02) History
03) What to port
04) Getting the SDK up to date
     -Essentials
     -Languages
     -Misc
     -Misc Linklibs
05) The basics
06) How to configure
     -Newlib or Clib2?
     -For newlib
     -For clib
     -For cygnix
     -Configuring a link library
     -Tricky configures
     -A small hint
     -Explanation of some GCC flags
07) Common errors that occur when configuring
08) Converting unix path's to Amiga path's
09) Defines
10) Understanding error messages
11) Errors and how to fix them
     -Common errors
     -Not so commong errors
12) Tips and tricks
13) Creating a Makefile by hand
14) Converting a Windows makefile into an AmigaOS makefile
     -Fixing the sources
15) Creating a GUI using Emperor (Alpha!)
16) Compiling SDL/GL apps
17) Adding support for AmiUpdate
18) Help me!
19) Contact me
20) Thanks


00) QUICK REFERENCE 
===================

For lazy geezers like me, I use these lines a lot and I don't want to 
wade through the guide to find them all the time, if you are new to this 
guide, just skip this chapter for now.


NEWLIB CONFIGURE QUICK REFERENCE

Finetuned for SDL projects.
sh ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix" LDFLAGS=-mcrt=newlib

Finetuned for SDL projects with old configure scripts, see COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING.
CC=gcc CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix" LDFLAGS=-mcrt=newlib ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib 

For generic non-SDL projects.
sh ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lauto -lunix" LDFLAGS=-mcrt=newlib

For generic non-SDL projects with old configure scripts, see COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING.
CC=gcc CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lauto -lunix" LDFLAGS=-mcrt=newlib ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib 

For link libraries with headers in SDK:Local/common/include/
sh ./configure --disable-shared --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib --includedir=/SDK/Local/common/include CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS=-lauto LDFLAGS=-mcrt=newlib

For link libraries with headers in SDK:Local/newlib/include/
sh ./configure --disable-shared --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib --includedir=/SDK/Local/newlib/include CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS=-lauto LDFLAGS=-mcrt=newlib

For old link libraries with headers in SDK:Local/newlib/include/ (see COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING) 
CC=gcc CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lauto -lunix" LDFLAGS=-mcrt=newlib ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib --includedir=/SDK/Local/newlib/include


CLIB2 CONFIGURE QUICK REFERENCE

Finetuned for SDL projects. (Type 'SH PATH=/SDK/Local/clib2/bin:$PATH' first!)
sh ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix" LDFLAGS=-mcrt=clib2

Finetuned for SDL projects with old configure scripts. See COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING. (type PATH=/SDK/Local/clib2/bin:$PATH from ABC-Shell first!)
CC=gcc CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix" LDFLAGS=-mcrt=clib2 ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib 

For generic non-SDL projects. (Type 'sh PATH=/SDK/Local/clib2/bin:$PATH' first!)
sh ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2

For generic non-SDL projects with old configure scripts. See COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING. (type sh PATH=/SDK/Local/clib2/bin:$PATH from ABC-Shell first!)
CC=gcc CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2 ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib 

For link libraries with headers in SDK:Local/common/include/ (Type 'sh PATH=/SDK/Local/clib2/bin:$PATH' first!)
sh ./configure --disable-shared --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib --includedir=/SDK/Local/common/include CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS=-lauto LDFLAGS=-mcrt=clib2

For link libraries with headers in SDK:Local/clib2/include/ (use this one if you want to make a clib2 only version) (Type 'sh PATH=/SDK/Local/clib2/bin:$PATH' first!)
sh ./configure --disable-shared --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib --includedir=/SDK/Local/clib2/include CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS=-lauto LDFLAGS=-mcrt=clib2

For old link libraries with headers in SDK:Local/common/include/ (See COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING) (Type 'sh PATH=/SDK/Local/clib2/bin:$PATH' first!)
CC=gcc CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2 ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib --includedir=/SDK/Local/common/include


COMPILING SDL PROJECTS THE HARDCORE WAY WITHOUT MAKEFILES (Use ABC-Shell)

g++ -mcrt=newlib -Wall -O2 -I/sdk/local/newlib/include/SDL -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -c *.cpp
g++ -mcrt=newlib -Wall -O2 *.o -mcrt=newlib -lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix -o test

gcc -mcrt=newlib -Wall -O2 -I/sdk/local/newlib/include/SDL -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -c *.c
gcc -mcrt=newlib -Wall -O2 *.o -mcrt=newlib -lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix -o test


COMPILING ALLEGRO PROJECTS THE HARDCORE WAY WITHOUT MAKEFILES (Use ABC-Shell)

g++ -mcrt=newlib -Wall -O2 -Wno-deprecated-declarations -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -c *.cpp
g++ -mcrt=newlib -Wall -O2 *.o -lal2xsai -lalmp3 -lalogg -laldumb -lalfont -lldpng -lpng -lz -laljpgalleg -lalfblend -lalagup -lallegro -lpthread -lstdc++ -lauto -lunix -o test

gcc -mcrt=newlib -Wall -O2 -Wno-deprecated-declarations -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -c *.c
gcc -mcrt=newlib -Wall -O2 *.o -lal2xsai -lalmp3 -lalogg -laldumb -lalfont -lldpng -lpng -lz -laljpgalleg -lalfblend -lalagup -lallegro -lpthread -lstdc++ -lauto -lunix -o test


01) WHY SHOULD I READ THIS? I CAN'T CODE!
=========================================

Well, the sad fact is that, neither can I! :) I am just a stubborn geezer!
And look at me now... 300+ uploads to http://os4depot.net compiling 
multiplatform stuff for AmigaOS 4.0 isn't THAT hard, c'mon! If I can do it,
you can do it too! You'll jump up and down screaming when you manage to
compile your first SDL app, I did! To my defence I have to say that I had
to figure out a lot of the process the hard way! :P
/Spot


02) HISTORY
===========

Version 1.7.8

  Added a new common error.

Version 1.7.7

  Added a new common error.

Version 1.7.6

  Added a new not so common error, thanx to Zerohero for the help with the 
  solution!

Version 1.7.5

  Added a new (advanced) chapter written by Rigo, on how to deal with AmiUpdate.
  Thanx for letting me use it Rigo!

Version 1.7.4 

  Minor tweaks to the configure lines.

Version 1.7.3 

  Added a new error and a solution submitted by Blacky_Stardust. Thanx a lot man!

Version 1.7.2

  Added a tip on how to add AmigaOS version strings to your exes to the tips and tricks chapter.

Version 1.7.1

  Added configure lines finetuned for SDL projects to the quick reference section.
  Thid should help newbies get rid of linking errors and save me from wasting time on makefile editing.
  Dunno why I didn't do this before.

  Cleaned up the Quick Reference guide, I hope it is much clearer now.

Version 1.7.0

  Added -ltiff to the CFLAGS, as my latest compile of SDL_Image needs and supports it.

Version 1.6.9

  Added a new common error to chapter 07.

Version 1.6.8

  Added some URL's to the 'What to Port' chapter.

Version 1.6.7 

  Added a really weird 'not so common error' that costed me some hair! Grrr!

Version 1.6.6 

  Added a new subchapter 'Newlib or Clib2?'
  Added some clarifications to the quick references. Thanx to Lio for the feedback!
  Added some new stuff to 'Tips and Tricks'
  Added a 'not so common error'

Version 1.6.5

  Added a new 'not so common error'

Version 1.6.4

  Added a new chapter 'Compiling SDL/GL apps'
  Added a new tip to the 'Common errors that can occur when configuring' chapter.

Version 1.6.3

  Added a new chapter: 'Converting a Windows makefile into an AmigaOS makefile'

Version 1.6.2

  Extended the common error section with a small guide on how to find
  out what header is missing.

Version 1.6.1

  Misc small changes and additional info 'backported' from the AROS 'port'
  of this guide.

Version 1.6.0

  Added a guide on how to make GUI's using Emperor.
  Added lots of small things that I can't remember.

Version 1.5.3 

  Added a tip on Fullscreen modes in SDL apps/games. Thanks Lio.
  Added some quick references related to Allegro compiling. Woooot? Already? ;)

Version 1.5.2 

  Corrected some small things related to SDL_Mixer 

Version 1.5.1

  Added SVN to tips and tricks

Version 1.5

  Fixed a typo. I had writen -lpng -lpng, when it should be -lpng -ljpeg.
  Thanx to Raziel for the report.

  Added a new chapter: History

  Added a new chapter: Getting your SDK up to date

  Added a new chapter: The basics

  Added a new chapter: Configuring linklibs

  Added a new chapter: Quick Reference

  Added more common errors

  Defines section updated

  Common errors section updated

  Corrections to the configure lines. Thanx HNL!

  Corrections to the example makefile. Thanx Booger!

  A lot of small changes that I can't remember.

  Corrected the cygnix config line.


03) What to port?
=================

Look what additional packages are required for the software you want to port. 
You cannot simply port when GUI toolkits like GTK or QT are needed. 
Only software which runs under a console can be ported directly.
When you want to port games, look if they use libSDL. 
Avoid software which requires OpenGL.

Here's some good sources for open source games and apps using SDL or Allegro;

http://www.happypenguin.org
http://www.allegro.cc
http://www.libsdl.org

04) GETTING THE SDK UP TO DATE
==============================

Lots of parts of the SDK have been updated since the last official
release, so install the following libs to get an up to date SDK.
This is especially important for the SDL libs, as the ones included
in the SDK are buggy. 


ESSENTIALS

  ABC-Shell - Amiga Bourne Compatible Shell
  http://www.os4depot.net/share/development/utility/abc-shell.lha

  GNU make including parallel compile
  http://www.os4depot.net/share/development/utility/make-bin.lha

  Diffutils - file comparison tools
  http://www.os4depot.net/share/development/utility/diffutils-hnl.lha

  m4 - Unix macro processor
  http://www.os4depot.net/share/development/misc/m4.lha

  GNU core utilities
  http://www.os4depot.net/share/development/utility/coreutils-bin.lha

  Texinfo - GNU documentation system
  http://www.os4depot.net/share/development/misc/texinfo-bin.lha

  clib2
  http://sourceforge.net/project/showfiles.php?group_id=115224

LANGUAGES

  Free Pascal Compiler
  http://os4depot.net/share/development/language/fpc.lha

  Perl 5.8.5
  http://www.os4depot.net/share/development/language/perl.tar.bz2

  Lua - powerful embeddable programming language
  http://os4depot.net/share/development/language/lua.lha

MISC

  Boost C++ libraries
  http://os4depot.net/share/development/library/boost.lha

  Expat C library for parsing XML
  http://os4depot.net/share/development/library/expat-ppc.lha

  GNU termcap library
  http://os4depot.net/share/development/library/termcap.lha

MISC LINKLIBS

  LibCurl - the multiprotocol file transfer library
  http://os4depot.net/share/development/library/libcurl.lha

  libFreetype2
  http://www.os4depot.net/share/library/misc/freetype2.lha

  libJPEG
  http://www.rcdrummond.net/amiga/libjpeg-6b.lha

  libODE - ODE and Opcode
  http://os4depot.net/share/development/library/ode.tgz

  libOGG
  http://www.rcdrummond.net/amiga/libogg-1.1.lha

  libOpenSSL - OpenSSL: The Open Source toolkit for SSL/TLS
  http://os4depot.net/share/development/library/libopenssl.lha

  libPNG
  http://www.rcdrummond.net/amiga/libpng-1.2.6.lha

  libSDL_gfx
  http://os4depot.net/share/development/library/sdl_gfx.lha

  libSDL_perl
  http://os4depot.net/share/development/library/sdl_perl.tar.bz2

  libSDL_ttf and libSDL_net
  http://os4depot.net/share/development/library/sdl_ttf_net.lha

  libVorbis
  http://www.rcdrummond.net/amiga/libvorbis-1.0.1.lha

  libXML2 - The XML C parser and toolkit of Gnome
  http://os4depot.net/share/development/library/libxml2.lha

  zlib
  http://www.rcdrummond.net/amiga/zlib-1.2.1.lha


05) THE BASICS
==============

The first thing you do is to check how to build your project.
If there is a file called configure in the root directory of the archive, it means 
you'll have to configure it for your platform.

Start ABC-Shell by typing 'sh' in your shell, and configure it. See the next 
chapter for a description on how to do that.

After the project is properly configured it's time to roll out the compiler. 
Start building your project by typing 'GMAKE'. 

However, if there was no file called Configure, look for a file called  
Makefile. Edit it to suit AmigaOS 4.0 and build the project with 'GMAKE'.

If everything compiled and linked you are ready to test your port. A very common
problem is that it won't find it's datafiles, and crash. Fix the path's as 
described in the path-fixing chapter, and try to run it again. 

If you've compiled a link library a 'GMAKE INSTALL' is recommended, as it will 
copy all neeeded files to the right places.

OK, you're done now, upload it to os4depot and aminet!


06) HOW TO CONFIGURE
====================

NEWLIB OR CLIB2?

A Clib is a library with standard functions used by all apps written in C.
Newlib is the official C library for OS4, so always try to configure for newlib first.
It is also a shared library, which CLib2 isn't, so your binaries will be smaller.
If you get errors when compiling, you could try using CLib2 as it has some unix functions that
are missing in Newlib. 

FOR NEWLIB
./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lauto -lunix" LDFLAGS=-mcrt=newlib

Use the same line if you are going to compile a linklibrary, but if you want to
compile exclusively for newlib or clib2 change /common/ to clib2 or newlib.

FOR CLIB2
If you want to configure for CLIB2, first fix the PATH, start ABC-Shell by
typing 'sh' in Amiga-Shell and then type; PATH=/SDK/Local/clib2/bin:$PATH

./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2

Use the same line if you are going to compile a linklibrary, but if you want to
compile exclusively for newlib or clib2 change /common/ to clib2 or newlib.

FOR CYGNIX
CFLAGS="-O2 -mcrt=clib2 -I/usr/X11R6.3/include/ -I/usr/include" LDFLAGS="-L/usr/X11R6.3/lib -laos4util -L/usr/lib -lunix -lnet -lamiga -lm -lauto" CPPFLAGS="-O2 -I/usr/X11R6.3/include -I/usr/local/include -I/usr/include" LIBS="-L/usr/X11R6.3/lib -laos4util -L/usr/local/lib -L/usr/lib -lunix -lnet -lm -lamiga -lauto" ./configure

CONFIGURING A LINK LIBRARY
When configuring a linklib we need an extra option, --includedir=
this is to specify where to install the header files. Use /common/ if you are 
going to compile the linklib for both clib2 and newlib. Change it to /newlib/ or /clib2/ if you
are going to compile for just one of them. It's recommended to make versions for both when
possible. Here's the example configure lines;

NEWLIB with headers in .../common/include/ (Use this if you intend to compile for both newlib and clib2.)
  ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib --includedir=/SDK/Local/common/include CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL" CXXFLAGS=-mcrt=newlib LIBS=-lauto LDFLAGS=-mcrt=newlib

NEWLIB with headers in .../newlib/include/ (Use this if you intend to compile for newlib only.)
  ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib --includedir=/SDK/Local/newlib/include CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL" CXXFLAGS=-mcrt=newlib LIBS=-lauto LDFLAGS=-mcrt=newlib

CLIB2 with headers in  .../common/include/ (Use this if you intend to compile for both clib2 and newlib.)
  ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib --includedir=/SDK/Local/common/include CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL" CXXFLAGS=-mcrt=clib2 LIBS=-lauto LDFLAGS=-mcrt=clib2

CLIB2 with headers in   .../clib2/include/ (Use this if you intend to compile for clib2 only.)
  ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib --includedir=/SDK/Local/clib2/include CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL" CXXFLAGS=-mcrt=clib2 LIBS=-lauto LDFLAGS=-mcrt=clib2


TRICKY CONFIGURES
Some configure scripts just don't want to do what you want them to, here's some real world examples,
from when I have had to tweak a configure script by issuing some flags;

Xmoto configured without Automake (notice the amigaos path fix: --srcdir=/Scene/Coding/xmoto-0.2.4);
  ./configure --disable-dependency-tracking --srcdir=/Scene/Coding/xmoto-0.2.4  --datadir=/PROGDIR/ --bindir=/SDK/Local/C --prefix=/PROGDIR/  CFLAGS=-mcrt=clib2 CXXFLAGS="-mcrt=clib2 -DMINIGL" LIBS="-mcrt=clib2 -lGL -lGLU -llua -lode -lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix" --with-sdl-prefix=/sdk/local/clib2
And some manual changes to the Xmoto Makefile;
  remove: $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) ... from LINK
  remove: $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) ... from CXXLINK

libXML:
./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -DLIBXML_DOTTED_VERSION=2.6.26 -DLIBXML_TEST_VERSION=20626 -DLIBXML_VERSION=20626 -DLIBXML_VERSION_STRING=20626" CXXFLAGS=-mcrt=clib2 LIBS=-lunix LDFLAGS=-mcrt=clib2

GNGEO: Notice the UNIX path fix at the end (pkgdatadir=/PROGDIR/data)
./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2 pkgdatadir=/PROGDIR/data


A SMALL HINT
It makes sense to write the configure statement to a text file. 
This way we can easily re-run it like this 'sh mybuildscript.sh'

But before we re-run the script we have to do 'gmake distclean' or 'rm -f config.cache' (the unix way) 
or simply 'delete config.cache' (the Amiga way) in order to reset the configuration process.

EXPLANATION OF SOME GCC FLAGS
LDLAGS="-lunix"
  This enables Linux semantics for paths. Linux applications often use absolute paths to their data files. 
  But an absolute Linux path like /usr/local/app means for AmigaOS to go one level up, then go into the usr directory.

--prefix=/PROGDIR

Prefixes all paths with /PROGDIR. Together with the -lunix option this allows to use Linux paths during compiling and
AmigaOS paths when running the exe.


07) COMMON ERRORS THAT CAN OCCUR WHEN CONFIGURING
=================================================

It's a VERY good idea to ALWAYS add this argument to your configure line;
  --srcdir=/DH1/Path/To/MyProject/
It cures a LOT of configure related problems.

I get errors like this;
  configure: warning: CFLAGS=-mcrt=newlib: invalid host type

Solution;
  The configure script is probably old, don't worry, we can still use it,
  but we have to issue the commands a little bit differently. Here's how;

FOR NEWLIB (Old Configure script)
  CC=gcc CFLAGS=-mcrt=newlib CPPFLAGS="-mcrt=newlib -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=newlib LIBS="-lauto -lunix" LDFLAGS=-mcrt=newlib ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/newlib/lib 

FOR CLIB2 (Old Configure script)
  CC=gcc CFLAGS=-mcrt=clib2 CPPFLAGS="-mcrt=clib2 -DMINIGL -D__USE_INLINE__" CXXFLAGS=-mcrt=clib2 LIBS="-lauto -lunix" LDFLAGS=-mcrt=clib2 ./configure --disable-dependency-tracking --bindir=/SDK/Local/C --prefix=/SDK/Local --libdir=/SDK/Local/clib2/lib 


I get errors like this;
  configure: error: C compiler cannot create executables

Solution;
  AmigaOS doesn't support the -pipe and -s flags.
  Remove the -pipe and -s flags from the configure script. (The file called 'Configure').


I get errors with libpng and libtiff;
  checking for png_create_read_struct in -lpng... no
  checking for TIFFClientOpen in -ltiff... no

Solution;
  Edit the configure script, add -lz after -lpng and -ltiff. 


I get errors like this;
  checking for IMG_Load in -lSDL_image... no

Solution;
  We are linking with static libraries, and we need to be tell exactly what
  to link in. Locate this line in the configure script;

LIBS="-lSDL_image $LIBS"

SDL_image depends on some more libraries to function correctly,
add them like this;

LIBS="-lSDL_image -ltiff -lpng -ljpeg -lz $LIBS"


I get errors like this;
  checking for Mix_OpenAudio in -lSDL_mixer... no

Solution;
  We are linking with static libraries, and we need to tell exactly what
  to link in. Locate this line in the configure script;

LIBS="-lSDL_mixer $LIBS"

  SDL_mixer depends on some more libraries to function correctly,
  add them like this;

LIBS="-lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ $LIBS"


The same thing also often happens when configure is searching for 
SDL_ttf, and you know why by now. We need to specify some more libs that 
SDL_ttf depends on. It needs -lfreetype and -lz. I will leave the 
rest to you as an excersize.


If you have added the needed dependencies to the configure script, and 
it still doesn't work it can be due missing files in the SDK.
freetype-config and smpeg-config are missing in the archives available
on http://www.os4depot.net. I compiled my libs by myself to get the 
missing files, but hopefully the authors of the AmigaOS 4.0 versions
will notice and fix these issues.

Another common problem are wrong paths in the .la files found in
SDK:Local/newlib/lib or SDK:Local/clib2/lib. 
Check your .la files to see if they are configured correctly, locate
the following lines;

# Directory that this library needs to be installed in:
libdir='/SDK/Local/newlib/lib'

This one is set up correctly, notice libdir='/SDK/Local...'
if it's set to '/USR/Local...' it's wrong. 

If it still doesn't work, and you are sure that you have the library
installed, try to remove the whole section where it checks 
for the failing library in the configure file.
This is not recommended, but if there is no other way...


Now you should be ready to build your project. When porting unix apps 
always type GMAKE. MAKE is for Amiga projects only.


08) CONVERTING UNIX PATH'S TO AMIGA PATHS
=========================================


How do I convert UNIX paths into AmigaDOS paths?

Exchange getenv("HOME"); to "/PROGDIR/"

Examples;
org: strcpy(path, getenv("HOME"));
new: strcpy(path, "/PROGDIR/");

org: strcpy(home,getenv("HOME"));
new: strcpy(home,"/PROGDIR/");

old: sprintf(rc_dir, "%s/.gngeo/romrc.d", getenv("HOME"));
new: sprintf(rc_dir, "%sgngeo/romrc.d", "/PROGDIR/");

Notice that I removed "/." in the last example.

Paths to datadirs are often set during the configure process by issuing 
-DDATADIR= if this is the case set it to -DDATADIR=/PROGDIR/
It's also common that the datadir are set in the makefiles locate DATADIR=
and change it to DATADIR=/PROGDIR/


08) DEFINES
===========

Defines are often set in config.h, if something is configured wrongly, you can
often change it here by using #DEFINE and #UNDEF.

A define example that considers all AmigaOS flavours;

  #ifdef __AMIGA__
	  blah blah blah
  #else 
          blah blah blah
  #endif

A define example that only considers AmigaOS 4.0;

  #ifdef __amigaos4__
	  blah blah blah
  #else 
          blah blah blah
  #endif

A define example, that considers BeOS and AmigaOS 4.0;

  #if !defined(__BEOS__) && !defined(__amigaos4__)

An example of a more complex #ifdef

  #ifdef GP2X
	char *gngeo_dir="save/";
  #elif defined __amiga__
	char *gngeo_dir="/PROGDIR/save/";
  #else
	char *gngeo_dir=get_gngeo_dir();
  #endif


10) UNDERSTANDING ERROR MESSAGES
================================

Error:
No return statement in function returning non-void 

  What does it really mean?
  There is no return in a function that needs a return.


Error:
Control reaches end of non-void function

  What does it really mean?
  it is reaching the end of a function that needs a return, but there is no return.

Error:
May be used uninitialized in this function

  What does it really mean?
  The variable is not initialized. 

Error:
Warning: implicit declaration of function 'blah blah'

  What does it really mean?
  You need to include a header.


11) ERRORS AND HOW TO FIX THEM
==============================

COMMON ERRORS

If you can't find the answer here, it's usually a good idea to
google the error message, for example, enter 
warning: implicit declaration of function 'strlen' and in many
cases the sollution will be there for you.

In general, when you get an error of this type;

warning: implicit declaration of function 'strlen'
warning: incompatible implicit declaration of built-in function 'strlen'

It means that the sources are missing an include. To find out which include
it wants, open a shell and CD to SDK: then do;
"grep -R strlen *" in this case you will get a LOT of output, so having KingCon
installed is a good idea. 99% of the info printed is irrelevant, what you are 
looking for is a header that includes the function the source wants.
Includes are stored in SDK:Local/Newlib/Include, SDK:Local/Common/Include,
SDK:Local/Clib2/Include, SDK:newlib/Include/ and SDK:Clib2/Include.
So only check the hits found in those directories.
For the lazy bunch, i've included the most common ones here;

warning: incompatible implicit declaration of built-in function 'exit'
warning: incompatible implicit declaration of built-in function 'abort'
  solution: #include <stdlib.h>

warning: implicit declaration of function 'strlen'
warning: incompatible implicit declaration of built-in function 'strlen'
  solution: #include <string.h>

warning: implicit declaration of function 'memcpy'
warning: incompatible implicit declaration of built-in function 'memcpy'
  solution: #include <string.h>

error: memory.h: No such file or directory
  solution: #include <string.h>

error: malloc.h: No such file or directory
  solution: #include <stdlib.h>

warning: incompatible implicit declaration of built-in function 'printf'
  solution: #include <stdio.h>

error: 'int64_t' undeclared (first use in this function)
  solution: #include <stdint.h>

warning: implicit declaration of function 'srandom'
warning: implicit declaration of function 'random'

  solution:
  We don't have random() and srandom() in neither clib2 or newlib.
  You "could" use rand() and srand() instead they are not totally compatible,
  but it should work.

  One way to do it is to manually edit the sources and replac srandom and random
  with srand and rand. Another way to do it is to; #define srandom srand in the
  source.

warning: implicit declaration of function 'MyRemove'
  solution: #define MyRemove Remove

error: 'sqrtl' was not declared in this scope
  solution: #define sqrtl           sqrt

Fullscreen modes doesn't work in your newly ported SDL game?
  solution: try replacing SDL_HWSURFACE with SDL_SWSURFACE.

error: conversion from 'float' to non-scalar type 'fix' requested
  solution: #include <math.h>

error: In file included from SDK:newlib/include/pthread.h:2,
                  from tools.h:52,
                  from bonus.c:30:
 SDK:local/common/include/pthread.h:39: error: redefinition of 'struct timespec'
 In file included from bonus.c:42:
 options_panel.h:64: error: redefinition of 'struct option'

If a struct is defined in a source code that already exists in your dev headers but it is defined
completely different, rename the struct in the source code to something else and change all 
references to it in the source code.

Example:

Defined in SDK sys/time.h:
  struct timeval {
  	unsigned long tv_secs;
	unsigned long tv_micro;
  };


Defined in source code WRONG.H:
  struct timeval {
	unsigned char something;
	signed short something_else;
  };


In source code CLEAR.C:
  timeval hereitis;


This would give a struct redefinition error.

Solution:
  Rename the struct in wrong.h to some other name, timeval2 for example.
  and change the reference in clear.c to match the rename ( change to timeval2 hereitis; )


The working example would look like this;

WRONG.H;
  struct timeval2 {
	unsigned char something;
	signed short something_else;
  };

CLEAR.C;
  timeval2 hereitis;


NOT SO COMMON ERRORS

I will put sollutions to not so common errors here, that I've 
managed to solve. Partly as a reminder to myself, but also as
it might be handy for you. Here we go!

If you get an error similiar to this one;
../include/xmpi.h:55: error: conflicting types for 'uint32'
SDK:include/include_h/exec/types.h:94: error: previous declaration of 'uint32' was here

check the mentioned line in xmpi.h

it looks like this;
typedef unsigned int uint32;

It's clashing with a typedef in the SDK.
To solve this, let's have a look at the other lines close to that one in xmpi.h;

typedef signed char int8;
typedef signed short int int16;
typedef signed int int32;
typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned int uint32;

We don't want to typedef these, as they are already present in our SDK in exec/types.h,
so what we do is to make AOS4 ignore these lines and include <exec/types.h> like this;

#ifdef __amigaos4__ 
#include <exec/types.h> 
#include <stdlib.h>
#else 
typedef signed char int8;
typedef signed short int int16;
typedef signed int int32;
typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned int uint32;
#endif


If you get a requester stating; 'Unknown/unsupported Reloc' when you start 
your newly linked exe, and a message in shell stating something like this; 
'syntax error: `((' unexpected' then check the makefiles for '-fPIC' and remove it.

error: array bound forbidden after parenthesized type-id

  solution: The guilty line looks something like this;
	frames = new(BITMAP*)[number_of_frames];
  remove the paranteses, so that it looks something like this;
	frames = new BITMAP*[number_of_frames];

error: stray '\26' in program
  solution: There's an single space on the last line, remove it.

error: expected primary-expression before '=' token
  solution: in this case, a space needed to be removed.
  original line:
            if ( i > = 320 )
  changed line:
            if ( i >= 320 )

12) TIPS AND TRICKS
===================

Add this line to your S:shell-startup to get easier access to this
guide;
Alias dummy multiview DH1:path/to/SpotsPortingForDummies.txt 

If you want to do the same for ABC-Shell, add this line to
SDK:Data/abc-shell/variables;
alias dummy="multiview DH1:path/to/SpotsPortingForDummies.txt"

Now, whenever you are in AmigaShell or ABC-Shell just type dummy
and hit enter, and you have the guide in your face, cut and paste away!


How do I search for text strings using GREP?
  From ABC-Shell type;
  grep -R "I am looking for this" *

How do I make a DIFF file with my changes?
  From ABC-Shell type;
  diff originalfile.cpp mychangedfile.cpp >./originalfile.patch

My executeable is crashing, how do I debug it?
  You can use Snoopy to find out what your application tries to do.
  It's VERY common that the app doesn't find a file that it needs.
  Check the section about fixing UNIX path's to fix it.

  In the Grim Reaper, click generate stack trace under the Stack Trace tab.
  Now you'll see a lot of numbers and things.

  Now use addr2line to find out where in the source the crash occured.

  Here's an example;
  addr2line -e xmoto.exe 0x39c48

How do I use Python?
  Assign python: to your python dir, and then add it to your path from
  abc-shell: PATH=$PATH:/python

How do I redirect GCC warnings and errors to a text file?
  gmake 2>/ram/warnings.txt

How do I make a tar.gz archive out of my source dir?
  tar czvf myarchive.tar.gz mysources/

How do I fetch a source when all I have is an URL like this one? svn://svn.72dpiarmy.com/smw
  install Subversion aka SVN and type this in shell; 
  svn checkout svn://svn.72dpiarmy.com/smw

How do I redirect GCC warnings and errors to a text file?
  gmake 2>warnings.txt

How do I add AmigaOS version strings to my binaries?
  Add this code to main.cpp 

#ifdef __amigaos4__
const char *version_tag = "$VER: xxxxxx 1.0 (01.01.2007)";
#endif


13) CREATING A MAKEFILE BY HAND
===============================

AN EXAMPLE MAKEFILE
  this makefile could be used if the build system is a mess and you want to
  simplify it a bit, alter it to fit your needs.
  Usually you only need to modify an existing makefile, and add -mcrt=newlib or
  -mcrt=clib2, add these include paths;
  -I/sdk/local/newlib/include/SDL -I/sdk/local/common/include/SDL
  and add some linklibraries.

  Here's an explanation of what the flags does.
 
  CC      - the name of the C compiler executeable 
  CXX     - the name of the C++ compiler executeable
  RM      - the name of the delete command
  STRIP   - the name of the strip command (used to remove debug data from exe files)
  CFLAGS  - tells the compiler where to find the includes and what clib to use etc.
            specify -mcrt=newlib or -mcrt=clib2 here.
  LDFLAGS - tells the compiler what link libraries to include etc. 
            specify -mcrt=newlib or -mcrt=clib2 here too, aswell as the other needed
            linklibs depending on what you are compiling.
  OBJS    - The compiler (GCC/G++) compiles object files (#?.o) from your .C or .CPP
            files that are later linked together to become an exe file.
            Specify the object file names here.
  OUTPUT  - The name of the final exe file.

---cut-here--------------------------------------------------------------------

CC      = gcc -mcrt=newlib
CXX     = g++ -mcrt=newlib
RM      = rm
STRIP   = strip
CFLAGS	= -mcrt=newlib -Wall -O2 -I/sdk/local/newlib/include/SDL -I/sdk/local/common/include/SDL 
LDFLAGS	= -mcrt=newlib -lSDL_gfx -lSDL_net -lSDL_image -ltiff -lpng -ljpeg -lz -lSDL_mixer -lsmpeg -lm -lvorbisfile -lvorbis -logg -lstdc++ -lSDL_ttf -lfreetype -lz -lsdlmain -lsdl -lauto -lpthread -lm -lunix
OBJS	= a.o b.o c.o
OUTPUT	= test.exe

all: $(OBJS)
		$(CXX) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(OUTPUT) 

main.o:		main.cpp main.h 
		$(CXX) $(CFLAGS) -c main.cpp

---cut-here--------------------------------------------------------------------


14) CONVERTING A WINDOWS MAKEFILE INTO AN AMIGA MAKEFILE
========================================================

When compiling an Allegro game for example, it often comes with a makefile for Windows, and obviously
no makefile for AmigaOS. That's where you come in.

I'll guide you through it step by step. The game used in the example is called Pikzels. 
Download it here, if you like; http://www.allegro.cc/files/depot/505/PikselzFinal.zip, extract it and
load pikselzfinal/source/makefile.win into your favourite editor.

You'll notice that it uses Windows line breaks, every other line is blank, which makes it harder to
overview. If you are using CED you can fix that by marking everything and selecting 'Strip CR marked'
in the Cut/Paste menu. No you should have a nicer layout to work with.

The first thing we notice are these two lines;

CPP  = g++.exe
CC   = gcc.exe

We have to get rid of the Windows extensions and tell GCC to use Newlib, like this;

CPP  = g++ -mcrt=newlib
CC   = gcc -mcrt=newlib

Good, now GCC will be found. On to the next two lines;

WINDRES = windres.exe
RES  = ../Obj/ErkleLnD_private.res

I am not sure what windres does, I guess it's related to the windows build environment.
We don't need it anyway. Remove those lines completely.

On to the next line;
OBJ  = ../Obj/Main.o ../Obj/erkMap.o ../Obj/erkTile.o ../Obj/erkTileType.o ../Obj/erkBmpGen.o ../Obj/erkUnit.o ../Obj/erkTTHive.o ../Obj/erkTTTrainer.o ../Obj/erkCommand.o ../Obj/erkCmdGo.o ../Obj/erkCmdClear.o ../Obj/erkCmdTrainer.o ../Obj/erkCmdHive.o ../Obj/erkTTThorns.o ../Obj/erkCmdThorns.o ../Obj/erkAI.o $(RES)

Notice the $(RES) thingie at the end? It tries to fetch the parameters from the 
"RES  = ../Obj/ErkleLnD_private.res" line that we removed. Not good. Remove $(RES) from that
line, and also from the other lines where it occurs, in this case, it only occurs on Line 6 and 7.

Those two lines shall look like this now;
OBJ  = ../Obj/Main.o ../Obj/erkMap.o ../Obj/erkTile.o ../Obj/erkTileType.o ../Obj/erkBmpGen.o ../Obj/erkUnit.o ../Obj/erkTTHive.o ../Obj/erkTTTrainer.o ../Obj/erkCommand.o ../Obj/erkCmdGo.o ../Obj/erkCmdClear.o ../Obj/erkCmdTrainer.o ../Obj/erkCmdHive.o ../Obj/erkTTThorns.o ../Obj/erkCmdThorns.o ../Obj/erkAI.o 
LINKOBJ  = ../Obj/Main.o ../Obj/erkMap.o ../Obj/erkTile.o ../Obj/erkTileType.o ../Obj/erkBmpGen.o ../Obj/erkUnit.o ../Obj/erkTTHive.o ../Obj/erkTTTrainer.o ../Obj/erkCommand.o ../Obj/erkCmdGo.o ../Obj/erkCmdClear.o ../Obj/erkCmdTrainer.o ../Obj/erkCmdHive.o ../Obj/erkTTThorns.o ../Obj/erkCmdThorns.o ../Obj/erkAI.o 

On to the next line;
LIBS =  -L"lib" -lalleg -mwindows -lalleg  

This is where the libs to be used are specified. We don't need some of it. -mwindows has to go. -L"lib" too.
I am a bit lazy, so I usually copy/paste my line from this guide, that has all allegro libs in it. The ones 
that aren't needed won't get used anyway. So make it look like this;
LIBS = -mcrt=newlib -lalmp3 -laldumb -lalfont -lalfblend -lalagup -lallegro -lpthread -lstdc++ -lauto -lunix

As I said, most of these aren't used by this game, but it doesn't matter. As GCC will just ignore them.
Notice the -mcrt=newlib part, don't forget it, as it tells GCC to use Newlib when linking.

On to the next two lines;
INCS =  -I"include"  -I"../include" 
CXXINCS =  -I"lib/gcc-lib/mingw32/3.3.1/include"  -I"include/c++/3.3.1/backward"  -I"include/c++/3.3.1/mingw32"  -I"include/c++/3.3.1"  -I"include"  -I"H:/Common/Include"  -I"H:/Libs/Lua/include"  -I"../include" 

These lines tell GCC where to look for the needed includes that we specified on the LIBS line.
The includes on the INCS = line are project specific, these are the includes for the game. We need those.
The ones on the next line are windows specific. We don't need those.

This is an allegro project, so we type the paths to our allegro includes, and add the game specific 
includes at the end;

INCS    = -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -I"include"  -I"../include" 
CXXINCS = -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -I"include"  -I"../include" 

I usually put the inclued path's on both those lines, just to make sure they get used.

On to the next line;
BIN      = ../ErkleLnD.exe

Change the windows path to an AmigaOS path like this;
BIN      = ErkleLnD.exe

Do the same for these lines;
all: all-before ../ErkleLnD.exe all-after
	$(CPP) $(LINKOBJ) -o "ErkleLnD.exe" $(LIBS)

make them look like this;
(Line 16) all: all-before ErkleLnD.exe all-after
(Line 23)	$(CPP) $(LINKOBJ) -o ErkleLnD.exe $(LIBS)

OK, the flags seems to look fine now. At this stage i usually search the makefile for RES to make sure
I haven't missed any occurances of it. Do that now. At the end of the makefile you'll find two lines
that looks like this;

../Obj/ErkleLnD_private.res: ErkleLnD_private.rc 
	$(WINDRES) -i ErkleLnD_private.rc --input-format=rc -o ../Obj/ErkleLnD_private.res -O coff 

They only deal with that WINDRES thing, remove them completely. Now save it as 'makefile.aos4'.

I tidied up the makefile a bit (I lined up the = chars, to make it more readable) but you should
now have a makefile that looks something like this;

# Project: ErkleLnD
# Makefile created by Dev-C++ 4.9.9.2

CPP      = g++ -mcrt=newlib
CC       = gcc -mcrt=newlib
OBJ      = ../Obj/Main.o ../Obj/erkMap.o ../Obj/erkTile.o ../Obj/erkTileType.o ../Obj/erkBmpGen.o ../Obj/erkUnit.o ../Obj/erkTTHive.o ../Obj/erkTTTrainer.o ../Obj/erkCommand.o ../Obj/erkCmdGo.o ../Obj/erkCmdClear.o ../Obj/erkCmdTrainer.o ../Obj/erkCmdHive.o ../Obj/erkTTThorns.o ../Obj/erkCmdThorns.o ../Obj/erkAI.o 
LINKOBJ  = ../Obj/Main.o ../Obj/erkMap.o ../Obj/erkTile.o ../Obj/erkTileType.o ../Obj/erkBmpGen.o ../Obj/erkUnit.o ../Obj/erkTTHive.o ../Obj/erkTTTrainer.o ../Obj/erkCommand.o ../Obj/erkCmdGo.o ../Obj/erkCmdClear.o ../Obj/erkCmdTrainer.o ../Obj/erkCmdHive.o ../Obj/erkTTThorns.o ../Obj/erkCmdThorns.o ../Obj/erkAI.o 
LIBS     = -mcrt=newlib -lalmp3 -laldumb -lalfont -lalfblend -lalagup -lallegro -lpthread -lstdc++ -lauto -lunix
INCS     = -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -I"include"  -I"../include" 
CXXINCS  = -I/sdk/local/newlib/include/allegro -I/sdk/local/newlib/include/ -I/sdk/local/common/include/ -I"include"  -I"../include" 
BIN      = /ErkleLnD.exe
CXXFLAGS = $(CXXINCS) -DALLEGRO_GUESS_INTTYPES_OK -fexpensive-optimizations -O3
CFLAGS   = $(INCS) -DALLEGRO_GUESS_INTTYPES_OK -fexpensive-optimizations -O3
RM       = rm -f

.PHONY: all all-before all-after clean clean-custom

all: all-before ErkleLnD.exe all-after


clean: clean-custom
	${RM} $(OBJ) $(BIN)

$(BIN): $(OBJ)
	$(CPP) $(LINKOBJ) -o ErkleLnD.exe $(LIBS)

../Obj/Main.o: Main.cpp ../include/erkTypes.h ../include/erkMap.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h ../include/erkBmpGen.h
	$(CPP) -c Main.cpp -o ../Obj/Main.o $(CXXFLAGS)

../Obj/erkMap.o: erkMap.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkMap.cpp -o ../Obj/erkMap.o $(CXXFLAGS)

../Obj/erkTile.o: erkTile.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkTile.cpp -o ../Obj/erkTile.o $(CXXFLAGS)

../Obj/erkTileType.o: erkTileType.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h ../include/erkBmpGen.h
	$(CPP) -c erkTileType.cpp -o ../Obj/erkTileType.o $(CXXFLAGS)

../Obj/erkBmpGen.o: erkBmpGen.cpp ../include/erkBmpGen.h ../include/erkTypes.h
	$(CPP) -c erkBmpGen.cpp -o ../Obj/erkBmpGen.o $(CXXFLAGS)

../Obj/erkUnit.o: erkUnit.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkUnit.cpp -o ../Obj/erkUnit.o $(CXXFLAGS)

../Obj/erkTTHive.o: erkTTHive.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkTTHive.cpp -o ../Obj/erkTTHive.o $(CXXFLAGS)

../Obj/erkTTTrainer.o: erkTTTrainer.cpp ../include/erkMap.h   ../include/erkTypes.h ../include/erkUnit.h ../include/erkCommand.h   ../include/erkTile.h ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkTTTrainer.cpp -o ../Obj/erkTTTrainer.o $(CXXFLAGS)

../Obj/erkCommand.o: erkCommand.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCommand.cpp -o ../Obj/erkCommand.o $(CXXFLAGS)

../Obj/erkCmdGo.o: erkCmdGo.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCmdGo.cpp -o ../Obj/erkCmdGo.o $(CXXFLAGS)

../Obj/erkCmdClear.o: erkCmdClear.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCmdClear.cpp -o ../Obj/erkCmdClear.o $(CXXFLAGS)

../Obj/erkCmdTrainer.o: erkCmdTrainer.cpp ../include/erkMap.h   ../include/erkTypes.h ../include/erkUnit.h ../include/erkCommand.h   ../include/erkTile.h ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCmdTrainer.cpp -o ../Obj/erkCmdTrainer.o $(CXXFLAGS)

../Obj/erkCmdHive.o: erkCmdHive.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCmdHive.cpp -o ../Obj/erkCmdHive.o $(CXXFLAGS)

../Obj/erkTTThorns.o: erkTTThorns.cpp ../include/erkMap.h ../include/erkTypes.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkTTThorns.cpp -o ../Obj/erkTTThorns.o $(CXXFLAGS)

../Obj/erkCmdThorns.o: erkCmdThorns.cpp ../include/erkMap.h   ../include/erkTypes.h ../include/erkUnit.h ../include/erkCommand.h   ../include/erkTile.h ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h
	$(CPP) -c erkCmdThorns.cpp -o ../Obj/erkCmdThorns.o $(CXXFLAGS)

../Obj/erkAI.o: erkAI.cpp ../include/erkTypes.h ../include/erkMap.h   ../include/erkUnit.h ../include/erkCommand.h ../include/erkTile.h   ../include/erkTTHive.h ../include/erkTTTrainer.h   ../include/erkTTThorns.h ../include/erkBmpGen.h
	$(CPP) -c erkAI.cpp -o ../Obj/erkAI.o $(CXXFLAGS)


FIXING THE SOURCES
It's now time to try to build the game. Unfortunately this game needed some work on the actual sources, 
so it didn't compile and link, bummer! :) But now you know how to convert a windows makefile into an 
Amiga makefile. Try it on some other Allegro/SDL game/tool. When you know what you are doing, this whole
process of converting the makefile will only take a minute or so. It's not as timeconsuming as it looks
like in this tutorial.

If you still want to build the game, this is how i solved it.

I googled for the error that I got. (error: '::main' must return 'int')
and I found this page;
http://www.linuxforums.org/forum/linux-programming-scripting/33421-main-must-return-int.html

One of the replies suggests this;
Don't write 'void main' write 'int main'.

Great! I edited line 29 in main.cpp, and changed void main() to int main() this helped, 
and now I only had a simple error left, 

error: winalleg.h: No such file or directory

This game is obviously written with Windows in mind, and it tries to include the windows
specific Allegro header winalleg.h, remove this from all the .cpp files where you find
it. They already include allegro.h, so you don' need to add that.

Once this is done, the game will compile and link! Yeah! Copy the exe ErkleLnD.exe 
into the pikselzfinal/ dir and try it.

Bummer. It crashed when launched. It also killed my mouse. And Snoopy didn't give me any
useful info, and as it killed my mouse I can't get any stacktrace to use with addr2line,
sorry, my knowledge ends here. I am off to compile another one, you? ;)

15) CREATING A GUI USING EMPEROR (ALPHA!)
=========================================

This section of the guide is to be considered alpha, it's untested,
and the guide was given to me in a hurry in #amigadev by Ami603.


Open your project and go to the Variables page.
Open the edit window by clicking the 'edit' button.
Add a stringpointer called commandfile. do not add any values to it.


Step by Step:

Go to the request page

Step by step;
page variable, click on edit, select stringpointer, name commandfile, click add.

Return back to the reaction page.

Go to the requester page.
Open the edit window again if it's not opened.
Select errorrequest.
Type "your emulator executable doesn't exists" or something similar as BodyText, and add it.

Select errorrequest again.
Type "The file you selected does not exist" as BodyText, and add it.

Go to the reaction page.
Click twice on your added getfile gadget (on the left).
A text editor will be opened with a function called GetFileX_GadgetUP_evt.

Enter this code between the brackets;

 	IIntuition->IDoMethod((Object *)gad[GID_Getfile1],GFILE_REQUEST,NULL,win[WID_Window1],NULL,TAG_DONE);
 	IIntuition->GetAttrs(gad[GID_Getfile1],GETFILE_FullFile,&commandfile,TAG_DONE);
 	IIntuition->RefreshGadgets(gad[GID_Getfile1],win[WID_Window1],NULL);

(Assuming your gadget is called GetFile1 and you didn't edit the gadget name).

Close the editor, click twice on the launch button.
Another function will be displayed in the text editor, 'Button1_GadgetUP_Evt'
Enter this code between the brackets;


 	BPTR executable,file;
 	STRPTR commandbuffer;
 	if (!(executable = IDOS->Lock("here_goes_The_emulator_cli_executable_name",ACCESS_READ)))
 	{
		// First requester below here
 	}
 	if (!(file = IDOS->Lock(commandfile,ACCESS_READ)))
 	{
		// Second requester below here
 	}
 	else if ((executable)&&(file))
 	{
 		commandbuffer = IUtility->ASPrintf("here_goes_the_emulator_cli_executable_name \"%s\"",commandfile);
 		if (IDOS->SystemTags(commandbuffer,
 					SYS_Input,	NULL,
 					SYS_Output,	NULL,
 					SYS_Asynch,	TRUE,
 					TAG_END)==-1)
 		{
 			IDOS->Printf("Commandline: %s failed\n",commandbuffer);
		}
 		IExec->FreeVec(commandbuffer);
 	}
	IDOS->UnLock(executable);
 	IDOS->UnLock(file);

Now without closing the texteditor go to the requester page again and put your 
editor cursor below the "//first requester below here", click twice on the 
ErrorRequester1 same for "//Second requester below here",
click twice on ErrorRequester2, close the editor, save all, shell ->make

Try to edit the your_command_cli_executable with the name of your exe in both places
in this function.

You can add a third requester, with your about info inside, add another button and 
do the same as before click button twice, select function, go to requesters page 
and click twice on it.

16) COMPILING SDL/GL APPS
=========================

First of all, if you are brave enough to try this, and finds an SDL/GL project
that don't throw hundreds of errors at you, this might help you.

Add -DMINIGL to your CFLAGS.
Add -lGL -lGLU to your LDFLAGS. It's important to add them first, 
before any other link libs.  

Then, there's a bug in the AmigaOS 4.0 version of SDL. It ALWAYS opens a fullscreen
mode, and many apps wants to open a window mode. This is a very common reason as 
to why GL apps crashes when compiled for OS4. So, some changes needs to be done to
the code. 

Look for SDL_SetVideoMode in the sources, and change it to use fullscreen instead.

Here's an example;

Original:
  screen = SDL_SetVideoMode( 800, 600,24, SDL_OPENGL | SDL_HWSURFACE ); 
Changed:
  screen = SDL_SetVideoMode( 800, 600,24, SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN ); 

I have reported this bug to Evil Rich, but he haven't answered the mail, so if
you read this Evil oner, consider it a bug report. ;)

I just got a new, yet unreleased game called Bomber Bastards compiled using this method, 
keep your eyes focused on amigaweb.net as it will be released on that site exclusively.


17) ADDING SUPPORT FOR AMIUPDATE
================================

This chapter is a bit more advanced than the rest. But it's useful info, so I wanted
to include it here anyway. You have been warned. ;) Thanx to Rigo for letting me include
it, it's taken from his site (www.amiupdate.net), and it is written by him.

On other systems, there is a central repository system that each and every application and
component registers itself with, and this makes it easy to find out what has been installed
on the host system. Unfortunately, AmigaOS doesn't have this facility (and lets be honest, 
would we really want to be tied down with such a mechanism?), so AmiUpdate needed a way of 
detecting what applications and components had been installed and where. Without this, there 
would be no way to be able to inform the user that an update is available. 
The solution is two-fold, and it involves the application writing a environment variable 
upon startup. This variable can then be checked, and the installation location obtained. 
From there on, the system checks that location just like any other fixed location 
(as in the OS components and libraries etc).

In the case of system components or third party additions that are always installed to a 
fixed location, you can disregard the following instruction. Files that are always in the 
same place (libs: devs: Utilities etc) do not need to do any special setup before being run, 
as AmiUpdate can use a fixed location to search for it. This applies to any system extention
installed in the Sys: disk, but if satellite programs (applications that use the library, 
for example) are to be installed anywhere the user chooses, then that application must comply 
with the following pre-start setup.

So, from a developers point of view, what is needed to be "AmiUpdate compatible"?

Well, as was mentioned earlier, the application or component needs to write an environment 
variable every time it starts up. One of the nice things with AmigaOS is the ability to be able 
to move things at will on disk without worrying about the installation being corrupted. 
By writing the variable each time the application is run, the contents of the variable is 
always correct, and thus the application may always be found, even when moved.

So, let's look at the steps needed for this:

Here is a function written in ANSI C which will write the variable for you. 
Thanks go to Colin Wenzel for this function (with slight alterations by Rigo - ed!)

/**********************************************************
**
** The following function saves the variable name passed in 
** 'varname' to the ENV(ARC) system so that the application 
** can become AmiUpdate aware.
**
**********************************************************/
void SetAmiUpdateENVVariable( char *varname )
{
  /* AmiUpdate support code */
  BPTR lock;
  APTR oldwin;
  
  /* obtain the lock to the home directory */
  if(( lock = IDOS->GetProgramDir() ))
  {
    TEXT progpath[2048];
    TEXT varpath[1024] = "AppPaths";

    /*
    get a unique name for the lock, 
    this call uses device names,
    as there can be multiple volumes 
    with the same name on the system
        */

    if( IDOS->DevNameFromLock( lock, progpath, sizeof(progpath), DN_FULLPATH ))
    {
      /* stop any "Insert volume..." type requesters
      oldwin = IDOS->SetProcWindow((APTR)-1);
                
      /* 
      finally set the variable to the 
      path the executable was run from 
      don't forget to supply the variable 
      name to suit your application 
      */

      IDOS->AddPart( varpath, varname, 1024);
      IDOS->SetVar( varpath, progpath, -1, GVF_GLOBAL_ONLY|GVF_SAVE_VAR );

      /* turn requesters back on */
      IDOS->SetProcWindow( oldwin );
    }
  }
}
                                
The function is well commented, so it should be fairly obvious what is happening. 
The function also stops DOS requesters during the write to allow for users that lock 
the system drive. Don't edit the function code, else there may be problems.
To use the function from your own code, simply call it with the name of your application. 
As these variables are stored in one central directory, it is of paramount importance 
that each variable has a unique name. The easiest way to acheive this is to name it the 
same as your application. If you steal someone elses location variable, it could have 
serious consequences on the system during update time.

char *appname = "myapp";                                        
SetAmiUpdateENVVariable( appname );
                                
Is all that is needed each time the application starts, so it needs to be in the main() 
function, preferably after all the library checks etc are done and the application is 
ready to start.

Then what, how does it update?

The next step is then to notify the AmiUpdate system that your application is compatible,
and this is done with the notification form located here
This will then allow your application to be entered into the online database of updates, 
and once a new version is available, all users will be able to take advantage of being
able to download it.

Please Note: The update to your application will not trigger until the second release with 
the compatibility code. The first release installs the setup required, but there is 
nothing to update yet, until the second release.


Automatic installation, how?


Some of the supported applications in the Contents section are able to automatically install 
themselves, and this acheived by using a special script located in the root of the update archive. 
Let's use the CopyStore archive as an example. A listing of the archive is as follows:

AutoInstall               256   12-Feb-2007
CopyStore               24013   05-Aug-2007
CopyStore.doc            3255   05-Aug-2007
CopyStore_relnotes       2575   05-Aug-2007
                                
This is the root of the archive once unpacked. The script we are interested in 
is called AutoInstall. This script is a standard DOS script which is executed once 
the archive has been downloaded and unpacked. Being a standard DOS script means that 
the developer can choose to take any number of actions in the script that they so choose.
You may elect to do some simple copying, or even start an Installer script, but the real
power comes from using the CopyStore command.
CopyStore gives you the facility to install your application as you would normally, but
also allows a backup to be made that can be accessed by the RollBack system. 
This is where the real power of the AmiUpdate suite comes into play, as in the 
event of an update which has caused problems, the RollBack tool can be used to 
"Undo" the installation.

Tell me more about CopyStore

Firstly, lets take a look at the AutoInstall script for CopyStore, this will hopefully 
help to explain the situation better:
; get the path to copy to
GetEnv AUPath >NIL:

; copy CopyStore and create a RollBack opportunity
CopyStore CopyStore $AUPath

; copy the doc
Copy CopyStore.doc "$AUPath" CLONE QUIET

; copy the relnotes
Copy CopyStore_relnotes "$AUPath" CLONE QUIET
                                
The first task is to get the path to install the update to, and this is done by
GetEnv. The AUPath variable is located in ENV(ARC): and is written by AmiUpdate 
itself, so it always points to the location on disk where it is installed. 
This variable is also used to update not only CopyStore, but also AmiUpdate and
the RollBack tool.
Once we have the path, the CopyStore command is used to copy the executable to 
the location received from the variable. While this copies the new version to 
it's destination, it also saves the old copy into the Rollback system so that we
may be able to restore the old version if needed. The rest of the script uses 
the standard AmigaDOS Copy command to install the document and release notes,
which obviously are not saved into the Rollback system.
Let us consider another example, this time from the Tunenet archive. This shows 
us a small difference in discovering the path that the application must
be installed to.

; autoinstall for TuneNet
; %VER: TunetNet AutoInstall 1.2 (7.1.2007)

; get the path to the executable from the ENV variable
Set TuneNet `GetEnv AppPaths/TuneNet`

; now copy everything in the archive (apart from the executable)
Copy tunenet/~(Tunenet) "$TuneNet" ALL CLONE QUIET

; copy and store a backup of the executable for Rollback
CopyStore tunenet/tunenet "$TuneNet"

; finally, free the variable
UnSet TuneNet
                                
This time we are setting a local variable (called TuneNet) to the contents of 
the AppPaths/TineNet variable, which is written by TuneNet itself each time it
runs. Now we have the location of TuneNets installation, we simply copy 
everything apart from the executable to the directory. The executable is copied 
via CopyStore, and this again allows the RollBack system to access the old 
version which is being updated. You may have noticed that the variable name has 
been quote-enclosed in the two example scripts listed above, and this is to 
protect against possible spaces in the location received from the environment 
variable. It is quite legal to have spaces in any part of the path that is 
stored in the variable, but once the script has expanded the variable contents,
 the spaces will produce unexpected results, and quotes around the variable name
 will allow us to use spaces without problems.

That is all you need to do in order to get your application or component not only
AmiUpdate compatible, but also to get it to automatically install itself too.

Just a quick word on the usage of CopyStore. As it creates a backup of the old 
version for possible later restoration, it is wise to consider disk space when 
choosing what to backup and what not to. As a general rule, only use CopyStore 
to install vital parts of the installation. Non critical parts (documentation etc) 
can be simply copied which will not take up space in the Rollback system.


18) HELP ME!
============

I created this document mainly to aid myself from the beginning, but it turned 
out to be quite useful in the end, so I decided to clean it up and release it.
I'd love to get help extending this document, if you've spotted an error, want to 
clarify a section or add a new section, please join me in my mission! I am sure
it will be appreciated by many! --- And hey! What could happen? os4depot could be
flooded by new files? That wouldn't be so bad would it?


19) CONTACT ME
==============

Send a mail to: spot AT triad DOT se
You can also find me and a bunch of other helpful developers in #amigadev on irc.amigaworld.net

20) THANKS
==========

This wouldn't be possible without:

HNL_DK, NICOMEN, ITIX, ZEROHERO, VARTHALL, BLACKY_STARDUST, AMI603, RAZIEL, LIO 
AMIGAGUY, SSOLIE, RIGO and the rest in #amigadev! THANX A LOT GUYS!


      .___________________________________________________________.
      |                                                           |
      |              G U I D E   W R I T TE N   B Y               |
     ._______                                        .______.     |
     |  ____/________________________________________|      |__   .
   ._|____._         |      ._       |      ._       |       _/______.
   |      |/         |      |/       |      |/       |      |/       |
   |                 |      _________|               |               |
   |_________________|______|spt/up  |_______________|_______________| 
      .                                                           .
      |                                                           | 
      |   I am in a shitty economical situation, so if you feel   | 
      |  that what I do is  worth anything, use paypal to donate  |  
      |         to my email addy, spotATtriadDOTse, thanx!        | 
      |                                                           | 
      |                    Spot / Up Rough 2007                   | 
      |___________________________________________________________|