Simple keystroke dynamics analyzer/validator written in Ruby-GTK
I have written a simple keystroke dynamics analyzer/validator as a school project. An instance of Analysis can be attached to a widget, and its collected keystroke data can be averaged and compared using class methods in Analysis.
The Validation class holds class methods to manage a password hashes file and save/load encrypted keystroke analysis metrics to/from disk.
Full documentation is provided through RDoc annotations.
The code will be publicly browseable at my code site when I get permission to host it from my teacher. This is now a gem, and the code is available on github!
Using autotools with C++ to make GTK apps
I’ve been playing around with GTK+, specifically gtkmm last week. I love the GTK+ GUI and I want to write some portable desktop applications. Luckily there are great docs for newbies to get started with. Although C++ has never been my language of choice, I really want to learn it. I think I will warm up to it given I can find a style that works for me. First up are Makefiles. Oh, Makefile. How slender and seductive you start out. Such warts you grow. So much does your ass inflate. After hacking away on my own Makefile for about 2 days I still had code that compiled. But along with that feat came an ugly Makefile which needed constant pruning. I decided it was enough, and thought I’d give automake a try, as is recommended in the gtkmm docs. Luckily the docs are good. But I think they need a bit of updating. On a new C++ project, here’s what I do. I’m using the first gtkmm example here.
aczid@homer:~/helloworld_gtk$ ls -lR .: total 4 drwxr-xr-x 3 aczid aczid 4096 2008-03-18 20:57 src ./src: total 12 -rw-r--r-- 1 aczid aczid 362 2008-02-09 11:35 helloworld.cpp -rw-r--r-- 1 aczid aczid 367 2008-02-09 11:32 helloworld.h -rw-r--r-- 1 aczid aczid 228 2008-02-09 11:33 main.cpp aczid@homer:~/helloworld_gtk$
As you see I have a ‘src’ dir conatining my C++ sources, and no Makefile. Now comes the magic.
aczid@homer:~/helloworld_gtk$ autoscan aczid@homer:~/helloworld_gtk$ ls -l total 8 -rw-r--r-- 1 aczid aczid 0 2008-03-18 20:59 autoscan.log -rw-r--r-- 1 aczid aczid 475 2008-03-18 20:59 configure.scan drwxr-xr-x 3 aczid aczid 4096 2008-03-18 20:57 src aczid@homer:~/helloworld_gtk$ mv configure.scan configure.ac
Autoscan has generated the input file for autoconf for you. Let’s take a look:
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT
Let’s add a few lines.
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) FULL-PACKAGE-NAME(Hello World) VERSION(1.0) BUG-REPORT-ADDRESS(bugs@aczid.nl) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. PKG_CHECK_MODULES(DEPS, gtkmm-2.4 >= 2.4 gtk+-2.0 >= 2.2 glib-2.0 >= 2.2) AC_SUBST(DEPS_CFLAGS) AC_SUBST(DEPS_LIBS) # Checks for header files. AC_STDC_HEADERS # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT
You see I added some GTK libs here. The next 2 lines after that set up the compiler options for them. Also notice I added references to a Makefile in the config files macro. These files need stubs to be processed by automake. There are a lot of macros in autoconf to do all kinds of crazy things. Edit ./Makefile.am and add:
SUBDIRS = src
And in the src/Makefile.am you put:
bin_PROGRAMS = helloworld helloworld_SOURCES = helloworld.cpp main.cpp helloworld_LDADD = $(DEPS_LIBS) AM_CPPFLAGS = $(DEPS_CFLAGS)
See, those LDADD and CPPFLAGS macros rely on our DEPS_LIBS and DEPS_CFLAGS variables declared in the configure.ac file. Now all you need to do is run some commands!
aczid@homer:~/helloworld_gtk$ aclocal /usr/share/aclocal/libmcrypt.m4:17: warning: underquoted definition of AM_PATH_LIBMCRYPT /usr/share/aclocal/libmcrypt.m4:17: run info '(automake)Extending aclocal' /usr/share/aclocal/libmcrypt.m4:17: or see http://sources.redhat.com/automake/automake.html#Extending-aclocal aczid@homer:~/helloworld_gtk$ autoconf aczid@homer:~/helloworld_gtk$ autoheader aczid@homer:~/helloworld_gtk$ touch NEWS README AUTHORS ChangeLog aczid@homer:~/helloworld_gtk$ automake --add-missing
Phew, that’s it! Now you can run ./confgure and it will generate a Makefile from the Makefile.in, which was in turn generated by Automake.
aczid@homer:~/helloworld_gtk$ ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for g++... g++ checking for C++ compiler default output file name... a.out checking whether the C++ compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C++ compiler... yes checking whether g++ accepts -g... yes checking for style of include used by make... GNU checking dependency style of g++... gcc3 checking for gcc... gcc checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking dependency style of gcc... gcc3 checking how to run the C preprocessor... gcc -E checking for grep that handles long lines and -e... /bin/grep checking for egrep... /bin/grep -E checking for ANSI C header files... yes checking for a BSD-compatible install... /usr/bin/install -c checking for pkg-config... /usr/bin/pkg-config checking pkg-config is at least version 0.9.0... yes checking for DEPS... yes configure: creating ./config.status config.status: creating Makefile config.status: creating src/Makefile config.status: creating config.h config.status: config.h is unchanged config.status: executing depfiles commands aczid@homer:~/helloworld_gtk$ make cd . && /bin/sh /home/aczid/helloworld_gtk/missing --run autoheader rm -f stamp-h1 touch config.h.in cd . && /bin/sh ./config.status config.h config.status: creating config.h config.status: config.h is unchanged make all-recursive make[1]: Entering directory `/home/aczid/helloworld_gtk' Making all in src make[2]: Entering directory `/home/aczid/helloworld_gtk/src' g++ -DHAVE_CONFIG_H -I. -I.. -I/usr/include/gtkmm-2.4 -I/usr/lib/gtkmm-2.4/include -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/gdkmm-2.4 -I/usr/lib/gdkmm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/include/atkmm-1.6 -I/usr/include/gtk-2.0 -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include -I/usr/include/cairomm-1.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/atk-1.0 -g -O2 -MT helloworld.o -MD -MP -MF .deps/helloworld.Tpo -c -o helloworld.o helloworld.cpp mv -f .deps/helloworld.Tpo .deps/helloworld.Po g++ -DHAVE_CONFIG_H -I. -I.. -I/usr/include/gtkmm-2.4 -I/usr/lib/gtkmm-2.4/include -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/gdkmm-2.4 -I/usr/lib/gdkmm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/include/atkmm-1.6 -I/usr/include/gtk-2.0 -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include -I/usr/include/cairomm-1.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/atk-1.0 -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp mv -f .deps/main.Tpo .deps/main.Po g++ -g -O2 -o helloworld helloworld.o main.o -lgtkmm-2.4 -lgdkmm-2.4 -latkmm-1.6 -lpangomm-1.4 -lcairomm-1.0 -lglibmm-2.4 -lsigc-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 make[2]: Leaving directory `/home/aczid/helloworld_gtk/src' make[2]: Entering directory `/home/aczid/helloworld_gtk' make[2]: Leaving directory `/home/aczid/helloworld_gtk' make[1]: Leaving directory `/home/aczid/helloworld_gtk' aczid@homer:~/helloworld_gtk$
See? :) I’ve quite enjoyed fooling around with this. It beats the hell out of writing your own Makefiles. It’s nice to know your app will be compatible with GNU standards and there is much less to write and consequently maintain. In the future I think I’ll look at other systems that try to ease the same pains. Autotools were made for much bigger projects than mine. Scons is what I might look into next.










