On a typical UNIX computer I can compile and link that program with a command like:
    cc -o hiworld.exe hiworld.c -lX11
whereas if I used the GNU C compiler that would simply be:
    gcc -o hiworld.exe hiworld.c -lX11
(and you may very well need other -l and/or -L arguments 
 depending on the details of your system, these will be discussed in the next 
 lesson.)
hiworld.c has a very simple interface: it pops up with the 'Hello!' string in place, mouse <Button-1> clicks put 'Hi.' strings in place, and any keyboard keystroke stops the primitive event handler loop and exits the program.
It is amusing to note that the equivalent functionality of that roughly 73 line C program can, with Perl/Tk to the rescue, be written in about 10 lines:
    #!/usr/bin/perl -w
    use Tk;
    my $m = MainWindow->new;
    my $c = $m -> Canvas(-height => 200, -width => 300,);
    $c -> pack;
    $c -> create('text', 40, 50, '-text' => "Hello World!");
    $m -> bind('<Any-KeyPress>' => sub{exit});
    $m -> bind('<Button-1>' => sub {
        $c -> create('text',$c->XEvent->x,$c->XEvent->y, -text => "Hi.") });
    MainLoop;
(Note that a tcl/tk version can be as few as 6 lines! 
 Neither the perl/tk nor tcl/tk versions are really fair to the C version since 
 it cannot even refresh the additional 'Hi.' strings on expose events 
 the way the perl and wish scripts do automatically.)
    hiworld : hiworld.c
            cc -o hiworld hiworld.c -lX11
which would be invoked with "make hiworld" for example. It is considered
much more fashionable to throw in a bunch of macros into one's 
Makefile's as in the following:
    CC = cc
    X11 = -lX11
    all : hiworld
    hiworld : hiworld.c
            $(CC) -o hiworld hiworld.c $(X11)
which is still invoked via "make hiworld" even though it looks a little
more complicated. Perl's ExtUtils::MakeMaker facility is much more adept
at making Makefiles though, its use is discussed in the next lesson.
    h2xs -A -n Howdy
and note the creation of a new Howdy/ directory with several new files.
With version 1.16 of h2xs the directory appears as follows:
    -rw-r--r--   user     118 Changes
    -rw-r--r--   user     982 Howdy.pm
    -rw-r--r--   user     158 Howdy.xs
    -rw-r--r--   user      54 MANIFEST
    -rw-r--r--   user     371 Makefile.PL
    -rw-r--r--   user     650 test.pl
The remainder of this lesson concerns itself with modifying (at least) four 
of the new files that were automatically generated: 
Howdy.xs, 
Howdy.pm, 
Makefile.PL, 
and test.pl. 
For those of you curious about the above options passed to h2xs try taking a look through perldoc h2xs or tkpod h2xs. Note that -A specifies omission of the AutoLoader, and the -n option is given the package name we will be creating: Howdy.
One way to get our C Xlib code into Howdy would be to append (and slightly modify) the contents of hiworld.c to the (initially) blank stub of Howdy.xs (on Unix that would be something like cat hiworld.c >> Howdy.xs.) We edit Howdy.xs to add the required CODE: and OUTPUT: RETVAL statements, as well as to change function main(argv argc) to a funtion hiworld(argv argc) (clever name eh?). So that now the head of Howdy.xs now appears like:
    #include "EXTERN.h"
    #include "perl.h"
    #include "XSUB.h"
    #include 
    #include 
    MODULE = Howdy          PACKAGE = Howdy
    int 
    hiworld(argc, argv)
            int argc
            char argv
            CODE:
   
(note the function type of int, although void would have been 
just as appropriate.) 
The tail of Howdy.xs now appears something like this:
            XCloseDisplay(mydisplay);
            OUTPUT:
            RETVAL
Note the absence of a call to exit(0); that we had in
hiworld.c, and an absence of the 
 braces {} for a main since there is no longer a 
 main (we are turning out a hiworld() subroutine call for perl 
 after all and perl.c already has a main{}).
We turn our attention to the Howdy/Makefile.PL file and change the line that initially says:
    'LIBS'      => [''],   # e.g., '-lm' 
to read something like what we needed to use to compile hiworld.c from the
command line, like:
    'LIBS'      => ['-lX11'],   # e.g., '-lm' 
better still would be something like what is in the Makfile.PL for Tk, as of
Tk-b11.02 that would be:
    'LIBS'    => ["$xlib -lX11 -lpt -lsocket -lnsl -lm"],
Hmm... we don't know what "$xlib" interpolates to, so let's keep it simple:
    'LIBS'      => ['-lX11 -lpt -lsocket -lnsl -lm -ldnet'],   
(The very observant will note that I also added a line to Howdy's
 Howdy/Makefile.PL that reads:
    'dist'      => { COMPRESS => "gzip -9f" },
 which is for make dist to make a nice compact 
 distribution file.)
Before attempting to build our Howdy extension lets put in some non-trivial code into the test.pl file so that make test will be interesting. Since test # 1 is the loading via a use Howdy; statement let us add a second test so that we set last_test_to_print to 2 and add a couple of careful lines to test.pl:
    eval '$retval = &Howdy::hiworld($foo,$bar);';
    if ($@) {print "not ok 2: $@\n";} else {print "ok 2\n";}
We can now type the following standard commands to build and install our 
Howdy::hiworld extension to perl:
    perl Makefile.PL
    make
    make test
    make install
(Note also, statically linked Howdy perl binaries can be made by running 
 something like this:
    make -f Makefile.aperl inst_perl MAP_TARGET=howdyperl
 after make and before make test. Scripts written with a 
 statically linked howdyperl will need to start with 
 #!/path/to/howdyperl.)
After make install it is possible to run perl scripts that call the hiworld() subroutine in as little as three simple lines of perl:
    #!/usr/bin/perl
    use Howdy;
    $return = &Howdy::hiworld($a, $b);
For illustrative and testing purposes I have made a
distribution copy of the 
Howdy "module" for perl, as it 
appears up to this point in the discussion.
    #!/usr/bin/perl
    use Howdy;
    $return = &hiworld($a, $b);
we get error messages like:
    $return = &Howdy::hiworld($a, $b);
which will complain under -w about $a and $b not being 
initialized. Let's re-write that sample use script as:
    #!/usr/bin/perl -w
    use Howdy;
    my ($a, $b) = (0, 0);
    $return = &Howdy::hiworld($a, $b);
    print "\$return = $return, \$a = $a, \$b = $b\n";