Wednesday, October 15, 2008

CMake (Part 1)

autoreconf, autoconf, automake, libtool... We are talking about the autotools. Everybody (almost) uses autotools, and it seems that everybody has to use them for good.

Luckily enough, this is not the case. There are alternatives. There are many alternatives. scons and cmake just to name two of the most used.

The problem the autotools solve is not an easy one. Unfortunately the solution is unnecessarily complex. Using autotools for simple projects is just a mess and often their full power is not needed. Consequently I looked for alternatives.

Even though I’m quite a Python enthusiast, I chose to learn cmake first (over scons).

Basically a cmake build script can be as simple as:

project(project_name)
add_executable(foo foo.c bar.h bar.c)

And building a library (shared or static) is not any more difficult:

project(mylib) 
add_library(mylib SHARED foo.c bar.h bar.c) 

Put the lines above in a CMakeLists.txt and run cmake. You can generate unix makefiles, code::blocks projects, xcode projects, visual studio projects, etc.

Nice. Moreover, writing a CMakeLists.txt is quite easier than writing the corresponding Makefile (and the repetitive stages of writing install and clean targets is automated as well).

What about more detailed instructions? Ok, ok, you are right. So...

Suppose you have this project (directories are followed by ‘:’, while files... well, you should recognize them ;) ):

foo:
    bar:
        bar.c
        bar.h
        barbar.c
        barbar.h
    foo.c
    opts.h
    opts.h

If we run ls -R, we get:

% ls -R
CMakeLists.txt bar            foo.c          opts.c         opts.h
./bar:
CMakeLists.txt bar.c          bar.h          barbar.c       barbar.h

Actually you want to create a libbar shared library and the main foo executable (which links libbar).

% cat foo.c
#include <bar/bar.h>
#include <bar/barbar.h>
#include "opts.h"

int main () {
    bar(1);
    barbar();
    opts("ciao");
    return 0;
}

Notice that <bar/bar.h> and <bar/barbar.h> are not local includes. Now we write the CMakeLists.txt for the foo directory. We start examining the main CMakeLists.txt:

% cat CMakeLists.txtPROJECT(foo) 
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)# bar must be processed 
ADD_SUBDIRECTORY(bar)# sets variable SOURCES to the project source files. 
SET(SOURCES foo.c opts.c opts.h) 
# puts the bar directory in the headers search path 
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) 
# puts the bar directory in the dynamic libraries search path 
LINK_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/bar) 

# links with libbar 
LINK_LIBRARIES(bar) 
# creates the executable 
ADD_EXECUTABLE(foo ${SOURCES}) 

I added comments in order to explain statements as you read them. Basically the ADD_SUBDIRECTORY command tells cmake to look for another CMakeLists.txt in the specified directory. Then we set the SOURCES variable. SET sets variables. If you need the value of a variable ${VARIABLE} is the way to get it (remember Make?).

${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} are variables set by cmake in order to simplify configuration.

Another useful command is MESSAGE (a ‘print’ command which can be used for debugging purposes).

Now, it is time for the CMakeLists.txt in bar:

% cat bar/CMakeLists.txtPROJECT(libbar) 
SET(SOURCES bar.c bar.h barbar.c barbar.h) 
ADD_LIBRARY(bar SHARED${SOURCES}) 

We are done!

% cmake . 
-- The C compiler identification is GNU 
-- The CXX compiler identification is GNU 
-- Check for working C compiler: /usr/bin/gcc 
-- Check for working C compiler: /usr/bin/gcc -- works 
-- Detecting C compiler ABI info 
-- Detecting C compiler ABI info - done 
-- Check for working CXX compiler: /usr/bin/c++ 
-- Check for working CXX compiler: /usr/bin/c++ -- works 
-- Detecting CXX compiler ABI info 
-- Detecting CXX compiler ABI info - done 
/Users/riko/src/foo/bar 
-- Configuring done 
-- Generating done 
-- Build files have been written to: /Users/riko/src/foo 

% make 
Scanning dependencies of target bar 
[ 25%] Building C object bar/CMakeFiles/bar.dir/bar.c.o 
[ 50%] Building C object bar/CMakeFiles/bar.dir/barbar.c.o 
Linking C shared library libbar.dylib 
[ 50%] Built target bar 
Scanning dependencies of target foo 
[ 75%] Building C object CMakeFiles/foo.dir/foo.c.o 
[100%] Building C object CMakeFiles/foo.dir/opts.c.o 
Linking C executable foo 
[100%] Built target foo 

More info on CMake can be found in these posts:
  1. CMake and Libraries

Tuesday, October 14, 2008

New tab in current directory (Terminal.app)

One of the most annoying things is when you have to open a new tab
in the current position. Say the shell in the current tab has x
as the current working directory and you want another shell already
in that directory. 
It seems there is no way to tell Terminal.app "open new tab"
from apple script. Mixing solutions found on the web, I came up with:

tell application "Terminal"
    set oldMem to (do shell script "pbpaste")
    set theTab to selected tab of the front window
    (do script "pwd | pbcopy" in theTab)
    set theText to (do shell script "pbpaste")
    tell application "System Events" ¬
        to tell process "Terminal" ¬
            to keystroke "t" using command down
    do script with command ¬
        "cd "& theText & ";clear "¬
        in selected tab of the front window

    do shell script "echo \""& oldMem & "\" | pbcopy"
end tell

Ugly, but works.

Monday, October 13, 2008

ICLP 08

Tomorrow I registered to the ICLP 08 conference.

I'm looking forward to go!

Sunday, October 5, 2008

Terminal.app ANSI Colors

Since Leopard, I did not have a good application able to change ANSI colours in Terminal.app.
Even though it does not seem a particularly pressing issue, the defaults are quite bad: the standard blue is quite too dark to be used on a dark background, so you have to use a light one. Unfortunately enough, some applications assume a dark background (for example, ipython). Of course, these applications can be personalized, but using a dark background can also be just a matter of taste.
Luckily enough, today I found TerminalColoreopard. It works well, it is easy to use, and solved my problem.

iPython and the less pager

When I develop software in Python, one of the most valuable tools is iPython. Among the first functions one learns to love, there are the ? and ?? commands.

Putting a ? after an identifier, gets help for that identifier, putting ?? shows the source. Lets use a couple of examples.

Friday, October 3, 2008

iCab

Today iCab is discounted on mupromo (50%).

Here it is the wikipedia article and here the website of the author.

iCab is a browser for the Mac. It is much more: it is a piece of WWW and Mac history. For a long time it has been the only relatively functional browser for MacOS Classic (after Moz dropped support for the platform).

It's a one man affair and once it used to have its custom rendering engine (until version 3). Now it's a nifty commercial browser with some nice features. Of course WebKit is great and means good support, but I kind of regret it does not use its own engine anymore. Diversity is good...

What has iCab that Firefox hasn't? Nothing. It has a great affective value. Of course, if you've got a MacOS 9, 8 or 7.5 system, it is also the only browser (version 3 from MacOS 8.1 and version 2.x from MacOS 7.5).

Still, its a good tool. It has some nice features, for example the smiley which signals when a website (or CSS) is not standard and opens a windows with the errors.

It has got some relics of when browsing was costly and slow: an offline mode and an acoustic signal triggered when it finishes to load a page.

And it's the only tabbed browser for older macs (but this isn't technical, is it?).

It's quite fast, indeed. And it has a very good filter system. Filters are quite general personalization tools: for example they can be used to add a "download" link to YouTube videos or create an AdFilter. iCab has a very good session management, too.

And that's it: it's not rocket science. It's a little old browser. But at $12.5 it's a bargain!

Thursday, October 2, 2008

The Year of the Kludge

Some days ago, I put back on this blog. Today I dedicated about half an hour to the forum we used to run here on akropolix.

This means reading a lot of PHP. More PHP than I like to see in a whole year. I've yet to recover.

It's exciting to see this big PHP applications work after you have read their code: I just couldn't believe my eyes. The application kind of works, with all its bugs and vulnerabilities, but does work. I'm actually using it. And as long as I don't have to see its code... After all, I have no guarantees on the code quality of most proprietary desktop applications I use (not that open source applications are necessarily better as some suggest). Why bothering about PHP web applications after all?

The point is that their code seems a kind of ordered set of kludges that lead to some approximation of a working application. It's the way most PHP applications are developed.

Many people write PHP code without the slightest clue of software engineering good practices. They often do not know typical web design patterns as well, let alone "classical" design patterns. They just write the code and fix it until it kind of works. The point is that they can do that: PHP allows (and encourages, in my opinion) this strategy.

Using frameworks like Django, you need to write sensibly less code. Most functionalities are already implemented in the framework. But you have to study the framework. You just can't improvise on a dubious architecture gluing together code snippets. And surprisingly the "good" strategy is perceived as harder. You have to be tidy and precise. You have to think. You have to design. You are strongly encouraged to test your software. You are led towards good software practices. And most people do not want to learn. They just want to get their job done. No matters they could save a lot of time doing things properly.

On the other hand, in standard PHP you can just write some messy code and fix it until it seems to work. This is the very idea on which Visual Basic was created. You don't need to know how to do things. You can just stammer code. But the point is not PHP or Visual Basic. There's plenty of languages that allow code stammer. You can write horrible kludges in C, C++, Java, Perl, whatever. And many people just do that.

Moreover, they tend to favour technologies that do not make it blatantly clear how poorly skilled and unwilling to learn they are. The result is that inferior technologies proliferate as incompetents do. By the way, this does not imply that every PHP developer is incompetent, I'm just talking about technologies and how people perceive their ease of use.

Monday, September 29, 2008

CoreData and RAD tools under OS X

I've never been a RAD tool enthusiast. However, I recognize they have their utility. Especially when the "rapid" part comes from a well done library and not from drag and drop mumbo jumbo. Besides, I'm a big fan of drag and drop: I just don't think software should be built with drag and drop. About the "rapid" as in library part, I love Django. I was quite fond of Rails as well, but since Django reached the metaphorical age of consent I just dropped the whole Ruby thing.

Back to Cocoa... I'm mostly an OS X user and I'm quite into OS X development as well. Not that I often write desktop software, but when I do, it's often Cocoa stuff (possibly with Python bindings). And when I received Hillegass book (Cocoa(R) Programming for Mac(R) OS X (3rd Edition) ) I knew it was time to tackle Core Data.

Core Data is a nice technology. There is plenty of examples when you create not-completely-trivial applications only with drag and drop. Which looks good (though I never understood what kind of programming language/framework benchmark is writing a hello world program as most software is not constituted of hello world applications -- and you don't get paid to write hello worlds). Well... the drag and drop thing works as expected: even if you don't know about programming more than what I know about Votic literature, you may surprise your suspenders wearing hacker friends (at least until they ask you how the damn thing works).

Unfortunately enough, everything that is not that trivial (which accounts for most software projects, indeed) needs a bit more attention. The first thing you learn is that you must know the underlying technologies. This seems reasonable enough (after all if you want to work in the IT world you must learn a lot of things -- votic excluded). And when we talk about "learning", we are talking about long term investments. You learn Core Data, KV-coding and Cocoa Bindings and you use them for good. Or at least until Apple screws the whole thing up.

Even though when things become complicated you need to write real code, there is a lot of drag and drop/checkbox checking development done in Interface Builder. Of course you could write that code programmatically, but then you don't qualify for the RAD buzzword thing. The point is that bugs in code are usually signaled with tests, code lints or lawyer dispatches about that blown up nuclear plant you wrote the software for. If you don't write a function, the compiler or the interpreter will complain. If you forget to write part of a function, the software will crash (or the tests will fail, if you are a savvy programmer).

Unfortunately, it is dramatically easy to forget to check checkbox (how many checkboxes would a woodchuck check?) or to fill some textbox in Interface Builder, especially if you have a rather complicated UI with lots of elements (and this accounts for most software you want to sell). Error messages are as cryptic as the Delphi oracle (with no known reference to a nice RAD tool and to the most popular commercial DBMS in the world). Cryptic means that most of the time you have no way to understand which UI element wasn't properly connected and generated the error message, you have to browse the bindings of all the widgets. You probably have to set some debugging option (if so I missed the paragraph where this was explained).

Key Value Validation transcends my understanding. As far as I can see it's dramatically easy to do things wrong and put the system in an inconsistent state. Probably I just did not get the rationale behind it. But... Django seems far easier. Sigh.

Monday, September 1, 2008

I'm Back (Back in Black)

I'm kind afraid the few who read this blog kind of regularly (for pretty wide values of regularly) stopped this despicable practice in the last year, as apparently I stopped writing as well.

This is indeed the bare naked truth. In september I graduated and in the last period I was astonishingly busy (and worried for the results). The results were excellent, but my schedule perseverated in being crowded. I also was thrown out from Google indexing since some nice guy proved that no PHP website can be left unattended for months (and did so filling my articles with invisible links to the worse sites of the web -- or the best ones, depending on your point of view --).

Out of the blue, I decided I could start writing again. And I decided to try the nice MacJournal application whose license I got among the ones in the last MacUpdate Bundle.

The bundle itself was quite unsatisfactory. I don't use most of the applications. I don't like Mellel (and in fact I'm a quite satisfied Nisus Pro user) and I find DEVONagent wonderful and mysterious as well (that implies that I was unsuccessful in making something of it). Some of the other applications are great, though I don't really need them.

For example I'm using 1% of Contactizer Pro capabilities and I think I scribbled somewhere I was to learn to use the program, since it seems extremely useful. I'm also very satisfied by LightZone, since I recently bought a nice reflex and plan to use it a lot. Unfortunately enough, I don't seem to have time to spend sightseeing (and consequently taking pictures) and this is how the story ends. Moreover, I really need two things in an image editing program: something to straighten the horizon and Photoshop ‘patch' tool. Appearently even Gimp has it, but not Pixelmator (nor LightZone, but this is because LZ is a totally different kind of program).

DSC_0351-2008-09-1-05-24.JPG

Moreover, I've got no time to learn LightZone and I'm afraid I'll stick with iPhoto even though it can only save edited images as JPEGs. Which kind of sucks, but it's my fault: I paid for more professional and I don't want to learn how to use them. Besides, the meaning of "more professional software" is still under theological scrutiny.

As a pleasant side effect of the MacUpdate Bundle, I got an enormous discount on software from Koingo Software. This particular discount gives me access to all the applications they created or will create and their updates as well. Librarian Pro is among them.

I love Librarian Pro. I love books and LP seems a great way to keep a catalog. And one day or another, I will put it online. But this is another story.

Going back to MacJournal, it seems an extremely good application. Maybe I will write this blog regularly, after all.

What else? We did Pycon Italy 2008, which was great. And since the blog was not actively maintained, I did not write about it then.

And for those of you curious about my yellow dog... it seems a Leopard ate it. Poor dog! :P

Monday, August 6, 2007

My Yellow Dog ate my Red Hat.

I've always been one of the (not so) few geeks who run Linux on PowerPC.
Sometime ago, Linus himself was one of us, however, it appears that now
he uses a different machine.
Since Apple dropped PPC, the Linux PPC world is quite in turmoil. The architecture is perceived as almost dead. However, new interest comes from the Linux on PS3 projects.
In any case Ubuntu dropped official support for PPC. That was a sad piece of new, since I was quite satisfied with it. I had to recompile the kernel in order to fully support my machine (but this would have been solved in successive releases).
I got back to Debian. I've been a Debian user since Woody, and I liked it ever since. I was a Debian unstable user, and I have always been satisfied with it. However, this time it was different. I've had many more troubles: each upgrade broke something I needed.
I don't know if it's a matter of developers paying more attention to Ubuntu or whatever: the point is that using Debian unstable as a 'reliable' desktop system on power pc seemed quite hard. I don't want to blame Debian developers: it's unstable. No warranties. I used it at my own risk.
Since Debian is unsuitable for my present needs (no hassle, no config, no time), I considered switching Yellow Dog. I know that these days a PPC community mantained version of Ubuntu has been released.
ydl5-2007-08-6-10-27.jpg
I bought a Yellow Dog Enhanced account, since I did want to support their work and I was interested in support, if something was not perferct in the first place. Remember, no time.
I installed the distribution from the DVD. My hardware was entirely recognized correctly. From the soundcard to the backlit keyboard. My video card should also work with dual head, though I haven't tried it yet. YD comes with a nice GUI to do this.
The only thing that was not working was the airport card. I just had to get the fwcutter and extract the firmware. Then it worked. Moreover, the network applet that stays in the notification area works great. I don't know why, but in Debian and Ubuntu for some reasons it did not work properly (in Ubuntu from a certain moment the whole network-manager stopped working). I did not investigate as I needed less time to write a couple of shell scripts to configure the network interfaces when I needed to switch.
I have always been skeptical about rpm-based distros. Once I used SuSE, but after using Debian I got somewhat convinced of the superiority of the Debian packages. More accurate studies on rpm done recently seem to go in another direction: it was not that deb is better than rpm. It is just that deb repositories were maintained more carefully.
YellowDog repositories are maintained quite carefully. However, there is not a lot of software. I suppose something like 1000 packages (Debian has got ten times that). So I had to learn how to cook my own rpms or simply build software from sources and install it with make install. This is probably the major drawback. However, I'm pretty satisfied with Yellow Dog.