How to Get Started Developing on *Nix

How to get started developing on *nix

Read some good books, notably Advanced Linux Programming and Advanced Unix Programming. Read also the advanced bash scripting guide and other documentation from Linux Documentation Project

Obviously, install some Linux distribution on your laptop (not in some VM, but on real disk partitions). If you have a debian like distribution, run aptitude build-dep gcc-4.6 gedit on it to get a lot of interesting developers packages.

Learn some command line skills. Learn to use the man command; after installing manpages and manpages-dev packages, type man man (use the space bar to "scroll text", the q key to quit). Read also the intro(2) man page. When you forgot how to use a command like cp try cp --help.

Use a version control system like git, even for one person tiny projects.

Backup your files.

Read several relevant Wikipedia pages on Linux, kernels, syscalls, free software, X11, Posix, Unix

Try hard to use the command line. For instance, try to do everything on the command line for a week or more. Avoid using your desktop, and possibly your mouse. Learn to use emacs.

Read about builder programs like GNU make

Retrieve several free software from their source code (e.g. from sourceforge or freecode or github) and practice building and compiling them. Study their source code

Basic tips to start (if a command is not found, you need to install the package providing it) in command line (in a terminal).

  • run emacs ; there is a tutorial menu; practice it for half an hour.

  • edit a helloworld.c program (with a main calling some hello function)

  • compile it with gcc -g -Wall helloworld.c -o helloworld; improve your code till no warnings are given. Always pass -Wall to gcc or g++ to get almost all warnings.

  • run it with ./helloworld

  • debug it with gdb ./helloworld, then

    1. use the help command
    2. use the b main command to add a breakpoint in main and likewise for your hello function.
    3. run it under gdb using r
    4. use bt to get a backtrace
    5. use p to print some variable
    6. use c to continue the execution of the debugged program.
  • write a tiny Makefile to be able to build your helloworld program using make

  • learn how to call make (with M-x compile) and gdb (with M-x gdb) from inside Emacs

Learn more about valgrind (to detect most memory leaks). Perhaps consider using Boehm's GC in some of your applications.

How to use Nix to setup a development environment?

You can use nix-shell for this. It drops you into a shell configured to the given nix expression. Initially that expression could simply be along the lines of buildInputs = [ pkgs.ruby ]; and you can develop it from that. There are a number of helpful articles online written by nix users that give more examples of using nix-shell, like this one from garbas.si

You may also find it useful to get a better idea of how nix packages work. There's a separate nixpkgs manual that covers in greater detail using nix to create package expressions. A quick skim of the 3rd section should be useful to give a bit more understanding. There's also a chapter on using nix with ruby bundler that might be useful for you. Again there are articles that give more examples of its use, such as one from stesie.github.io.

If you need postgresql actually running in your environment nix won't manage that for you; its function is solely the building and management of packages, not their activation. You could simply activate postgres manually, use the nix-shell hook, or create some other integration with nix, but I think the most robust option is to make use of the Linux distribution that's built on top of Nix - NixOS. NixOS integrates with nix packages and manages the services provided by the packages. You could create a NixOS configuration with postgres active and your development environment present. This utility from github.com/chrisfarms may also be of interest.

Linux programming - getting started, how?

Depends on how much you want to learn (from the easiest option to the hardest one):

  • Just use C# via Mono - that gives you access to most of the POSIX interfaces via Mono.UNIX, access to GTK# so you can do desktop apps, access to many linux libraries, so you can do more advanced stuff / integrate better. (you can program in Monodevelop - it's a Sharpdevelop clone, kind of VS-ish)
  • Learn Vala - it's a language compiled down to C, very similar to C# but closer to the bare minimum. It's gathers anti-MS people who wanted a response to C# IMHO. (never really used it, but apparently there's a Vala plugin for Monodevelop and the language itself is becoming more popular)
  • Learn Python - it's a scripting language. It's got bindings to most popular libraries (also GTK and QT) (IDE: anything that can edit text - you won't get good intellisense from a dynamic language anyways)
  • Learn C++ and QT, or C and GTK - although those are very low level languages where you will spend a lot of time just getting used to the environment. (IDE: Anjuta, Kdevelop, Monodevelop with C++ plugin, Eclipse+CDT, emacs, vim, etc. - anything goes really)

If you want "something new", but don't want to spend loads of time learning a completely new environment, I'd recommend trying out Vala. If you're more curious about different styles, go for Python, which I think has a very good tutorial for new people (but not new to programming): Tutorial or Beginner's Guide. With Python you also have an advantage of having the whole environment available in packages in any distribution, no such luck with Vala (yet).

shifting from windows to *nix programming platform

Linux is the most accessible and has the most mature desktop functionality. BSD (in its various flavours) has less userspace baggage and would be easier to understand at a fundamental level. In this regard it is more like a traditional Unix than a modern Linux distribution. Some might view this as a good thing (and from certain perspectives it is) but will be more alien to someone familiar with Windows.

The main desktop distributions are Ubuntu and Fedora. These are both capable systems but differ somewhat in their userspace architecture The tooling for the desktop environment and default configuration for system security works a bit differently on Ubuntu than it does on most other Linux or Unix flavours but this is of little relevance to development. From a user perspective either of these would be a good start.

From a the perspective of a developer, all modern flavours of Unix and Linux are very similar and share essentially the same developer tool chain. If you want to learn about the system from a programmer's perspective there is relatively little to choose.

Most unix programming can be accomplished quite effectively with a programmer's editor such as vim or emacs, both of which come in text mode and windowing flavours. These editors are very powerful and have rather quirky user interfaces - the user interfaces are ususual but contribute significantly to the power of the tools. If you are not comfortable with these tools, this posting discusses several other editors that offer a user experience closer to common Windows tooling.

There are several IDEs such as Eclipse that might be of more interest to someone coming off Windows/Visual Studio.

Some postings on Stackoverflow that discuss linux/unix resources are:

  • What are good linux-unix books for an advancing user

  • What are some good resources for learning C beyond K&R

  • Resources for learning C program design

If you have the time and want to do a real tour of the nuts and bolts Linux From Scratch is a tutorial that goes through building a linux installation by hand. This is quite a good way to learn in depth.

For programming, get a feel for C/unix from K&R and some of the resources mentioned in the questions linked above. The equivalent of Petzold, Prosise and Richter in the Unix world are W Richard Stevens' Advanced Programming in the Unix Environment and Unix Network Programming vol. 1 and 2.

Learning one of the dynamic languages such as Perl or Python if you are not already familiar with these is also a useful thing to do. As a bonus you can get good Windows ports of both the above from Activestate which means that these skills are useful on both platforms.

If you're into C++ take a look at QT. This is arguably the best cross-platform GUI toolkit on the market and (again) has the benefit of a skill set and tool chain that is transferrable back into Windows. There are also several good books on the subject and (as a bonus) it also works well with Python.

Finally, Cygwin is a unix emulation layer that runs on Windows and gives substantially unix-like environment. Architecturally, Cygwin is a port of glibc and the crt (the GNU tool chain's base libraries) as an adaptor on top of Win32. This emulation layer makes it easy to port unix/linux apps onto Cygwin. The platform comes with a pretty complete set of software - essentially a full linux distribution hosted on a Windows kernel. It allows you to work in a unix-like way on Windows without having to maintain a separate operating system installations. If you don't want to run VMs, multiple boots or multiple PCs it may be a way of easing into unix.

Tutorials for setting up a robust small-to-medium project *nix build

I'd strongly suggest using one of the newer cousins of Make instead of autoconf or makefiles for smaller projects. One of the best ones for you (and the one I mostly love) could be premake4. Why do I suggest it? Because it's extremely simple to use, yet quite powerful, and capable of producing GNU Makefiles, Visual Studio projects, Code::Blocks projects and many more. And the premake files are very clear and readable, using the Visual Studio nomenclature that you're already familliar with.

Here's an example:

-- A solution contains projects, and defines the available configurations
solution "MyApplication"
configurations { "Debug", "Release" }

-- A project defines one build target
project "MyApplication"
kind "ConsoleApp"
language "C++"
files { "inc/**.h", "src/**.cpp", "main.cpp" }

configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }

configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }

Using hoogle in a haskell development environment on nix

Here's what my Nix Haskell dev environment looks like

in ~/.nixpkgs/config.nix:

The environment helper function

First off, define a haskellEnvFun function for building Haskell environments:

packageOverrides = super: rec {

haskellEnvFun = { withHoogle ? false, compiler ? null, name }:
let hp = if compiler != null
then super.haskell.packages.${compiler}
else haskellPackages;

ghcWith = if withHoogle
then hp.ghcWithHoogle
else hp.ghcWithPackages;

in super.buildEnv {
name = name;
paths = [(ghcWith myHaskellPackages)];
};

Defining some environments

Call this function to define two environments: one for running the Hoogle builder on changes, and one without:

haskellEnvHoogle = haskellEnvFun {
name = "haskellEnvHoogle";
withHoogle = true;
};

haskellEnv = haskellEnvFun {
name = "haskellEnv";
withHoogle = false;
};

Packages

Define all the packages you want to use in your local Haskell dev environment:

myHaskellPackages = hp: with hp; [
Boolean
HTTP
HUnit
MissingH
QuickCheck
SafeSemaphore
Spock
aeson
async
attoparsec
bifunctors
blaze-builder
blaze-builder-conduit
blaze-builder-enumerator
blaze-html
blaze-markup
blaze-textual
cased
cassava
cereal
comonad
comonad-transformers
directory_1_2_4_0
dlist
dlist-instances
doctest
exceptions
fingertree
foldl
free
hamlet
hashable
hspec
hspec-expectations
html
http-client
http-date
http-types
io-memoize
keys
language-c
language-javascript
language-bash
lens
lens-action
lens-aeson
lens-datetime
lens-family
lens-family-core
lifted-async
lifted-base
linear
list-extras
list-t
logict
mime-mail
mime-types
mmorph
monad-control
monad-coroutine
monad-loops
monad-par
monad-par-extras
monad-stm
monadloc
mongoDB
monoid-extras
network
newtype
numbers
optparse-applicative
parsec
parsers
pcg-random
persistent
persistent-mongoDB
persistent-template
pipes
pipes-async
pipes-attoparsec
pipes-binary
pipes-bytestring
pipes-concurrency
pipes-csv
pipes-extras
pipes-group
pipes-http
pipes-mongodb
pipes-network
pipes-parse
pipes-safe
pipes-shell
pipes-text
posix-paths
postgresql-simple
pretty-show
profunctors
random
reducers
reflection
regex-applicative
regex-base
regex-compat
regex-posix
regular
relational-record
resourcet
retry
rex
safe
sbv
scotty
semigroupoids
semigroups
shake
shakespeare
shelly
simple-reflect
speculation
split
spoon
stm
stm-chans
stm-stats
streaming
streaming-bytestring
streaming-wai
strict
stringsearch
strptime
syb
system-fileio
system-filepath
tagged
taggy
taggy-lens
tar
tardis
tasty
tasty-hspec
tasty-hunit
tasty-quickcheck
tasty-smallcheck
temporary
test-framework
test-framework-hunit
text
text-format
time
tinytemplate
transformers
transformers-base
turtle
uniplate
unix-compat
unordered-containers
uuid
vector
void
wai
wai-conduit
warp
wreq
xhtml
yaml
zippers
zlib
];

Shell helpers

In your ~/.profile define a couple bash functions to load those environments for convenience:


env-type () {
envtype="$1"
shift
nix-shell -Q -p $envtype "$@"
}

haskell-env () {
env-type "haskellEnv" "$@"
}

haskell-env-hoogle () {
env-type "haskellEnvHoogle" "$@"
}

Hoogle

Call haskell-env-hoogle in your shell. This will build all of your packages + docs and load you into an environment with hoogle in scope. At this point I usually type:

hoogle server --local -p 8080 &> /tmp/hoogle.log & disown

to launch a hoogle server the the background. Eventually I want to have a systemd service for this so that I can just nixos-rebuild to regen docs and launch the server automatically.

Emacs

For emacs I've set the haskell-hoogle-url to http://localhost:8080/?hoogle=%s, so that I can get local hoogle docs for keywords under my cursor. I use spacemacs so I just type , h h for this functionality.

You can see my full nixpkgs config here: https://github.com/jb55/nix-files/blob/659798f2ca81fb7ad0cb5a29de576024ee16eef8/nixpkgs/config.nix#L20

Hope that helps.

Any lightweight *nix environment for programming

Actually, a machine that you do development on shouldn't be lightweight. It should be heavy. full of compilers, interpreters, profilers, debuggers, IDEs, editors, benchmarks, checked-out code from repos, development versions of system libraries, test suites, generated large test files, backup tools, virtual machines, chroots, music to set-up comfort environment, mail, office suite to do the paperwork.

I mean, install Putty and connect to your machine (a), or do all development on virtual machine (b), that is kept on external hard drive (that's what I did, when I needed this), so you can use it everywhere where VirtualBox can run.

As for linuxes, I personally would like to use Gentoo Linux, as it can be customized to be lightweight. But unless you're really experienced with all linux administration stuff, customization may take a lot of time. So as a (c) variant, I'd advise to use any distribution (like your Mandriva), because normally base system takes about 10% of "weight" that you need for development on top of that.

And, by the way, boot speed is irrelevant on VirtualBox, since you can save virtual machine state entirely on hard drive and restore it within seconds.



Related Topics



Leave a reply



Submit