Monday, January 14, 2013

A Simple Cmake Tutorial

There are many Cmake tutorials available on internet. Still I had to struggle a bit to get exactly the things that I wanted. So I believe that the tutorial given below will be useful for a beginner who is looking for a quick and simple introduction into how cmake works. So, here we go !!

We are looking into the aspect of building static libraries in this example. I have the following directory structure for my package:

Utilities
  |------------ CMakeLists.txt
  |------------ /include
  |                    |------------ memalloc.h
  |------------ /lib
  |                    |------------ libmemalloc.a
  |------------ /src
                       |-------------- /memalloc
                                              |-------- CMakeLists.txt
                                              |--------- memalloc.cpp

The main folder 'Utilities' has three folders, namely, include, lib and src. The include contains all header files at one place. 'lib' should contain the static library 'libmemalloc.a' once it is built and the 'src' folder contains another folder named 'memalloc' that contains the file 'memalloc.cpp' that is needed for building the static library.

For this case, I need two 'CMakeLists.txt' one inside the main folder 'Utilities' and one inside the 'memalloc' folder within 'src' folder. Infact, all folders that would potentially produce an output such as a library or an executable should contain on 'CMakeLists.txt' file inside it.

The 'CMakeLists.txt' file within the main folder looks something as shown below:


#Specify the version being used
cmake_minimum_required(VERSION 2.8)

#Name your project here
project(UTIL)

# compiler
SET(CMAKE_CXX_COMPILER "g++")

# cpp flags
SET(CMAKE_CXX_FLAGS "-g -Wall")

# various project names
# go on adding multiple names for different projects
SET(PROJECT_NAMES "memalloc")

foreach(PROJECT_NAME ${PROJECT_NAMES})

  # add sub-directories
  add_subdirectory("${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}"
    "${CMAKE_CURRENT_BINARY_DIR}/out/${PROJECT_NAME}")

endforeach(PROJECT_NAME ${PROJECT_NAMES})

   -----------------------------------
For every project, there is a corresponding folder inside the 'src' folder. The content of the 'CMakeLists.txt' file inside the 'memalloc' folder is given below:


#include headers from this folder
include_directories(${UTIL_SOURCE_DIR}/include)

# source files
set(MEMALLOC_SOURCES "memalloc.cpp")

# Build Library
add_library(memalloc STATIC ${MEMALLOC_SOURCES})

# install directory
install(TARGETS memalloc 
  ARCHIVE DESTINATION "${UTIL_SOURCE_DIR}/lib" )

--------------------------------------------


Now execute the following commands inside the 'Utilities' folder:

$ mkdir build
$ cd build

$ 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/swagat/TCS/Programs/utilities/build

$ make
Scanning dependencies of target memalloc
[100%] Building CXX object out/memalloc/CMakeFiles/memalloc.dir/memalloc.cpp.o
Linking CXX static library libmemalloc.a
[100%] Built target memalloc

$ make install
[100%] Built target memalloc
Install the project...
-- Install configuration: ""
-- Installing: /home/swg/utilities/lib/libmemalloc.a

------------------------------

If you want to build libraries within a given folder, then your CMakeLists.txt file should contain the following lines:



set(MVG_SOURCE "mvg.cpp")
# Build Library
add_library(mvg STATIC ${MVG_SOURCE})
set_target_properties(mvg PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
  ${CMAKE_SOURCE_DIR}/lib)   

The library will be built within the lib folder under the root directory. Hence, you do not have use make install command as you did above. Make install command should be used for putting the files at a different location within your system. 

-----------------------------------

In order to build binary inside a specific directory instead of the default location, use the following statements:


add_executable(testmvg ${MVG_TEST_SRC})
target_link_libraries(testmvg ${GLIBS} ${MVG_LIB} ${MEM_LIB} )           
set_target_properties(testmvg PROPERTIES RUNTIME_OUTPUT_DIRECTORY
  ${CMAKE_SOURCE_DIR}/bin)  

--------------------------------              

Thursday, November 22, 2012

Converting jpeg to pdf with lower quality

Convert jpeg into PDF with 50% quality:

$ convert -quality 50 file1.jpg file.pdf


Combine multiple file into PDf

$ pdftk *.pdf cat output merged.pdf
or
$ pdftk file1.pdf file2.pdf cat output merged.pdf

You need to have imagemagick and pdftk installed on your system.

If you have multiple files to convert, use the following command on bash:


$ for i in *.jpg; do convert -quality 50 -resize 60% "$i" "${i%.jpg}.eps"; done


Changing resolutions in DPI

$ convert -units PixelsPerInch pic1.png -density 300 pic1.jpg
$ identify -verbose pic1.jpg | grep Resolution
Resolution: 300x300


Converting from PDF to eps 

$ pdftops -eps input.pdf output.eps

Wednesday, November 21, 2012

File Synchronization over Network using Unison

Unison is great tool for synchronizing files over network. Earlier I used rsync for file-synchronization. Unison at least provides one level of comfort over rsync which requires quite a bit of customization. If you want to use Unison to synchronize files between two systems over a network, then please refer to the following links:

http://www.howtoforge.com/setting-up-unison-file-synchronization-between-two-servers-on-ubuntu-11.10

This worked for me on Ubuntu 12.04 LTS 64-bit version and I managed to do everything mentioned on this page. One more thing, you don't need to use the root login for executing the steps.

If you need to delete the several profiles already created on Unison, you should go to ~/.unison folder and delete the corresponding .prf files. It is not possible to delete profiles using GUI.

Sunday, October 14, 2012

GNUPlots Loops


It is possible now to use 'loop's within the GNUPlot Command. See this link for more details.

The following commands plots 10 blocks with different colours. Remember each block is separated from the other block by a pair of double lines.

gnuplot> plot for [i=0:9] './clusterpos.txt' index i u 1:2 w p



Thursday, October 4, 2012

APT Behind Proxy Server Ubuntu 12.04


This worked for me on Ubuntu 12.04


Create a new file as shown below:

$ sudo gvim  /etc/apt/apt.conf.d/02http-proxy

and enter the following line:

Acquire::http::Proxy "http://username:password@proxy.tcs.com:8080";



Save the file and run

$ sudo apt-get update 

It should work for you.

One more thing, if your password contains '@' character, then you need to replace it with '%40' in your password.




Saturday, February 12, 2011

Sunday, August 15, 2010

Working with PDFs

Join PDF files using ghostscript:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=finished.pdf file1.pdf file2.pdf


Merge Two or More PDFs into a New Document using PDFtk
pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf
or (Using Handles):
pdftk A=1.pdf B=2.pdf cat A B output 12.pdf
or (Using Wildcards):
pdftk *.pdf cat output combined.pdf