Makefile tutorial — June 4, 2014

Makefile tutorial

Compiling a source code files can be tedious, specially when you want to include several source files and have to type the compiling command every single time. That’s one of the reasons why I decided to look into Makefiles. It was a very fun task to learn about Makefiles. I’m writing this post as a short introduction to the Makefiles.

Makefiles are special format files that together with the make utility will help you to build and manage projects.

Comments

The comment is indicated by the comment character “#”.

Variables

Variables that are used in Makefiles may come from a large number of places; variables may be defined in the Makefile itself, or in Make’s large database of predefined variables, or in the command line invocation of Make, or within the environment. The following variables have special significance:

  • CFLAGS – gives a list of flags that should be passed to the C compiler
  • CPPFLAGS –  gives a list of flags that should be passed to the C/C++ preprocessor
  • CXXFLAGS – gives a list of flags that should be passed to the C++ compiler
  • LDFLAGS – gives a list of flags that should be passed to the linker.

Make defines variables for a variety of tools and utilities. The following variables are automatically defined by make:

  • CC – specifies the system’s default C compiler
  • CPP –  specifies the system’s default C preprocesor
  • CXX – specifies the system’s default C++ compiler
  • LD – specifies the system’s default linker.

Macros

A macro definition consists of a macro name, an equal sign “=”, and a macro value. Make replaces $(name) with the appropriate definition. Make automatically imports environmental variables as macros, so you can reference the environmental variable PATH with the expression $(PATH).

For instance: MACRONAME=value

Rules, Targets and Dependency List

A basic syntax of the Makefile can be seen on the Figure 1. A rule specifies when and how to remake targets. It lists the files that are prerequisites of the target, and commands to create or update the target. A target most of the time is a file to be created/updated. target depends upon a set of source files or other targets described in Dependency List. For each target, make checks the modification time of the corresponding dependency files to determine whether the target needs to be rebuilt using the corresponding command.

makefile_syntax

Figure 1: Makefile general syntax

The make process is recursive. Target’s sources are made before the timestamp comparison occurs. This means that file1 and file2 are made before their timestamps are compared with target.

Dependency Rules indicate that if any file to the right of the colon changes, the target to the left of the colon should be considered out-of-date. Pattern Rules are often used for compile-line.

Conventional Targets

By convention, every Makefile is expected to support the following targets:

  • all
  • clean
  • distclean

When make is invoked, it automatically builds the first target listed in the Makefile. This target should be named all and should depend on all other targets and/or build products the Makefile is producing. The clean target removes the result and any intermediate build products of invoking make all. The make distclean target does everything that make clean does, except that it may also remove additional configuration information.

Phony Targets

Sometimes target does not mean a file but it might represent an action to be performed. When a target is not related to a file it is called phony target.

For instance:
getobj:
    -mv obj/*.o . 2>/dev/null

getobj target moves all files with .o extension from obj directory to current directory – not a big deal. However, you should be asking yourself: “What if there is no file in obj?”. In that case the mv command would return an error that would be passed to the make command.

Note: make command default behavior is to abort the processing when an error is detected while executing commands in rules.

To avoid the make command from aborting when an error occurs you can use a special character – (minus) preceding the mv command. There is another special character: @ – tells make not to print the command to standard output before executing.

There is a special phony target called all where you can group several main targets and phony targets.

More special characters

$?   List of dependencies changed more recently than current target.
$@  Name of current target.
$<  Name of current dependency.
$*  Name of current dependency without extension.

An Example

# Macros
CC=g++
CFLAGS=-g -Wall
RM=/bin/rm -f

all: main                      # ensure that every feature of the program is compiled
frog.o: frog.h frog.cc         # create the object file for frog.cc
        ${CC} ${CFLAGS} -c frog.cc

main.o: frog.h main.cc         # create the object file for the main file
        ${CC} ${CFLAGS} -c main.cc

main: main.o frog.o            # create the executable
      ${CC} ${CFLAGS} -o main main.o frog.o

clean:                         # rule for cleaning files generated during compilations
      ${RM} *.o main
GSoC Report #1 — June 3, 2014

GSoC Report #1

Two weeks of GSoC are behind our backs. From the very first day I have really dived deep into the code and had a lot of fun with it. Here is the first report of my work.

I’m really thankful for the feedback and comments you all gave me. As the whole idea is still in the development phase and nothing is strictly defined I considered some of your comments. I’m going to list the things that slightly changed from the initial proposal:

  • ‘Read mode’ vs ‘Preview mode’ – The mode in which user will be able to read the eBook will be called the ‘Read mode’, as it better describes its purpose.
  • DRM issue – For the begging it would be good to support listing and reading of DRM-free eBooks. Later on, one way to handle the DRM issue might be to authorize ‘GNOME Books’ application using an ID, but this could be further evaluated because there is also a clash of principles of DRM and freedom.
  • ‘GNOME Books’ integration with an existing store – a big plus would be to integrate ‘GNOME Books’ with different eBook stores. Defining a plugin API for eBook store fronts would probably be something that could be developed later on. For the begging it would be good to choose one store and try to integrate it with GNOME. Good online eBook store is Smashwords, and there is also Project Gutenberg.

EPUB.JS vs LIBGEPUB

Epub.js is a JavaScript library for rendering EPUB documents in the browser. Epub.js provides an interface for common eBook functions (such as rendering, persistence and pagination). While libgepub is a very simple GObject based library with only the core functionality needed to open an archive files and read HTML documents. Because epub.js provides most of the features for rendering .epub files I decided to look into it, and tried to build a simple application.

TEST APPLICATION DEVELOPED IN C

To start up I decided to make a test application in C, using GTK and WebKit. I’m using WebKit2 to load the library epub.js and render the eBook. WebKit is a huge project, and I’m just staring to discover all the functionality it provides. Using WebKit to present the eBook in the ePub format  has a big advantage, because it can interpret HTML, CSS and JavaScript, so there is no need to develop the backed for that interpretation.

At this point I came across an interesting fact.  To locally run epub.js through WebKit I had to run node.js server (or any http simple server) to avoid cross origin requests, because epub.js needs to access the local files using JavaScript. I’m still working on this, implementing some around solutions to the problem.

A very nice feature that comes with the WebKit is Inspector, the excellent debugger. You can use the property to turn on enable-developer-extras. This will cause “Inspect Element” to be added to the WebKit’s context menu.

The test application can render an an eBook in the .epub file format using epub.js and show it in the WebKit View. The screenshot of the test application can be seen on the Figure 1.

NEXT STEPS

  • Start a git repository
  • Port the test application to gjs
  • Overcome the cross origin issue with the URI schemes

gnome-books-Ctest

Figure 1: Screenshot of the test application

eBook application based on Documents — April 27, 2014

eBook application based on Documents

A goal of the Google Summer of Code project is to develop an eBook application for GNOME. An eBook application will use GNOME Documents as a relative. This post will give you an overview of the project. Your comments and toughs are very welcome.

Introduction

Documents is a document manager application. It integrates GNOME Online Accounts for accounts and credentials. The implemented features are: listing of the local and online documents in list and grid view, document preview, presentation view, search through documents, filtering, print, online edit mode for docs in Google drive, etc. The popularity of eBooks is constantly growing. There is need for the application which has functionality similar to eBook readers.

Project description

I’m proposing to develop an eBook application for listing, searching and reading eBooks, called gnome-books. The idea is to integrate gnome-books with an existing online eBook store. One option could be Google Books. It has millions of books from libraries and publishers worldwide, with the big collection of free eBooks. The user will have to login with his Google account in GNOME Online Accounts and approve access to Google Books.

gnome-books will be implemented upon the application gnome-documents, and it is going to live in the same git repository. This would be a great solution regarding code duplication, because it would be possible to reuse relevant code blocks from gnome-documents and add extra features related to eBooks.

The gnome-books application will have three different modes:

  1. Overview mode – user can see the list of his eBooks, local and from the online eBook store (by the filter he applies)
  2. Preview mode – user can read the eBooks from its collection
  3. eBookStore mode – which will open the web application inside gnome-documents to allow the user to buy new eBooks

Two ideas of how to implement Preview mode have been evaluated:

  1. Browser preview – using epub.js library [1]
    This solution will give gnome-books possibility to have a preview mode with some nice animations that HTML5 is delivering. Changing the interface, or adding the annotation functionality can be easily customized.
  2. Glib/GObject library for interfacing .epub files
    Integrate the library within the existing Evince Document library which is used in Documents. This solution would lead to a much faster interface for the user, because there is no need for opening a web browser to preview the eBook. A possible start could be libgepub [2] library. libgepub library is a GObject based library for handling and rendering .epub files. This library could be used to extend the Evince Document library with the functionality of interfacing .epub files which is going to be used by gnome-books.
    I have been researching this option so you can find more information in my post EPUB support in Evince.

Updates about the progress will come soon. Thank you for reading.

[1] epub java script library
[2] libgepub library

“A journey of a thousand miles must begin with a single step.”
– LAO-TZU, Tao Te Ching
Google Summer of Code 2014 — April 24, 2014

Google Summer of Code 2014

Let the fun begin!!!

logo-2014-600x540I’m very happy to announce that I am accepted to Google Summer of Code, and even more that I’ll contribute to GNOME.

I’ll be developing an application for listing, searching and reading eBooks, called gnome-books. The idea is to integrate gnome-books with an existing online eBook store. My mentor is Cosimo Cecchi. He was a great support during the application process and I am looking forward to work with him and the GNOME team.

I wish to all participants a great summer and fun with their projects.

EPUB support in Evince — April 13, 2014

EPUB support in Evince

Ubuntu & !(EPUB support) have pretty long history now.

Let’s change it!

Everyone would say that Ubuntu gets a big plus for having a handful of apps which handle out-of-the-box all of the most popular content formats. Unfortunately, that is not the case for EPUB. EPUB is free and open e-book standard that is widely used. To support it in Ubuntu a backend has to be implemented in the default document reader, Evince. You can also look at the bug report.
Evince_ePub

EPUB defines a means of representing, packaging and encoding structured and semantically enhanced Web content — including XHTML, CSS, SVG, images, and other resources — for distribution in a single-file format.
EPUB 2 was initially standardized in 2007.
In October, 2011, EPUB 3 superseded EPUB 2 as the current version when EPUB 3.0 was
approved as a final Recommended Specification.
[1]

Good start could be to use libgepub library. It provides an EPUB rendered widget using glib and webkit. It is based on libgxps. libgepub library is unfinished, therefore some work has to be done in order to add it to Evince.

Today’s post gives an overview of the first challenge that needs to be faced to support EPUB. That is a layout or pagination problem.

LAYOUT

The design center of EPUB is dynamic layout: content is typically intended to be formatted on the fly rather than being typeset in a paginated manner in advance (i.e., expecting a particular sized “page”). EPUB files are paginate with “optimal fill”: new “page” is created only when there is no more space for text on the previous page. The user has ability to adjust font size, preview mode and different settings, and pages will be dynamically created. This way of formatting means that the original page numbers, from the printed book will not correspond to the eBook ones. But they can be displayed in a format from-to (for example 1-3/100). This functionality has to be implemented as the backend solution in Evince. Versions of EPUB have different way of solving the pagination problem.

For EPUB version 2.0.1, some files use DAISY’s Navigation Control File (NCX) for pagination. In NCX’s pageList element contains navigation information for pages within pageTargets. Each navigable page within the book will be represented by a pageTarget within the pageList.

EPUB 3.0 includes its own pagination specification. The page-list nav element is a container for pagination information.

The problem is that some EPUBs (version 2.0.1) don’t have NCX files. This could be solved by implementing a pagination algorithm.

There are several criteria in use to divide the ebook’s content in pages:

  • Adobe Digital Editions interprets every 1024 bytes of source-content as a “page”. This solution gives consistent page numbers across all screen and font sizes, but it shows wrong behaviour for pictures, which are commonly heavier than plain text, and will occupy more pages.
  • On the other hand Sony BBeB reader counts “pages” in units of “screenfuls of text”. In this case page numbers will change according to the font size.
  • A progress indicator as an incremental percentage (Eg. “You’re at the 80% of the book”).

The first solution seems like the best one in case that the version of EPUB file is 2.0.1 and it doesn’t have NCX file. Some extra calculation should be done in order to display pictures on one page. The pictures could be detected and it’s position could be calculated in advance. As other formats of EPUB files include page numbers in their specification there is no problem of displaying the actual page number.

This is the first in a series of posts about supporting EPUB file format in Ubuntu. Until next time…

[1] EPUB specification

GNOME 3.12 Released — March 26, 2014

GNOME 3.12 Released

Counting down: 0

This is very exciting moment: GNOME 3.12 has been released. There is many new features and improvements coming with this release. I don’t know where is the limit, but GNOME is getting better and better. Great applications, user friendliness, beauty will leave you breathless.

As I started contributing for GNOME, my fingers have also made small contributions in this version of GNOME Documents.
To make it short have a look at the major changes in GNOME 3.12 in the release notes + video.

Next release, GNOME 3.14, is planned for September 2014. I hope I’ll make great things for GNOME.  Looking forward…

GNOME_need

Run the Latest Development Code — March 19, 2014

Run the Latest Development Code

— with JHbuild

If you don’t want to mess up your operating system and it’s dependencies while trying to build the work-in-progress version of GNOME, JHbuild is the right tool for you. It is used to safely download, build, install and run the latest GNOME development code alongside your existing GNOME installation. JHbuild is a command-line program which automates downloading, building and running the latest source code. It builds software into a separate install prefix without interfering with the rest of your system.

With JHbuild you can easily run collections of source packages, called ‘modules’. JHbuild uses ‘module set’ files to describe modules available to build. The ‘module set’ files include dependency information, so JHbuild can properly build modules in the right order. It can build modules from a variety of sources and using a variety of build systems.

Installing JHbuild

  • Download JHbuild, recommended with git from a new directory where all source code will be installed, for example, ~/checkout/gnome: $ git clone git://git.gnome.org/jhbuild
  • Build and install JHbuild:
    $ ./autogen.sh
    $ make
    $ make install
  • Add ~/.local/bin to the PATH: $ PATH=$PATH:~/.local/bin

Configuring JHbuild

JHBuild can be configured via configuration file jhbuildrc present in ~/.config folder. Couple of hints:

  • checkoutroot – directory to unpack the source trees
  • prefix – directory to install modules, for example, /opt/gnome
  • moduleset – the name(s) of the module set(s) to use
  • modules – define individual modules or groups of modules which you want to install:
    modules = ['gnome-weather', 'gnome-documents']
  • Add ignore_suggests = True which will ignore installing many unwanted dependencies, making the building process faster.

Installing Dependencies

GNOME’s development code often requires additional software. To check that necessary tools are installed run:
$ jhbuild sanitycheck. JHbuild can help you with installing some of the required software with the command:
$ jhbuild sysdeps --install. Even with these installed packages, you may find more things will need to be installed depending on you  distro.

Using JHBuild

  • After set up is complete, JHbuild can be used to build modules defined in the .config file:
    $ jhbuild build
  • To build a set of modules and their dependencies you should pass the module names as arguments:
    $ jhbuild build gnome-documents
  • If To resume the build at a particular module use –start-at option:
    $ jhbuild build --start-at=pango
  • To build one or more modules, ignoring their dependencies use the buildone command:
    $ jhbuild buildone gnome-documents
    Adding the option -n will prevent downloading updates – this will avoid conflicts with local changes you have made.
  • To download or update all the software sources without building use the update command:
    $ jhbuild update
  • To run a particular command with the same environment used by JHBuild, use the run command:
    $ jhbuild run program
  • To start a shell with the same environment used by JHBuild, use the shell command:
    $ jhbuild shell

If you are stuck with the menu prompted to choose the option to continue, you should choose to start the shell and install the required dependencies using apt-get or jhbuild and exit the shell with exit command. After that continue building your module. More informations on the link.

Enjoy your new, awesome working environment! 🙂

%d bloggers like this: