Khanh-Dang Nguyen Thu-Lam <kdntl_at_yahoo_dot_fr>
The latest version of this documentation can be found on my website.
Please apologize for my very bad English.
Make is a program very useful for people programming in SysRPL and ASM on HP49 caculators. Its purpose is compiling all the files of a project automatically. It is especially efficient for projects with a lot of source files, for example a library. If you just change one source file, Make would only recompile this file, automatically.
To some extents, Make is the equivalent of the program make running on UNIX systems.
Make is a free software : the source code is under the GPL (General Public License). See http://www.gnu.org/ for more information.
Make version 1.0 can be downloaded on my website. The file is a hp49's repertory. You have to transfer it on your calc with binary mode.
You can also check the source code at the end of this page.
Once the file is copied on your calc, you have a repertory called make, in which there are four objects : CST, config, make and makeclean. You have to move these four variables to the root path of your project. The root path of your project cannot be HOME. For example, if all the source file of your project are located in the repertory { HOME MyProject }, you have to copy the four files there.
Once you have copied the files, you have to create a variable 'Prog' which contains a string. With our example, you can put the string "MyProject" in 'Prog'.
Then, you have to go in the CST menu (blue-shift [H]) and press config. This will run a script that detects whether you have extable installed and the root path of your project. The script will create a variable '~path' (do NOT modify this variable) and a repertory 'bin' (stands for binary). This repertory will contain all the compiled files.
Note: you should only use the commands in the CST menu.
Now you have to create the variable 'Makefile'. This variable must be a list containing the names of the files you want to compile. If the variable is a string, then Make will run the command ASM in order to compile it. Then the compiled file will be save in 'bin'. If it is a repertory, Make will enter in it and will run recursively in it (then, there must be another 'Makefile' in this repertory). If it is another type of object, Make will directly copy the file in 'bin'.
Note that in each repertory where Make reads a 'Makefile', a variable '~makecache' will be created. This file contains the source code's checksum. Make uses it to know whether a file has been changed.
The command 'makeclean' in the CST menu will delete 'bin', ~path and all ~makecache files. It is useful if you want to diffuse the source of your program, or if you want to recompile all you source code.
Say you are programming an astronomy software called HPlanétarium written with SysRPL and ASM (It is exactly my case and it's why I wrote Make ;-). Your source files are divided in two categories : the calculus fonctions located in the repertory 'libastro' and other programs that will draw the display and handle user input. Here is the representation of the source tree (some lines are numeroted for convenience):
1 HPl 2 |-- Makefile 3 |-- Prog 4 |-- GUI 5 | |-- Makefile | |-- DrawMenu | |-- ... | `-- DrawDialogBox 6 |-- libastro 7 | |-- Makefile | |-- CalcMercury | |-- CalcVenus | |-- ... | `-- CalcMoon |-- CST |-- config |-- make `-- makeclean
Variable number 2 contains { 'GUI' 'libastro' }. Variable 5 contains { 'DrawMenu' ... 'DrawDialogBox' }. Variable 7 contains { 'CalcMercury' ... 'CalcMoon' }.
Now, let's run config form the CST menu. All will be OK if lib extable is installed. Some variables are created : 'bin' and '~path'.
Now, after running make from the CST menu, all your source files are compiled and copied in 'bin'. The source tree now looks like this :
HPl 1 |-- ~makecache |-- bin 2 | |-- DrawMenu 2 | |-- ... 2 | |-- DrawDialogBox 2 | |-- CalcMercury 2 | |-- ... 2 | |-- CalcMoon 1 |-- ~path |-- Makefile |-- Prog |-- GUI 1 | |-- ~makecache | |-- Makefile | |-- DrawMenu | |-- ... | `-- DrawDialogBox |-- libastro 1 | |-- ~makecache | |-- Makefile | |-- CalcMercury | |-- CalcVenus | |-- ... | `-- CalcMoon |-- CST |-- config |-- make `-- makeclean
All the compiled file are in the 'bin' repertory. Note that variables 1 (prefixed with a ~) shouldn't be edited.
As my project is a library, I also created a script that copies a $ROMID and $TITLE into 'bin' and then runs CRLIB.
Now, say that you have just found a bug in the files DrawMenu and CalcMoon. So you edit these two files, correct the bug. You want to compile it. Without Make, you would have done it manually. But now, just go in the CST menu and press make and the two files (and only these two files) are compiled !
Here is the source code of version 1.0. These files are protected by the GPL.
Note: \=/ is an escaped form and means "not equal"
{
{
"config"
« PUSH { -66. -72. } SF config POP »
}
{
"make"
« '~path'
IF DUP VTYPE 5 \=/
THEN DROP "Please run config" DOERR
ELSE RCL EVAL
END 0 R\->I -> \<-r
«
IFERR make
THEN PATH TAIL
« "/" SWAP + » MAP
"in HOME" SWAP + ΣLIST ":
" + ERRM + MSGBOX
END
»
»
}
{ }
{
"clean"
« "Clean ?" { "Yes" "No" } 2.
IF CHOOSE
THEN
IF "Yes" ==
THEN '~path'
IF DUP VTYPE 5 \=/
THEN DROP "Please run config" DOERR
ELSE RCL EVAL
END
CLLCD "Purge 'bin'.." 1. DISP
"Purge '~path'.." 2. DISP
'bin' PGDIR '~path' PURGE
makeclean
END
END
»
}
{ }
{
"help"
« PUSH -70. SF "[F1]: init some vars
[F2]: start compilation
[F3]: install the lib
[F4]: purge bin, ~makecache
[F6]: this screen
" 1. DISP -1. FREEZE POP
»
}
}
« 0. \-> l
«
IFERR CLLCD "Configure.." 'l' INCR DISP
"Checking ROM version.." l 1. + DISP
VERSION DROP DUP "#" POS 1. + 99. SUB
IF { "1.19-6" } OVER POS
THEN "ROM " SWAP + ": OK" +
ELSE "WARNING: not tested on ROM " SWAP +
END
'l' INCR DISP
"Checking for extable.." l 1. + DISP
IF LIBS "extable" POS
THEN "extable: OK" 'l' INCR DISP
ELSE "LIB 258 extable not found" DOERR
END
"Find RootPath.." 'l' INCR DISP
WHILE
IF PATH TAIL DUP SIZE
THEN
« "/" SWAP + » MAP
IF DUP SIZE 1. >
THEN ΣLIST
ELSE HEAD
END
ELSE DROP "/"
END
"Path: HOME" SWAP + l DISP
VARS 'Prog' POS NOT
PATH SIZE 1. \=/ AND
REPEAT UPDIR
END
IF PATH SIZE 1. ==
THEN "Can't be in HOME" DOERR
END
"Project: " 'Prog' RCL + 'l' INCR DISP
PATH '~path' STO
"Checking for 'bin'.." l 1. + DISP
IF VARS 'bin' POS NOT
THEN "Creating 'bin' directory" 'l' INCR DISP 'bin' CRDIR
ELSE
IF 'bin' VTYPE 15. \=/
THEN "'bin' must be a directory" DOERR
END
END
THEN "ERROR: " ERRM +
ELSE "Done."
END
'l' INCR DISP 10. FREEZE
»
»
« CLLCD '\<-r' INCR "make[" SWAP + PATH TAIL
« "/" SWAP + » MAP "]: HOME" SWAP + ΣLIST + 1. DISP
IFERR 'Makefile'
IF DUP VTYPE 5. \=/
THEN "No or bad Makefile" DOERR
ELSE RCL
IF DUP SIZE NOT
THEN DROP "" DOERR
END
END
DUP SIZE '~makecache'
IF VARS OVER POS
THEN RCL
IF DUP2 SIZE \=/
THEN DROP # 0h 'X' 1. 4. PICK 1. SEQ
END
ELSE DROP # 0h 'X' 1. 4. PICK 1. SEQ
END
SWAP UNROT
\-> m ~m
« 1. SWAP
FOR k m k GET DUP 2. DISP
IF DUP BYTES DROP ~m k GET ==
THEN ": no changes" + 2. DISP
ELSE
DUP VTYPE
CASE DUP 2. ==
THEN
DROP DUP RCL ASM SWAP
PUSH ~path EVAL bin STO POP
END DUP 15. ==
THEN
DROP EVAL make UPDIR
CLLCD \<-r "]" + "make[" SWAP + 1. DISP
END
DROP DUP RCL SWAP
PUSH ~path EVAL bin STO POP
END
END
NEXT
"Updating '~makecache'.." 2. DISP
{ }
1. m SIZE
FOR k
m k GET DUP 3. DISP BYTES DROP +
NEXT
'~makecache' STO
»
THEN ERRM
IF DUP "" ==
THEN DROP
ELSE DOERR
END
END
'\<-r' DECR DROP
»
« PATH TAIL
« "/" SWAP + » MAP
"Cleaning HOME" SWAP + ΣLIST 3. DISP
'~makecache' PURGE
15 TVARS DUP SIZE
IF DUP
THEN 1. SWAP
FOR k
DUP k GET EVAL makeclean UPDIR
NEXT
DROP
ELSE DROP2
END
»