Make for HP49

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.

What's new?

07/23/2004 - version 1.0
First public release. Lots of enhancements can be made but with a slown down. Moreover, SysRPL programmers may easily change the program to fit their need.

What is it?

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.

Download and installation

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.

How to use it?

Procedure

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.

Example

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 !

Bugs and issues

TODO list

Source code

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"

CST

{
{
"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
»
}
}

config

« 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
  »
»

make

« 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
»

makeclean

« 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
»