Jayson Explains CMake

As men­tioned in the pre­vi­ous entry, my good buddy Jayson is going to con­tribute addi­tional programming/technical/geeky arti­cles on the blog. Below is his first such arti­cle. Enjoy!

Today’s arti­cle is going to be about CMake. I started using this at work recently. It took a bit of time for me to get it work­ing with my setup at work; fig­ur­ing out how it oper­ates. So I’m here to pro­vide hints so that maybe if you’re start­ing out using CMake, you can have a bet­ter clue as to how to use it.

This guide is going to be generic and assume a gcc devel­op­ment envi­ron­ment; be that MinGW inside Win­dows or gcc inside Linux.

First and fore­most, as their doc­u­men­ta­tion states, you need a CMakeLists.txt file in each direc­tory you’re going to do some com­pil­ing in.

For just a sim­ple basic sin­gle file appli­ca­tion, you would have this as your direc­tory and file structure:

$ ls
CMakeLists.txt  main.c

Now, the CMakeLists.txt file is pretty sim­ple for this:

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(mini)

add_executable(mini main.c)

And our main.c file is rather drafty as well:

#include <stdio.h>

int main() {
printf(“Hello, world!\n);
return (0);
}

Now, on a Linux sys­tem, this is what I typed at the com­mand line to gen­er­ate Unix Make files: cmake –G “Unix Makefiles”

The above com­mand will then parse through the CMakeLists.txt file and gen­er­ate every­thing needed to build the project. After it com­pletes, all that is needed is to type make at the com­mand line. Actu­ally, from here on out, if you were to add other source files to the project, all you’d need to do is type make. The only time you ever need to run the cmake com­mand directly is the first time you run it. Every other time, you can sim­ply type make.

Now, the above small lit­tle project isn’t exactly using any­thing use­ful. Most of the time, if you’re doing a project, you’re using other libraries. CMake includes search func­tions for a lot of libraries. The syn­tax for search­ing for each library is fairly sim­i­lar, so I’m only going to give some exam­ples for a couple[1].

First, we’ll high­light using the wxWid­gets library. We’ll start with the struc­ture in the CMakeLists.txt file as to how to search for wx.

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(first_wx)

find_package(wxWid­gets COMPONENTS base core aui REQUIRED)
include(${wxWidgets_USE_FILE})

set(FIRST_WX_SRC app.cpp)

add_executable(first_wx ${FIRST_WX_SRC})
target_link_libraries(first_wx ${wxWidgets_LIBRARIES})

Now, this is still pretty sim­ple, but I’ve added a few things that I’d like to elab­o­rate upon. First, find_package(). Shipped with CMake are, as men­tioned above, some func­tions to search for pop­u­lar libraries. To use these, just call find_package() with the library name, some COMPONENTS you’d like to use from the library, and whether those com­po­nents are REQUIRED. What this does is searches the sys­tem for the pack­age, and the sub-components. If it finds them, the com­po­nents listed are auto­mat­i­cally added to the link stage. How­ever, as the code states below the find_package() call, you still need to explic­ity add the include and link direc­to­ries. Each library may have dif­fer­ent syn­tax for these vari­ables, so don’t blindly assume they are all the same.[1][2]

Next I add a vari­able to store the source files in. I just use this as a con­ve­nience, so that just in case I use it in mul­ti­ple places, I only have to type the variable.

Our direc­tory struc­ture is flat, for now:

$ ls
CMakeLists.txt  app.cpp  app.h

Our app.h and app.cpp files are simple:

#ifn­def __app_file_h_included__
#define __app_file_h_included__

#include “wx/app.h“

class app : pub­lic wxApp
{
pub­lic:
bool OnInit();
int OnExit();
};

#endif
#include “app.h“

#include <wx/frame.h>
#include <wx/intl.h>

IMPLEMENT_APP(app)

bool app::OnInit()
{
wxFrame* frame = new wxFrame (0L, wxID_ANY, _(“Hello, World!”));
if (!frame) {
return (false);
}
frame-&gt;Show ();
return (true);
}

int app::OnExit()
{
return (0);
}

Now that we have that work­ing, we’ll move on to add boost to our pro­gram. We’ll still not have it be very elab­o­rate. We’ll take one of the asio demo’s, so that we can use actual libraries; in addi­tion to some header only stuff.[3]

The lay­out stays the same, but here’s the mod­i­fied CMakeLists.txt file:

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(wx_boost)

find_package(wxWid­gets COMPONENTS base core aui REQUIRED)
include(${wxWidgets_USE_FILE})

set(Boost_USE_MULTITHREADED ON)
find_package(Boost 1.39.0 COMPONENTS date_time thread sys­tem)
include(${Boost_INCLUDE_DIRS})

set(FIRST_WX_SRC app.cpp)

add_executable(wx_boost ${FIRST_WX_SRC})
target_link_libraries(wx_boost ${wxWidgets_LIBRARIES} ${Boost_LIBRARIES})

The app.h file was not mod­i­fied, but here’s the changed app.cpp:

#include “app.h“

#include <wx/frame.h>
#include <wx/intl.h>
#include <wx/msgdlg.h>

#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

IMPLEMENT_APP(app)

sta­tic wxFrame* frame = 0;

void popup(const boost::sys­tem::error_cc lang=“c”&amp; /*e*/)
{
wxMes­sage­Box (_(“Pop up!”), _(“Box”), wxOK, frame);
}

bool app::OnInit()
{
frame = new wxFrame (0L, wxID_ANY, _(“Hello, World!”));
if (!frame) {
return (false);
}
boost::asio::io_service io;

frame-&gt;Show ();
boost::asio::deadline_timer t (io, boost::posix_time::sec­onds(5));
t.async_wait (popup);

io.run ();
return (true);
}

int app::OnExit()
{
return (0);
}

So, now that we’ve seen how to imple­ment a cou­ple libraries into an exe­cutable, I’ll go through a handy set­ting for the install() function.

install() is as it states[2], it will install things to the des­ig­nated loca­tions. When using cmake to build libraries, I found the fol­low­ing to be very handy:

install(DIRECTORY   DESTINATION ${}
FILES MATCHING PATTERN “*.h“
PATTERN “.svn” EXCLUDE
)

Now, the above will copy all the header files in the direc­tory list­ing, exclud­ing the .svn direc­tory. With­out the exclude, the .svn direc­tory would get copied to the instal­la­tion path. That will han­dle include pathing for your own cus­tom library, but the instal­la­tion of the library itsel would go like this:

add_library(  STATIC )
install(TARGETS     ARCHIVE DESTINATION lib)

This would cre­ate a sta­tic library [.a|.lib] for your project and then copy it to the lib direc­tory on the DESTINATION path. This path can be set up by set­ting the following:

set(MY_LIB_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/lib)

[1] The wiki page for Find­ing Libraries on your system

[2] The offi­cial doc­u­ment page for CMake detail­ing _every_ avail­able call

[3] The full source list­ing for the Boost only ASIO code

Extended Euclidean Algorithm

I’ve started a cryp­tog­ra­phy class at DePaul and dur­ing the first lec­ture we first reviewed the Extended Euclid­ean Algo­rithm.  It pro­vides a method, using only a table, pen­cil, and paper, to eas­ily find not just the gcd of two inte­gers, but the s and t val­ues as well. Aca­d­e­m­i­cally: Let a and b be two inte­gers, at least one of which is nonzero, and let d = gcd(a,b). There exists some val­ues s,t such that d = sa + tb.

When it was cov­ered in class, the table didn’t have the k col­umn as it does in Wikipedia so I didn’t quite grasp it the first time through.  When I’m unsure of some­thing I attempt to write imple­ment it in code. So below is my quick Python imple­men­ta­tion of the Extended Euclid­ean Algo­rithm for find­ing d, s, and t, given a and b in d = gcd(a,b) = sa + tb . Not quite sure what we’ll use it for, but I have no doubt that I will learn that soon enough!

# Uses the Extended Euclid­ean Algo­rithm (Table Method) to find the gcd, s, and t
def gcd(a,b,dis­play=False):
    # Setup the first two rows of the table
    s2 = 1; t2 = 0; d2 = a; k2 = 1;
    s1 = 0; t1 = 1; d1 = b; k1 = d2/d1;
   
    # Com­pute Rows until the GCD is found
    while True:
        # Cal­cu­late a Table Row
        s0 = s2 — k1*s1
        t0 = t2 — k1*t1
        d0 = d2 — k1*d1
        k0 = d1/d0
       
        # Shift all the Row Vari­ables
        d2 = d1;    d1 = d0;
        s2 = s1;    s1 = s0;
        t2 = t1;    t1 = t0;
        k2 = k1;    k1 = k0;
       
        # We’ve found the GCD
        if d2%d1 == 0:
            break
           
    # Print the Results
    if dis­play == True:
        print “gcd(a,b)=sa+tb: gcd(“+‘a‘+”,”+‘b‘+”)=(“+‘s1‘+”)(“+‘a‘+”)+(“+‘t1‘+”)(“+‘b‘+”) = “+‘d1‘
   
    # Return the results
    return d1, s1, t1