Hari's Corner

Humour, comics, tech, law, software, reviews, essays, articles and HOWTOs intermingled with random philosophy now and then

Basic tips for Linux programming

Filed under: Tutorials and HOWTOs by Hari
Posted on Mon, Dec 11, 2006 at 10:56 IST (last updated: Wed, Oct 29, 2008 @ 22:00 IST)

If you're new to Linux programming, then you might be interested in considering these aspects before you start your wonderful journey. Especially if you've programmed in Windows, you might want to change some of your ideas, so that you minimize the "culture" shock you experience when you encounter completely different ideas and ways of thinking.

Here are some of my tips, based on common questions asked in forums about Linux programming especially from experienced Windows programmers.

Evaluate every available alternative

Unlike the unified Windows API which provides the Windows programmer with a single method of achieving a certain objective, Linux provides a variety of ways to achieve the same objective. For instance there are a variety of GUI abstraction toolkits, the major ones being QT and GTK to write GUI programs. Again, you need not necessarily choose C or C++. There are many choices for programming including basic shell scripting, Perl, Python and PHP. So do not always have a fixed idea that you need to learn the "hard" way. In fact, you might be surprised to discover the power and elegance of scripting.

Do not be overwhelmed by choices. Just be aware of all of them and pick the tools and techniques that you're most comfortable with.

IDEs are not necessarily more productive

Programmers who've used Microsoft Visual Studio extensively to do their development might find it uncomfortable to adapt to Linux's way of doing things. While there are some pretty decent IDEs in Linux including Kdevelop, anjuta and Eclipse, you might actually find that using a text editor and creating a make file to be a better idea in the long run. Particularly when you are developing Free Software applications, you might not want to tie down development to a particular platform or IDE considering that your code will be shared and other programmers might also be contributing to your project. While IDEs are not always bad, you might find developing smaller projects using a simple text editor and a makefile a better idea.

Do not look for distribution-specific features

It might surprise many Windows programmers to know that you can practically make no assumptions about a default Linux configuration on the end user's machine. Different distros use different configuration file locations and settings. Unless you're writing a system configuration utility for a particular distro, try and avoid distro-specific assumptions. Also never force users to run as "root" unless your application's sole purpose is to modify system specific settings.

Do NOT modify or attempt to modify system files

Apart from being bad programming etiquette,
  1. You cannot assume that a certain system file exists on the end user's machine (because of distribution-specific differences).
  2. You simply cannot modify system files as a "normal" user and you cannot expect a normal productivity app to be run as "root."
In most cases, you will find you hardly have any good reason to touch system specific files.

Be consistent visually

GUI programmers, especially GTK and QT programmers, need to understand that these libraries are heavily themeable (meaning that the end-user can modify the visual appearance of GUIs in almost any way possible - including fonts, colours and the widget appearance). Therefore, avoid using specific fonts or colours in your GUIs. You don't need them. Do not force your end users to install any particular font on their system. Leave your application's visual rendering entirely to the GUI library that you use. Unless you're writing a word processor you might hardly ever need to directly handle fonts in your application's code.

Be prepared to do some research

Linux does not come with an MSDN-like tool to provide you documentation for every single programming tool or API available out there. It's simply not practical because Linux is not developed by a single company. In most cases if you're using third-party libraries, you will be able to find documentation (either downloadable or online) on the official website of that particular library's maintainer. Also be aware that quite a few libraries come with incomplete documentation or none at all.

You might have to look for sample code or even at header files to learn more about a particular library. Fortunately you might not encounter this situation in the case of most popular third-party libraries, but it's better to be prepared nevertheless.

Do not package dependencies

When you're creating a "distributable package" do not include dependencies along with your tarball. Just include the source and provide compiling instructions (the more generic, the better). Also mention the required dependencies in your README or INSTALL files and in your website. Since most Linux distributions have their own package management systems (and if you're application is good enough, it might even be included in the official package repository), you should leave the dependency handling either to the end user who compiles your program manually or to the distribution package maintainer who ships your application as part of his package. Since every Linux distribution has a different way to manage dependencies, do not interfere with it by creating an "installation" routine that tries to be smart and installs other libraries.

Apart from creating versioning problems, it's simply tedious and cumbersome to include dependencies with the program. Also try and keep the dependencies to a minimum, particularly if your program tends to use exotic third-party libraries.

Even if you're not releasing your program as Free Software, try and keep the packaging to a minimum and provide instructions to the user on dependencies.

I hope this has been of use to you as a newbie to Linux programming. Happy programming!

37 comment(s)

  1. Why don't you send this as an article on Linux-Journal or Newsforge? Great write-up!

    Comment by Sudipta Chatterjee (visitor) on Mon, Dec 11, 2006 @ 12:08 IST #
  2. Thanks Sudipta, maybe somebody can submit it to a syndication site like LXer. :grin:

    Comment by hari (blog owner) on Mon, Dec 11, 2006 @ 12:19 IST #
  3. Indeed - great article, Hari!Submitted to both LXer and LinuxToday :P

    Comment by J_K9 (visitor) on Thu, Dec 14, 2006 @ 01:25 IST #
  4. Thanks, J_K9.:smile:

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 07:55 IST #
  5. Nice but I have one question about dependencies, is there any reason not to publish both the source-code in the way you recomend and a seprate tarball containing a version with all dependencies included. I'd have thoguht that a monolitic zero-dependency tarball would be usefull for testing the program before going to the effort of tracking the dependencies for the proper version.

    Comment by Tortanick (visitor) on Thu, Dec 14, 2006 @ 14:49 IST #
  6. Very useful for beginning programmer like me. Thanks a lot!

    Comment by KaruppuSwamy.T (visitor) on Thu, Dec 14, 2006 @ 15:09 IST #
  7. Tortanick, first dependencies are rather complex and the versioning of libraries makes it even more difficult to track on a per-application basis. There is a good reason why most Linux developers don't include every dependency within their packaging ;)A zero-dependency application sounds a good idea, but in practice, linking statically to all libraries makes for huge binaries and that would really put a huge load for larger applications. Besides it's wasteful to have to link each application to the common libraries statically which duplicates a lot of code in every application.Secondly, most modern Linux distros come with their own package manager which handle dependencies and program installations. So doing anything to disrupt the package manager's work is a bad idea. It's best to release the source code and allow the package maintainers/builders of each distribution to release your program as binaries and let them deal with the dependency-handling issue. People don't appreciate it when your program tries to be "clever" because you can never tell what distribution of Linux and configuration the end user's installation runs on. You might end up breaking a lot of distribution-specific stuff if you have a generic installation utility which people don't like.A third reason for not packaging third-party libraries -- you might end up distributing older and obsolete versions of libraries with your application. It's best to let people install third-party tools from their distribution-specific package manager or the website of that particular library so that they can be sure of being up-to-date with the latest version.Examples of breaking stuff: wrong default application installation location, overwriting existing libraries with newer ones, breaking the package manager's internal dependency handling, installing configuration files at wrong locations etc. etc. ;)KaruppuSwamy, thanks... hope you can gain something from it.

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 15:43 IST #
  8. Good read, but I have one objection to your last point about packaging dependencies. I think it depends. I am a newbie programmer (running Debian) and I wrote a program (Python) that used a third party module that I got using apt. No worries there. One day I updated the machine and saw that a new version of this third party module was to replace the one that I have been using. No problems there I thought but not so. My program wouldn't work after the upgrade. I worked on this for a bit and figured out that it was the upgraded module that was buggy. The old version was gone from my system as well so I couldn't remove and install the older package either so I was stuck. In any case, this story has a happy ending because the author of this module was quick to respond to my findings and provided me with a patch so I was up and running again within a short time period, but think of the implications if I had distributed my program? All Debian users would have been sitting with a broken program without an immediate fix. I am therefore thinking about integrating this third party module into my program as a result.

    Comment by Dave (visitor) on Thu, Dec 14, 2006 @ 17:25 IST #
  9. Dave, that's precisely the point. If a third party module is buggy or broken, you shouldn't take it upon yourself to fix third-party bugs.Where there's already a system that manages it for you, you, as an individual programmer should not be concerned about third party bugs except to alert your users to the problem and the fix (if available). Not *take* it upon yourself to fix the issue assuming things about their system which might be vastly different from your own.If you try and fix it yourself on the end user's machine with your own version of that package, imagine how chaotic the situation would be today with every software developer distributing their own version of common libraries. Won't it create dependency hell on the end user's machine?

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 17:50 IST #
  10. [...] Continue reading at Hari’s Corner [...]

    Comment by NewStance » Blog Archive » Basic tips for Linux programming (visitor) on Thu, Dec 14, 2006 @ 17:51 IST #
  11. Dave, the correct solution is to have the author of the 3rd-party library you are using fix the bug, not to bundle the old version of the library.If you bundle the module with your own application, it may unintentionally conflict with a newer version of the same module on the system already and you break another application. That's a bad idea and not appreciated. This is pretty typical issue on Windows where a program X installs its own copies of some system libraries and breaks something else depending on the original version.

    Comment by Jan (visitor) on Thu, Dec 14, 2006 @ 17:55 IST #
  12. Good post, I agree with pretty much all of it. But that dependency point makes me wonder.I just happen to have installed the "dock-apps" for the slit in Fluxbox on my new Slackware 11.0 system that I've been moving into. Took the better part of the day for four system monitors and two utilities.Now, here you have a situation where (a) no automatic package system, just "installpkg" for .tgz files and good luck with the rest, (b) dockapps, which are notorious for being compile-only installs and for no two of them sharing any particular standard, (c) some of these dockapps out there are dependent not just on any library, but on some obscure, bizarre library that is guaranteed to not be installed on 99% of the distros out there.In that case, I *would* appreciate it if the author at least tossed in the library package (especially if it was only 40 KB in size!) as an option. Even at the very least, co-host the library on their server, or have an up-to-date link for it. Scouring the depths of the Internet desperately searching for the one server in a corner of Botswania that hosts the library's tarball is a little much even for a Slackware hacker!But that's just a minor nit. Of course, dockapps on Slackware are an edge case, and I only have to do it once every couple of years on a clean install.

    Comment by Penguin Pete (visitor) on Thu, Dec 14, 2006 @ 19:03 IST #
  13. Yeah, in the case of very exotic libraries, I think it's a good point, but not for the rest...

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 19:18 IST #
  14. Very good article, congratulations :wink:

    Comment by Miguel Rentes (visitor) on Thu, Dec 14, 2006 @ 19:22 IST #
  15. Err ... is it just me or does this article make depressing reading from the point of view of someone trying to make a software package that will install and run on any Linux machine?As much as I like Linux, there seems to be a large overhead (primarily research) associated with making your package runnable on say 4 Linux distributions (Red-Hat, Suse, Ubuntu, Debian). For one thing, if you use a window manager you'll be hit with the QT/GTK and KDE/Gnome controversy. If you don't use a Window manager ... you'll either have to take aboart code in program to create your own interface, or you're back at command-line level.Then ... package dependencies. A previous poster (Dave) described a scary experience with a third-party module that stopped working when updated. Lack of regression testing of that third-party application apparently.Now compare that to the one-stop shopping situation in MS Windows where lots of things about the OS can be assumed; starting with the existence of a registry. I had an approximately similar experience as a user of a Java package that ties in to the statistical package "R". Under Windows the package installed in 15 seconds after download and ran without problems. Under Linux the same package took me 2 days of work to get to run ... because of package dependencies that didn't quite work out. I had to actually goin and edit the make files.Despite all its progress Linux still has some work to do before it catches up with MS Windows in terms of ease of writing (and installing) a package with a GUI that uses other packages. So let's not get too cocky about Linux just yet, shall we?

    Comment by Golodh (visitor) on Thu, Dec 14, 2006 @ 19:22 IST #
  16. [...] Free/Open Source Software Basic tips for Linux programming Red Hat: Vista is an opportunity Crossing the OS Divide With Linux Linux radio suite powers independent broadcasters Why FOSS isn’t on activist agendas [...]

    Comment by BLOGical Thoughts » Thursday, 14 December, 2006 (visitor) on Thu, Dec 14, 2006 @ 19:43 IST #
  17. Hari, I agree with your post (9) if we lived in a perfect world :) In my case my application stopped working. If I want to wait until a fix appears "the normal way" (that is, through Debian) then the developer has to publish a new version of his software and then I would have to rely on the Debian maintainer to upload that fix to Debian right away. I can't be sure of either.Jan (11), I don't see what the problem is with bundling the library that works for my app even if it isn't the most recent one. I would also make sure that if I did bundle it then I would make sure that it is in an unconventional place so that only my application would know of it. In that way I wouldn't have to worry about versioning problems. Another thing to figure out is that this library is only found by default in Debian and Gentoo if I am not mistaken. Everybody else will have to go through the tedious process of downloading it and installing it. The way my app works right now is that it checks to see if the import fails for that library. If it does then it will point out where it is found for download. I doubt I will ever publish my app since it is an app that fixes a specific problem I have (and a couple of my friends), but the above is the reason why I would consider integrating 3rd party libs if they are only small ones (or obscure ones) in apps that I am writing. It makes everybody's life easier - not harder.

    Comment by Dave (visitor) on Thu, Dec 14, 2006 @ 19:52 IST #
  18. Golodh, If you know Linux well you should know that dependencies are taken care of by apt-get (Debian & derivatives), emerge (Gentoo), yum (Redhat and derivatives) so your "QT/GTK and KDE/Gnome controversy" doesn't really exist as you describe it for modern distros. I for one run KDE on a day to day basis and I have no problems running Gnome apps when I want. As your your statement on regression testing, we are not talking about a serious app here that costs money, but a solution that I created for a small problem I had and that solution is dependent on a third party library. I have used my app on Debian, Kubuntu, Fedora Core 6 and even Windows (with a minor change) and it works just fine as long as the third party lib is installed on the respective platforms.As for Windows, my company deals with dll hell each and every day. Right now we are suffering tremendously because we are changing from Visual Studio 2003 to 2005. It is quite amusing to see how many dll related issues we are running into :)

    Comment by Dave (visitor) on Thu, Dec 14, 2006 @ 20:07 IST #
  19. In reply to the idea that the dependency situation makes it hard to maintain an application for a number of distributions...There is a simple approach to this problem: Provide a statically linked version of your application in addition to the normal dynamically linked version. If a customer is having problems with library compatability, give them a way to install the larger binary to fix the problem.This fix to a build system usually only takes a small portion of a day to do. From then on the application can support any Linux distribution.

    Comment by Curtis (visitor) on Thu, Dec 14, 2006 @ 20:21 IST #
  20. With regards to the situation where a windows installation went so smoothly and the Linux one was a bitch:Yes I've experienced similar situations... but you are forgetting the converse. When something in windows does not work (due to a bug in a windows library) I cannot fix the library, recompile and install on Windows. I may be (and have on occasion) waited years for a proper fix. Linux wins big for me when this happens. The rare two day linux fix seems like a blessing compared with having your hands tied.

    Comment by Curtis (visitor) on Thu, Dec 14, 2006 @ 20:30 IST #
  21. Unfortunately, providing a statically linked version of major apps with big libraries will be very infeasible.Secondly, packaging our own dependencies seems like an excellent solution, except that you create more problems than you fix -- namely the same library will be littered in multiple locations in the end user's machine and it will lead to breakages in other apps which depends on a different version of the library.Actually this whole "dependency" issue is so complex that even major OS developers break their heads over it. As programmers we cannot expect to solve all the problems of the end user but to merely make sure they are armed with the knowledge to fix them.I still believe that if every application developer started packaging dependencies, we'd soon get unusable systems simply because the conflicts between different versions of the same library will be immense.

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 20:48 IST #
  22. Golodh, you do exaggerate a bit. There is indeed a need for standardization in Linux and some folks do work on it. But the situation is not that bad as you think. For example if you choose a qt library to program your GUI a GNOME user will be able to run it as well just by installing some library which he probably has installed by default. Besides that most of the libraries are so widely used that you shouldn't worry about having them in some distro. Having things the MS way is not a perfect solution either, they do limit your freedom by locking you into some particular libraries or tools which you may not like. In GNU Linux on the other hand you have the choice, so you can pick the library which you find the most suitable. It does takes some time to pick the right ones, but that is not a bad thing after all.Enjoy your freedom!

    Comment by lexan (visitor) on Thu, Dec 14, 2006 @ 20:56 IST #

  23. Comment by Tortanick (visitor) on Thu, Dec 14, 2006 @ 20:58 IST #
  24. You forgot to mention one nice nice competitive GUI programming language:WxWindows --> multiplatform, python binddings and more...GTK and KDE are not uniques in linux there are plenty more.gatuus

    Comment by gatuus (visitor) on Thu, Dec 14, 2006 @ 21:22 IST #
  25. Tortanick, yes, I do agree that in special cases with programs requiring exotic libraries, having a static binary would be a good idea. E.g. some MIDI programs and sequencers (they're really a pain to get to work sometimes due to exotic system requirements).So yes, but only as a special case. My post was targetted at clueless newbie programmers who think they must like statically to libraries like QT or GTK to fix all their dependency problems.

    Comment by hari (blog owner) on Thu, Dec 14, 2006 @ 21:22 IST #
  26. I agree with the 'it depends' crowd on dependencies. For common libraries (ie. libpng, libz, libxml2) expect the user/distro to handle it. However, if the library is not so common, it is not hard to build the app using relative paths to find the required libs. The master Makefile first builds the libs, then the app Makefile sets something like -L../../libdir -lfoo for each library. This links those statically, and after the 'make install', the whole install tree can be blown away.

    Comment by JJS (visitor) on Thu, Dec 14, 2006 @ 23:18 IST #
  27. Good overview - helps manage what programmers should expect. Very much common sense advice (but not necessarily common knowledge).

    Comment by Mr. Tx (visitor) on Fri, Dec 15, 2006 @ 02:16 IST #
  28. I agree with the comments by Tortanick. But lets understand there is a difference in basic concepts here.There are some people that are interested in open source and the incredible amount of resources available. Then there are others that want to build applications for end users. Of course, these 2 groups overlap to some degree.Another way to look at it is this: Those focusing on open source want to 'tap into' the code/binaries distributed through open source. The other people want to make applications that are 'bullet proof' for their end users. Are you beginning to see the conflict?Tapping into code/binaries that are not under your control for distribution/update will almost assuredly cause problems for your application at some point in time. So those wanting to build applications are 'horrified' (or at least very worried) and hesitant to build on such a foundation. The bottom line is if you include EVERYTHING in your application distro, and you ensure you only work with the code/binaries in that distro, you will have the highest assurance that your application will always work as expected (of course, still not a 100% guarantee ).And there is one thing I'm not sure about. I do not think the open source model allows someone to 'include' the source in a product for sale. Or, if you include the code in your distro, you need to make your distro open source as well. That is something an application developer is also probably afraid of doing.And I think therein is a big challenge for Linux and open source. The OS and technical merit does not help get Linux adopted. It is the applications and functions that sit on top of it. So, unless some way is found to give a benefit to application developers, Linux, and open source, will have only slow growth.Just my opinion of course. And believe me, I'm really really hoping Linux/open source wins out in the end. I tell everyone Linux/open source is the only hope for true advancement in the computer industy.

    Comment by Charlie (visitor) on Fri, Dec 15, 2006 @ 09:20 IST #
  29. Charlie, whether you can use FOSS licensed code in proprietary applications is a matter of the license.Some FOSS licenses allow it - e.g. BSD-style licenses allow you to use the code in proprietary applications (you needn't release the source code of your application), while the GPL license prevents you from using GPLed software in proprietary applications.Also note the difference between the terms: proprietary and commercial. Anybody can always sell FOSS software for money...

    Comment by hari (blog owner) on Fri, Dec 15, 2006 @ 10:25 IST #
  30. Static linking is not so bad. Especially when your program reqs. unusual libraries. Very good idea is to use UPX on statically linked binary to reduce its size.

    Comment by Vinicius (visitor) on Fri, Dec 15, 2006 @ 18:09 IST #
  31. Vinicius, precisely. There are always exceptional cases where static libraries are better - as you said - in the case of unusual libraries. But in general, shared libraries are preferable :smile:

    Comment by hari (blog owner) on Fri, Dec 15, 2006 @ 18:16 IST #

  32. Comment by peuster.org » Blog Archive » links for 2006-12-15 (visitor) on Sat, Dec 16, 2006 @ 22:32 IST #

  33. Comment by TeraOpen: The Small Space of the TI (visitor) on Sun, Dec 17, 2006 @ 09:10 IST #
  34. Thanks Hari for all of these good advices. As a beginner I was looking for such guidance. Thanks again

    Comment by Hameed Khan (visitor) on Tue, Dec 19, 2006 @ 19:18 IST #
  35. URL Title:...


    Comment by wagthis.com (visitor) on Sat, Jan 6, 2007 @ 13:04 IST #
  36. Great plugin may be... Thanks!

    Comment by Anker (visitor) on Wed, Aug 29, 2007 @ 01:07 IST #
  37. Do you know where I can watch a demo of linux basic.

    Comment by samantha manzano (visitor) on Fri, Oct 3, 2008 @ 01:03 IST #

Comments closed

The blog owner has closed further commenting on this entry.