My cmake Bootstrap Process

I’ve been using eclipse as an IDE for a long time. For Java, eclipse is ridiculously beautiful. It almost writes your programs for you. Eclipse CDT is lacking a some features I would really like to see, and it’s impossible to understand the code base and write plugins (and so… I have not implemented anything myself) however, as a traditionalist, I like my IDE to work on top of the command line tools, not in place of them. Also, I like that there are PHP, Javascript, XML, Perl, and Latex plugins… which means that my life is much easier given that I work on all my projects with the same familiar interface.

Lately, I’ve also started using CMake (instead of my ridiculously complicated but super-stream-lined personal makefile system). The CMake project generator for Eclipse is really awesome, and I’m completely sold on using cmake now. However, creating a new project from within eclipse doesn’t work as well as I’d like. Also, I have a couple of other files that I generally include in every project, so I’ve started bootstrapping my projects by using a template directory, and a pair of scripts.

Consequently I find myself repeating several tasks every time I start a new project… just like when I was starting off with programming.

  1. copy an old project
  2. rip out all the unnecessary classes
  3. chop of the CMakeLists.txt files to get it down to a bare bones
  4. initialize a git repository
  5. make an initial commit
  6. create a build directory
  7. export my development root directory so cmake can find it
  8. call cmake (which, for eclipse projects, is a chore)

All this gets a little tedious. I’d really like to have an eclipse plugin that does this… but I’m not that skilled in the advanced features of Eclipse, so I started automating this with a script. Most of the things that I’ve been working on lately have been Gtkmm programs. So I’ve created a barebones project directory with stubs for all of the common parts I need:

  • all the gtkmm cmake find modules
  • a stub CMakeFile.txt
  • a stub glade file
  • a stub UI xml file
  • a simple main.cpp
  • one class called Application to load the glade file and the UI
  • some git helper scripts
  • a .gitignore file
  • a doxyfile
  • a doxygen mainpage file
  • a bootstrap script

I also wrote a script which does all of the redundant tasks mentioned above. I’ll go through all the files in the template directory and the new project script describing what they’re for. The template files can be downloaded as a gzipped tarball here. The new project script can be retrieved here

Scripts I Always Use

countlines.pl

This is a simple script that I use to count the number of lines of code in a project. It reports the total number of lines of code as a raw number, exluding whitespace, and exluding comments.

#!usr/bin/perl
 
my @extensions  = ("cpp","h","hpp");
my @directories = ("src");
my @filelist;
 
foreach $directory( @directories )
{
    print "searching $directoryn";
    foreach $extension( @extensions )
    {
        print "   for *.$extensionn";
        open INLIST, " find $directory -name '*.$extension' |";
        while()
        {
            chomp;
            push(@filelist, $_);
        }
        close INLIST;
    }
}
 
$totallines     = 0;
$written        = 0;
$noncomment     = 0;
 
my $blockcomment    = 0;
my $comment         = 0;
 
print "parsing filesn";
 
foreach $file( @filelist )
{
    print "   $filen";
    open INFILE, "./" . $file or die "failed to open" . $file . "n";
 
    while()
    {
        chomp;
        s/s//g;
 
        $totallines++;
 
        $comment        = 0;
        if( /^(//)/ )   {$comment        = 1;  }
        if( /(/*)/ )    {$blockcomment   = 1;  }
        if( /(*/)/ )    {$blockcomment   = 0;  }
 
        $noncomment++   unless( length($_) == 0 || $comment || $blockcomment );
        $written++      unless( length($_) == 0 );
    }
 
    close INFILE;
}
 
print "n";
print "total:       " . $totallines     . "n";
print "written:     " . $written        . "n";
print "noncomment:  " . $noncomment     . "n";
 
$dummy = <>;

logChanges.sh

This is a helper script I use to format my git commits the way I like. I like to have a list of all the files changed at each commit stored right in the log. This script strips the comment hashes from the git status report.

#!/bin/bash
 
echo ""
echo "Files Changed:"
git status | sed -e "s/#t//" -e "/^#/d"

commitAll.sh

This is a script that I call to commit all changes to the git repository. It calls logChanges.sh to generate a changelog changes.txt, and then opens nano to add a nice comment to the log entry.

#!/bin/bash
 
git add -A
bash logChanges.sh > changes.txt
nano changes.txt
git commit -F changes.txt

bootstrap.sh

This is a script that calls cmake from the build directory. It prepends $HOME/Codes/devroot to the CMake prefix path so that it can find all of my develepment libraries. It adds the corresponding lib/pkgconfig directory to the PKG_CONFIG_PATH variable so that pkg-config looks for my development library versions before checking the system versions. It also sets the prefix-path directory to be the install prefix. Then it calls cmake to generate Eclipse CDT4 project files, along with a source project and the option to build with debug flags.

#!/bin/bash
 
export PREFIX=$HOME/Codes/devroot
 
export SCRIPT_DIR=`dirname $0`;
export CMAKE_PREFIX_PATH=$PREFIX:CMAKE_PREFIX_PATH
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig/:PKG_CONFIG_PATH
cmake -G "Eclipse CDT4 - Unix Makefiles" -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PREFIX $SCRIPT_DIR

Configuration Files

doxy.config.in

Doxygen configuration file. The project, version, paths, and some other things are set via cmake variables

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING      = UTF-8
PROJECT_NAME           = "${PROJECT_NAME}"
PROJECT_NUMBER         = v${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_BUGFIX}
OUTPUT_DIRECTORY       = ./doc
CREATE_SUBDIRS         = NO
OUTPUT_LANGUAGE        = English
BRIEF_MEMBER_DESC      = YES
REPEAT_BRIEF           = YES
ABBREVIATE_BRIEF       =
ALWAYS_DETAILED_SEC    = YES
INLINE_INHERITED_MEMB  = NO
FULL_PATH_NAMES        = YES
STRIP_FROM_PATH        = ${CMAKE_CURRENT_SOURCE_DIR}/src
STRIP_FROM_INC_PATH    = {CMAKE_CURRENT_SOURCE_DIR}/src/
SHORT_NAMES            = NO
JAVADOC_AUTOBRIEF      = NO
QT_AUTOBRIEF           = NO
MULTILINE_CPP_IS_BRIEF = YES
INHERIT_DOCS           = YES
SEPARATE_MEMBER_PAGES  = NO
TAB_SIZE               = 4
ALIASES                =
OPTIMIZE_OUTPUT_FOR_C  = NO
OPTIMIZE_OUTPUT_JAVA   = NO
OPTIMIZE_FOR_FORTRAN   = NO
OPTIMIZE_OUTPUT_VHDL   = NO
EXTENSION_MAPPING      =
BUILTIN_STL_SUPPORT    = YES
CPP_CLI_SUPPORT        = NO
SIP_SUPPORT            = NO
IDL_PROPERTY_SUPPORT   = YES
DISTRIBUTE_GROUP_DOC   = NO
SUBGROUPING            = YES
TYPEDEF_HIDES_STRUCT   = NO
SYMBOL_CACHE_SIZE      = 0
 
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL            = YES
EXTRACT_PRIVATE        = YES
EXTRACT_STATIC         = NO
EXTRACT_LOCAL_CLASSES  = YES
EXTRACT_LOCAL_METHODS  = NO
EXTRACT_ANON_NSPACES   = NO
HIDE_UNDOC_MEMBERS     = NO
HIDE_UNDOC_CLASSES     = NO
HIDE_FRIEND_COMPOUNDS  = NO
HIDE_IN_BODY_DOCS      = NO
INTERNAL_DOCS          = NO
CASE_SENSE_NAMES       = NO
HIDE_SCOPE_NAMES       = NO
SHOW_INCLUDE_FILES     = YES
FORCE_LOCAL_INCLUDES   = NO
INLINE_INFO            = YES
SORT_MEMBER_DOCS       = YES
SORT_BRIEF_DOCS        = YES
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES       = YES
SORT_BY_SCOPE_NAME     = YES
GENERATE_TODOLIST      = YES
GENERATE_TESTLIST      = YES
GENERATE_BUGLIST       = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS       =
MAX_INITIALIZER_LINES  = 30
SHOW_USED_FILES        = YES
SHOW_DIRECTORIES       = YES
SHOW_FILES             = YES
SHOW_NAMESPACES        = YES
FILE_VERSION_FILTER    =
LAYOUT_FILE            =
 
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET                  = NO
WARNINGS               = YES
WARN_IF_UNDOCUMENTED   = YES
WARN_IF_DOC_ERROR      = YES
WARN_NO_PARAMDOC       = NO
WARN_FORMAT            = "$file:$line: $text"
WARN_LOGFILE           =
 
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ${CMAKE_CURRENT_SOURCE_DIR}/src
        ${CMAKE_CURRENT_SOURCE_DIR}/include
        ${CMAKE_CURRENT_SOURCE_DIR}/docs/pages
        ${CMAKE_CURRENT_BINARY_DIR}/src
        ${CMAKE_CURRENT_BINARY_DIR}/include
        ${CMAKE_CURRENT_BINARY_DIR}/docs/pages   
 
INPUT_ENCODING         = UTF-8
FILE_PATTERNS          = *.cpp
                         *.h
                         *.hpp
RECURSIVE              = YES
EXCLUDE                =
EXCLUDE_SYMLINKS       = NO
EXCLUDE_PATTERNS       =
EXCLUDE_SYMBOLS        =
EXAMPLE_PATH           =
EXAMPLE_PATTERNS       =
EXAMPLE_RECURSIVE      = NO
IMAGE_PATH             =
INPUT_FILTER           =
FILTER_PATTERNS        =
FILTER_SOURCE_FILES    = NO
 
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER         = YES
INLINE_SOURCES         = NO
STRIP_CODE_COMMENTS    = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION    = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS              = NO
VERBATIM_HEADERS       = YES
 
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX     = NO
COLS_IN_ALPHA_INDEX    = 5
IGNORE_PREFIX          =
 
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML          = YES
HTML_OUTPUT            = html
HTML_FILE_EXTENSION    = .html
HTML_HEADER            =
HTML_FOOTER            =
HTML_STYLESHEET        =
HTML_TIMESTAMP         = YES
HTML_ALIGN_MEMBERS     = YES
HTML_DYNAMIC_SECTIONS  = NO
GENERATE_DOCSET        = NO
DOCSET_FEEDNAME        = "Doxygen generated docs"
DOCSET_BUNDLE_ID       = org.doxygen.Project
GENERATE_HTMLHELP      = NO
CHM_FILE               =
HHC_LOCATION           =
GENERATE_CHI           = NO
CHM_INDEX_ENCODING     =
BINARY_TOC             = NO
TOC_EXPAND             = NO
GENERATE_QHP           = NO
QCH_FILE               =
QHP_NAMESPACE          =
QHP_VIRTUAL_FOLDER     = doc
QHP_CUST_FILTER_NAME   =
QHP_CUST_FILTER_ATTRS  =
QHP_SECT_FILTER_ATTRS  =
QHG_LOCATION           =
GENERATE_ECLIPSEHELP   = NO
ECLIPSE_DOC_ID         = org.doxygen.Project
DISABLE_INDEX          = NO
ENUM_VALUES_PER_LINE   = 4
GENERATE_TREEVIEW      = YES
USE_INLINE_TREES       = NO
TREEVIEW_WIDTH         = 400
FORMULA_FONTSIZE       = 12
SEARCHENGINE           = NO
SERVER_BASED_SEARCH    = NO
 
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX         = NO
LATEX_OUTPUT           = latex
LATEX_CMD_NAME         = latex
MAKEINDEX_CMD_NAME     = makeindex
COMPACT_LATEX          = YES
PAPER_TYPE             = letter
EXTRA_PACKAGES         = amsmath
                         amsfonts
                         hyperref
LATEX_HEADER           =
PDF_HYPERLINKS         = YES
USE_PDFLATEX           = YES
LATEX_BATCHMODE        = YES
LATEX_HIDE_INDICES     = NO
LATEX_SOURCE_CODE      = NO
 
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF           = NO
RTF_OUTPUT             = rtf
COMPACT_RTF            = NO
RTF_HYPERLINKS         = NO
RTF_STYLESHEET_FILE    =
RTF_EXTENSIONS_FILE    =
 
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN           = NO
MAN_OUTPUT             = man
MAN_EXTENSION          = .3
MAN_LINKS              = NO
 
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML           = YES
XML_OUTPUT             = xml
XML_SCHEMA             =
XML_DTD                =
XML_PROGRAMLISTING     = NO
 
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF   = NO
 
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD       = NO
PERLMOD_LATEX          = NO
PERLMOD_PRETTY         = YES
PERLMOD_MAKEVAR_PREFIX =
 
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING   = YES
MACRO_EXPANSION        = NO
EXPAND_ONLY_PREDEF     = NO
SEARCH_INCLUDES        = YES
INCLUDE_PATH           =
INCLUDE_FILE_PATTERNS  =
PREDEFINED             =
EXPAND_AS_DEFINED      =
SKIP_FUNCTION_MACROS   = YES
 
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES               =
GENERATE_TAGFILE       = ${PROJECT_NAME}.tag
ALLEXTERNALS           = NO
EXTERNAL_GROUPS        = YES
PERL_PATH              = /usr/bin/perl
 
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS         = YES
MSCGEN_PATH            = ${CMAKE_MSCGEN_PATH}
HIDE_UNDOC_RELATIONS   = YES
HAVE_DOT               = NO
DOT_FONTNAME           = FreeSans
DOT_FONTSIZE           = 10
DOT_FONTPATH           =
CLASS_GRAPH            = YES
COLLABORATION_GRAPH    = YES
GROUP_GRAPHS           = YES
UML_LOOK               = NO
TEMPLATE_RELATIONS     = NO
INCLUDE_GRAPH          = YES
INCLUDED_BY_GRAPH      = YES
CALL_GRAPH             = NO
CALLER_GRAPH           = NO
GRAPHICAL_HIERARCHY    = YES
DIRECTORY_GRAPH        = YES
DOT_IMAGE_FORMAT       = png
DOT_PATH               = ${CMAKE_DOT_PATH}
DOTFILE_DIRS           =
DOT_GRAPH_MAX_NODES    = 50
MAX_DOT_GRAPH_DEPTH    = 0
DOT_TRANSPARENT        = NO
DOT_MULTI_TARGETS      = NO
GENERATE_LEGEND        = YES
DOT_CLEANUP            = YES

CMakeLists.txt

The root CMakeLists file. The project name is replaced by the new project script

cmake_minimum_required(VERSION 2.8)
 
# defines the project name
project (projectName)
set( ${CMAKE_PROJECT_NAME}_VERSION_MAJOR 0 )
set( ${CMAKE_PROJECT_NAME}_VERSION_MINOR 1 )
set( ${CMAKE_PROJECT_NAME}_VERSION_BUGFIX 0 )
 
# adds the project-specific cmake module directory cmake/Modules to the cmake
# search path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 
# finds pkg-config
find_package(PkgConfig REQUIRED)
 
# add the src/ subdirectory to the list of directories cmake processes
add_subdirectory(src)
add_subdirectory(include)
 
# configure the doxygen configuration
configure_file(
    "${PROJECT_SOURCE_DIR}/doxy.config.in"
    "${PROJECT_BINARY_DIR}/doxy.config"
    )
 
# use Jan Woetzel's doxygen doc target
include("${CMAKE_MODULE_PATH}/TargetDoc.cmake" OPTIONAL)

src/CMakeLists.txt

The CMakeLists for the application.

find_package(GTKmm REQUIRED)
#find_package(Boost COMPONENTS iostreams REQUIRED)
 
include_directories(
#   ${Boost_INCLUDE_DIRS}
    ${GTKmm_INCLUDE_DIRS}
    )
 
set(LIBS ${LIBS}
#   ${Boost_LIBRARIES}
    ${GTKmm_LIBRARIES}
    )
 
add_executable( ${CMAKE_PROJECT_NAME} main.cpp Application.cpp)
 
target_link_libraries( ${CMAKE_PROJECT_NAME} ${LIBS})
 
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.glade
    ${CMAKE_CURRENT_BINARY_DIR}/mainwindow.glade COPYONLY )
 
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.xml
    ${CMAKE_CURRENT_BINARY_DIR}/mainwindow.xml COPYONLY )

New Project Script

start_new_project.sh

This is the script I use to start a new project. It copies the template directory to a new directory in $HOME/Codes/cpp/ named after the new project. It also replaces the project name in the root CMakeLists to the project name. It initializes a git repository in the source and make an initial commit with all the files. It then creates a build directory in $HOME/Codes/cpp/builds. It changes to that directory and then calls the bootstrap script to generate the project files and makefiles.

#!/bin/bash
 
EXPECTED_ARGS=1
if [ $# -ne $EXPECTED_ARGS ]
then
    echo "Usage: `basename $0` {arg}"
    exit 1
fi
 
PROJECT_DIR="$HOME/Codes/cpp/$1"
BUILD_DIR="$HOME/Codes/cpp/builds/$1"
TEMPLATE_DIR="$HOME/Codes/cpp/template"
 
if [ -d "$HOME/Codes/cpp/$1" ]
then
    echo "The directory '$PROJECT_DIR' already exists"
    exit 1
fi
 
echo "Making $PROJECT_DIR"
mkdir $PROJECT_DIR
 
echo "Copying files from $TEMPLATE_DIR to $PROJECT_DIR"
cp -rv $TEMPLATE_DIR/* $PROJECT_DIR/
 
echo "Setting project name in CMakeList.txt"
sed -i "s/projectName/$1/" $PROJECT_DIR/CMakeLists.txt
 
echo "Changing to project directory"
cd $PROJECT_DIR
echo "   pwd: `pwd`"
 
echo "Initializing the git repository"
git init
git add -A
git commit -m "Initial commit, template project"
 
echo "Changing to the build directory"
mkdir $BUILD_DIR
cd $BUILD_DIR
echo "   pwd: `pwd`"
 
echo "Bootstrapping cmake"
$PROJECT_DIR/bootstrap.sh

Program Source Files

src/main.cpp

/*
 *  file   main.cpp
 *  date   May 31, 2011
 */
 
#include 
#include "Application.h"
 
int main(int argc, char** argv)
{
    Gtk::Main kit(argc, argv);
    Application app;
    kit.run(app.getWindow());
}

src/Application.h

/*
 *  file   Application.h
 *  date   Mar 19, 2011
 */
 
#ifndef APPLICATION_H_
#define APPLICATION_H_
 
#include 
 
class Application
{
    private:
        Glib::RefPtr      m_builder;
        Glib::RefPtr    m_ui;
        Gtk::Window*                    m_mainWindow;
 
    public:
        Application();
        virtual ~Application();
 
        Gtk::Window& getWindow();
};
 
#endif /* Application_H_ */

src/Application.cpp

/*
 *  file   Application.cpp
 *  date   Apr 29, 2011
 */
 
#include "Application.h"
 
Application::Application():
    m_mainWindow(0)
{
    using namespace Glib;
    using namespace Gtk;
 
    m_builder = Builder::create_from_file("mainwindow.glade");
    m_mainWindow = 0;
    m_builder->get_widget("main_window",m_mainWindow);
 
    VBox* vbox = 0;
    m_builder->get_widget("main_vbox", vbox);
 
    m_ui = UIManager::create();
    m_ui->add_ui_from_file("mainwindow.xml");
    Gtk::Widget* menubar = m_ui->get_widget("/mb_main");
    Gtk::Widget* toolbar = m_ui->get_widget("/tb_main");
    vbox->pack_start(*menubar,false,false);
    vbox->pack_start(*toolbar,false,false);
    vbox->reorder_child(*menubar,0);
    vbox->reorder_child(*toolbar,1);
 
    m_mainWindow->show_all();
}
 
Application::~Application()
{
 
}
 
Gtk::Window& Application::getWindow(){ return *m_mainWindow; }

src/mainwindow.glade

<!--?xml version="1.0" encoding="UTF-8"?-->
 
  <!-- interface-naming-policy project-wide -->
  <object id="main_window" class="GtkWindow">400300FalseGtkmm Stub300200      <object id="main_vbox" class="GtkVBox">TrueFalse          <object id="label1" class="GtkLabel">TrueFalseHello World          </object>
 
True
True
0
 
          <object id="statusbar1" class="GtkStatusbar">TrueFalse2          </object>
 
False
True
1
 
      </object>
 
  </object>

src/mainwindow.xml

 

1 Comment

Gtkmm 3.0 in Ubuntu 11.04

Lately I’ve been writing a lot of codes using gtkmm 3.0. The latest stable branch is 2.4, but this is based on GTK+ 2… and I really want to use GTK+ 3. Why? Because GTK+ 3 uses cairo for it’s native drawing API, and cairo is sweet. gtkmm uses cairomm, which is even sweeter. So here are my notes on getting gtkmm-3 built and installed for Ubuntu 11.04. I’ve written a shell script to do all the work, but I’ll go through it section by section to explain what’s going on.

Setup

Traditionally /usr/ is used for normal system stuff /usr/local is for experimental stuff (it’s essentially the same as /usr but it makes it easy to find and remove stuff after it breaks your system). However, since I originally was developing with the unstable Gtkmm branch in Ubuntu 10.04, which didn’t even have a package for GTK+ 3 in the repositories, I started installing things into my home directory… since it’s just for testing anyway. Therefore, I create a directory $HOME/Codes/devroot (for development root filesystem) where I install all the “unstable” packages I’m using, or where I practice-install the programs/libraries I’m writing.

I also make a directory $HOME/Codes/cpp/gnome where I download all the source tarballs and do the building.

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
cd $HOME
 
export BASE=$HOME/Codes/devroot
export PATH=$BASE/bin:$PATH
export LD_LIBRARY_PATH=$BASE/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=$BASE/lib/pkgconfig:$PKG_CONFIG_PATH
export XDG_DATA_DIRS=$BASE/share:$XDG_DATA_DIRS
export ACLOCAL_FLAGS="-I $BASE/share/aclocal $ACLOCAL_FLAGS"
 
mkdir -p $BASE
mkdir -p Codes/cpp/gnome
cd Codes/cpp/gnome

Next I export some variables containing the versions of the unstable packages I’m using. This is so that I can quickly update the script for future installations and things.

15
16
17
18
19
20
export MM_COMMON_VER=0.9.5
export GLIBMM_VER=2.28.1
export ATKMM_VER=2.22.5
export PANGOMM_VER=2.28.2
export CAIROMM_VER=1.1.10
export GTKMM_VER=3.0.1

Then I download all the source tarballs

22
23
24
25
26
27
wget http://ftp.acc.umu.se/pub/GNOME/sources/mm-common/0.9/mm-common-$MM_COMMON_VER.tar.gz
wget http://ftp.acc.umu.se/pub/GNOME/sources/glibmm/2.28/glibmm-$GLIBMM_VER.tar.gz
wget http://ftp.acc.umu.se/pub/GNOME/sources/atkmm/2.22/atkmm-$ATKMM_VER.tar.gz
wget http://ftp.acc.umu.se/pub/GNOME/sources/pangomm/2.28/pangomm-$PANGOMM_VER.tar.gz
wget http://ftp.acc.umu.se/pub/GNOME/sources/gtkmm/3.0/gtkmm-$GTKMM_VER.tar.gz
wget http://cairographics.org/snapshots/cairomm-$CAIROMM_VER.tar.gz

And extract them all into $HOME/Codes/cpp/gnome (currently PWD).

29
30
31
32
33
34
tar xvzf mm-common-$MM_COMMON_VER.tar.gz
tar xvzf glibmm-$GLIBMM_VER.tar.gz
tar xvzf atkmm-$ATKMM_VER.tar.gz
tar xvzf pangomm-$PANGOMM_VER.tar.gz
tar xvzf gtkmm-$GTKMM_VER.tar.gz
tar xvzf cairomm-$CAIROMM_VER.tar.gz

Then we start installing the packages in the appropriate order. There are a few ugly things that we have to do in the process though.

36
37
38
39
40
41
42
43
44
45
cd mm-common-$MM_COMMON_VER
./configure --prefix=$BASE
make -j6
make install
cd ..
 
cd glibmm-$GLIBMM_VER
./configure --prefix=$BASE
make -j6
make install

The first ugly thing is that the glibmm package doesn’t install the doctool perl script like it should… so we have to do that manually:

46
47
mkdir -p $BASE/share/glibmm-2.4/doctool/
cp docs/doc-install.pl $BASE/share/glibmm-2.4/doctool/

Then we continue installing the libraries

48
49
50
51
52
53
54
55
56
57
cd ..
 
cd atkmm-$ATKMM_VER
./configure --prefix=$BASE
make -j6
make install
cd ..
 
cd pangomm-$PANGOMM_VER
./configure --prefix=$BASE

The second ugly thing we have to do is move libfreetype.la to where libtool can find it. I’m not sure why it can’t find this specific library but for whatever reason, even after setting LD_LIBRARY_PATH it always looks in /usr/lib. So I just pretend like no ones watching and create a symlink.

58
sudo ln -s /usr/lib/x86_64-linux-gnu/libfreetype.la /usr/lib/

And everything after that goes pretty normally.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
make -j6
make install
cd ..
 
cd cairomm-$CAIROMM_VER
./configure --prefix=$BASE
make -j6
make install
cd ..
 
cd gtkmm-$GTKMM_VER
./configure --prefix=$BASE
make -j6
make install
cd ..

No Comments

Getting Inkscape to Use Latex Fonts (in Windows)

Introduction

Creating graphics for latex can be a real pain. There are a number of different options for doing this, though none of them is completely ideal. If you’re comfortable using regular latex and generating DVI’s, then the pstricks package is a very powerful tool. If you prefer generating PDF (now an open standard) files (as I do) then the PGF/TikZ latex packages are a very powerful and can do just about everything… except that you have to code your graphics… which is a very slow iterative process. The GNU Diagramming tool Dia can create block diagrams and flow charts and can export either pstricks or tikz code. Inkscape is a much nicer user-oriented graphical vector drawing tool, but doesn’t have native support for for LaTex, and creating graphics including LaTeX math-mode is a real pain. In any case, I’ve found a number of situations where a figure like the following was pretty easy to do create in Inkscape.

Inkscape Figure for LaTeX

Inkscape Figure for LaTeX

Getting the Fonts

In order to get the math font’s to look like they do in LaTeX, though, you need to have the font’s installed where Inkscape can find them. Unfortunately, LaTex uses type1 postscript fonts, while Inkscape can only find font’s that windows has installed in the system, which includes true-type or open-type fonts. Fortunately you can get the fonts for “Computer Modern” (Knuth’s Font uses as the default in LaTeX) from the TeX archives in these formats. Simply download these fonts, and install them in windows (drag them to C:/Windows/Fonts). The next time you run Inkscape, it will have these font’s available and you can use them in your pretty graphics.

Other Fonts

There are some other font’s that you’ll find used by latex that aren’t in OTF or TTF format though. The only (open-source) way I’ve found to convert type-1 font’s to OTF is through an ancient tool called Font-Forge. It’s an X-Windows program so you’ll have to install the Cygwin x-server, or, luckily, someone has ported it to MinGW (native Win32).

Tex Text plugin

Lately, I’ve been using the Tex Text plugin instead of using latex fonts with regular inkscape text. The interface is a little tedious, but it works quite well (and it’s a lot less tedious then laying out the text by hand).

1 Comment