Cpp packaging

From wikinotes



C++ file structure is a little different than that of python. Instead of having your classes and methods defined in the same place (the source), cpp divides it into header files and source files.


filetypes

headers (.h)

Headers are like an index of your CPP code.

// mysource.h

class MyClass
{
    int instance_attr = 0;

    public:
        void do_something( int, int );

    private:
        void _do_something_else( int );
}

source (.cpp)

Sourcefiles are the actual meat/potatoes of your code.

// mysource.cpp
# include "mysource.h"

void MyClass::do_something( int start, int end )
{
    result = end - start;
    this->instance_attr = result
}

void MyClass::_do_something_else()
{
    cout << "lots of information..." << endl;
}

object-file (.o)

A compiled version of your source, without being actually executable itself. (Generally one program will make use of several .o files)



headers

writing headers

It is considered good practice to mark your header files with includes. However, at compiletime, for each component, all of your required headers get mashed together into one big file. Problem: C++ does not let you include the same file twice.

The way to get around this in your header files only is to use include-guards. These work like if statements in your preprocessor.

/*
 * Below we have a problematic situation. main.ccp references 
 * calendar.h and week.h, which both in turn reference date.h.
 *
 * If includes were specified in the header file, this would
 * generate an error.
 */

// main.cpp
#include "calendar.h"
#include "week.h"

// calendar.cpp
#include "date.h"

// week.cpp
#include "date.h"
/*
 * The solution is to use ifndef (if not defined) blocks in the headers.
 * 
 */

//date.h
#ifndef DATE_H
#define DATE_H

class MyClass 
{
	...
}

class MyOtherClass
{
	...
}

#endif

including headers

your headers

installed headers

By default, installed libraries should be available to your compiler without any modifications. In case you find you do need to add other directories, you'll need to look into your compiler's arguments for adding include directories.

gcc     -I/usr/include -I/some/path/include  # ...
clang++ -I/usr/include -I/some/path/include  # ...
#include <xcb/randr.h>                     // from: /usr/include/xcb/randr.h

std::cout << XCB_RANDR_ROTATION_ROTATE_0;  // from enum:  xcb_randr_rotation_t.XCB_RANDR_ROTATION_ROTATE_0

Project Structure

http://hiltmon.com/blog/2013/07/03/a-simple-c-plus-plus-project-structure/ simple cpp project structure (I really like!)
http://gcc.gnu.org/codingconventions.html gnu coding conventions
http://www.cplusplus.com/forum/lounge/90812/ project structure examples
https://msdn.microsoft.com/en-us/library/ms235629.aspx Microsoft walkthrough of creating project standard

There seems to be several ideas about how your project should be structured, the closest there is to being the cpp project-structure standard seems to be the gcc coding conventions.


Generally:

bin/			## executables go here
src/			## all .cpp files
include/		## all .h files
test/			## unittests

build/		## all .o files (keep `make clean` easy)
doc/			## notes/config files
lib/			## libraries that get compiled in

spike/		## misc ideas, simple tests, etc

makefile
README.rst


NOTE in order to use an alternate include directory, you will need to add to the include directories:

  • g++: -I path/include_dir
  • clang++: -I path/include_dir


Sources

http://www.cplusplus.com/forum/articles/10627/ how includes work
http://stackoverflow.com/questions/12409493/c-trying-to-use-ifndef-and-include-statements how to use include-guards