Creating a New Programming Project (C/C++)

Posted on by on September 9th, 2011 | 0 Comments »

What is a Programming Project?

IDE

When a programmer sets out to start writing some code, technically the only thing he needs is a basic text editor and a compiler.  This is sufficient for starting out programming or for writing small scripts and such, but it has its limitations.  Sooner or later the programmer is going to want features such as easy management of many files of code, the ability to debug, and library linking or creation.  All of these features are generally crammed together in what is known as an Integrated Programming Environment (IDE).  The IDE generally takes care of all the syntax-highlighting, formating, code-completion, compiling, linking, and debugging.  Most of these could be stand-alone utilities such as the Gnu Project Debugger (gdb), but it is generally more useful to have them all in one place.  Some examples of IDEs include Emacs, Microsoft Visual Studio, NetBeans, Vim, Nano, Notepad++, CodeLite, and Code Blocks.  Most programmers will tend to focus on mastering and customizing a few varying usage based on their current need or by what's available.  When starting out programming it's generally good to explore multiple IDEs and to learn what older and more experienced programmers use. Managing Projects in an IDE Most IDEs will have a default set of "project management."  When you are a single programmer, this can be sufficient.  Customization of variables such as where the executable is run while debugging or project names can all be customized from within the IDE.  Not knowing the intricacies of the particular IDE can lead to frustration though.  Things such as renaming a folder or moving it to a different computer can "break" a project forcing it to be rebuilt and the code copy and pasted over or imported into a new project.  This wastes time and is inefficient.  Fortunately there are tools such as cmake and Make that allow a programmer to define their own projects in a platform-independent manner.

Hiearchy

I have a fairly standard hiearchy that I apply to all of my projects.  Having the same hiearchy allows me to navigate large branches of code very quickly, gives me a standardized structure to start projects with, and the uniformity makes bulk modifications much simpler.  The general hiearchy is as follows:
  • bin - binaries - this is where the executables go
    • <project_name>.<exe/out>
  • build - project management configurations (how to build the project)
    • cmake
      • CMakeLists.txt
  • docs- external documentation
  • include - header files (.h)
  • src - source code
    • <project_name>.<c / c++>
This is a very logical way of organizing code, but getting this system to cooperate with any given IDE can be tricky.  Fortunately there is cmake. Cmake is a configuratoin file that other programs use to generate project files (in build) and thus the structure of your code is maintained no matter what IDE or platform you are using as long as it supports cmake.  My IDE of choice is a Linux Emacs using Make, but I also dabble in Microsofot Visual Studio from time to time and a few other IDEs, which makes compatability of projects become very important in order to avoid wasting time and stay organized  

General CMake File

Here is my cmake file. My goal is to make it general enough to be able to be used with little or no modification for all my programming projects.

Source Code

Version 1

 CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
 PROJECT(Math_Library)ADD_DEFINITIONS(-g)#used to force inclusion of math.h
 if(UNIX)
 link_libraries(m)
 endif(UNIX)SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../bin/)
 SET(SRC_DIR ${CMAKE_SOURCE_DIR}/../../src/)
 SET(INC_DIR ${CMAKE_SOURCE_DIR}/../../include/)INCLUDE_DIRECTORIES(
 ${INC_DIR}
 )FILE(GLOB MAIN_FILES ${SRC_DIR}/*.c)FOREACH(APPNAME ${MAIN_FILES})
 GET_FILENAME_COMPONENT(BASENAME ${APPNAME} NAME_WE)
 ADD_EXECUTABLE(${BASENAME} ${APPNAME})
 ENDFOREACH(APPNAME ${MAIN_FILES})MAKE_DIRECTORY(${EXECUTABLE_OUTPUT_PATH})
 

Version 2


I've been working to develop a cross platform way to build code and develop projects. Here is the CMake file I created to do that.

CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
PROJECT(Math_Library)

ADD_DEFINITIONS(-g)

#used to force inclusion of math.h
if(UNIX)
link_libraries(m)
endif(UNIX)

SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../bin/)
SET(SRC_DIR ${CMAKE_SOURCE_DIR}/../../src/)
SET(INC_DIR ${CMAKE_SOURCE_DIR}/../../include/)

INCLUDE_DIRECTORIES(
${INC_DIR}
)

FILE(GLOB MAIN_FILES  ${SRC_DIR}/*.c)

FOREACH(APPNAME ${MAIN_FILES})
GET_FILENAME_COMPONENT(BASENAME ${APPNAME} NAME_WE)
ADD_EXECUTABLE(${BASENAME} ${APPNAME})
ENDFOREACH(APPNAME ${MAIN_FILES})

MAKE_DIRECTORY(${EXECUTABLE_OUTPUT_PATH})

 Usage - Building Cmake Files for Make

  1. navigate to build
  2. mkdir Make
  3. cd Make
  4. cmake ../cmake/
 

An example of a successfull cmake building a Make project

 

C Template File

Usage

  • It should be stored in your ~/templates folder.

Source Code

////////////////////////////////////////////////////////////////////////////////
/**
 *  @file FILENAME.EXTENSION
 *  @brief 
 *
 *  DETAILED DESCRIPTION
 *  
 *  @title FILENAME
 *  @author AUTHORE_NAME
 *  @email EMAIL_ADDRESS
 *  @web WEBSITE
 *  @created DATE
 * 
 *  Compile with: g++ -g -o ../../bin/FILENAME FILENAME.EXTENSION
 */
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------ :Libraries:
//                      _    _ _                 _        
//                     | |  (_) |__ _ _ __ _ _ _(_)___ ___
//                     | |__| | '_ \ '_/ _` | '_| / -_|_-&lt;
//                     |____|_|_.__/_| \__,_|_| |_\___/__/
//                                                        
// -----------------------------------------------------------------------------
// Input-Output
#include              /* input-output stream - necessary for cout */
//#include             /* to use file stream */
using namespace std;            /* to not need std:: on all io */  
//Strings
//#include              /* to use strings */
//#include             /* use strings like cout */
//#include             /* for atoi */
//#include              /* for atoi */
//#include 
//#include
<map>  
//Math
//#include
<math>               /* pow, sqrt and use compile flag -lm */ 
//#include           /* use sort and find */

//--------------------------------------------------------------------- :Global:
//                            ___ _     _          _ 
//                           / __| |___| |__  __ _| |
//                          | (_ | / _ \ '_ \/ _` | |
//                           \___|_\___/_.__/\__,_|_|
//                                                   
// -----------------------------------------------------------------------------
//const int EMPTY = -1;
//----------------------------------------------------------------- :Prototypes:
//                  ___         _       _                     
//                 | _ \_ _ ___| |_ ___| |_ _  _ _ __  ___ ___
//                 |  _/ '_/ _ \  _/ _ \  _| || | '_ \/ -_|_-&lt;
//                 |_| |_| \___/\__\___/\__|\_, | .__/\___/__/
//                                          |__/|_|           
//  
//----------------------------------------------------------------------------- 
int Example_Function();
//----------------------------------------------------------------------- :Main:
//                              __  __      _      
//                             |  \/  |__ _(_)_ _  
//                             | |\/| / _` | | ' \ 
//                             |_|  |_\__,_|_|_||_|
//                                                 
// -----------------------------------------------------------------------------
int main ( int argc, char* argv[] )
{
    //////////////////////////////
    // Variables
    //////////////////////////////

    //////////////////////////////
    // Input 
    //////////////////////////////  

    //////////////////////////////
    // Output
    //////////////////////////////

    //////////////////////////////
    // Exititing
    //////////////////////////////
    return 0;
}
//------------------------------------------------------------------ :Functions:
//                      ___             _   _             
//                     | __|  _ _ _  __| |_(_)___ _ _  ___
//                     | _| || | ' \/ _|  _| / _ \ ' \(_-&lt;
//                     |_| \_,_|_||_\__|\__|_\___/_||_/__/
//                                                        
//
//-----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/**
 *  @brief 
 *  @warning 
 *  @param[in] 
 *  @return
 */
////////////////////////////////////////////////////////////////////////////////
int Example_Function()
{
    return -1;
}
//---------------------------------------------------------------- :Depreciated:
//                 ___                      _      _          _ 
//                |   \ ___ _ __ _ _ ___ __(_)__ _| |_ ___ __| |
//                | |) / -_) '_ \ '_/ -_) _| / _` |  _/ -_) _` |
//                |___/\___| .__/_| \___\__|_\__,_|\__\___\__,_|
//                         |_|                                  
//
//-----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/**
 *  @brief 
 *  @warning 
 *  @param[in] 
 *  @return
 */
////////////////////////////////////////////////////////////////////////////////
 

BASH Script to Auto-Generate A Hiearchy

Purpose

I created this script to assist me in automatically creating projects for me so I can repeatidly build projects exactly the same and not need to do the manual labor of physically creating every folder and file.

 Origins

I first created this program in my CSI class at UCF and as such there are current add/replace with specifics to that course still in place.  I intend to clean this file up and make it more general and more user friendly.  Right now it just works.

Usage

Using command line, a general C project would look like:
  • ./create_project project <project_name> program <main_name> c cs1
    • this will create the whole project hiearchy for a c project and will also copy header info specific to the cs1 class

Source Code

This is the C File I use with my bash script to generate my projects.
#!/bin/bash
################################################################################
#
# Title: create_project
#
################################################################################
#
# Author: Nicholas Guthrie
# Creation Date: 2-16-2011
#
# Purpose: Automatically create diretory hiearchies with templates for projects.
#
# Usage: Run this from the base directory of the project.
# Example: run from ~/Desktop/
# sh ~/create_project.sh
#
# Arguments:
# "project" ..Project Title (Required)
# What you want the project to be called
# "program" ..Project Title (Required)
# What you want the program to be name
#
# "c" || "cpp || "java"......Project Type (Required)
# What type of program it is.
#
# "cs1" || "oop".............School Project
# makes a project frop cop3502
# makes a project frop cop3330
#
# "open".....................Open Files
# Opens files in freemind & emacs after creation.
#
# "nocmake"..................No CMake
# Prevents cmake creation for C & C++ projects.
#
################################################################################
# To-Do
################################################################################
#
# 1. Make & configure Java Template
# 2. GUI ?
#
################################################################################
# Global Variables
################################################################################
DATE=$(date +%Y-%m-%d)
MONTH=$(date +%m-%d)
HOUR=$(date +%H:%M:%S)
DIRASSIGNMENT="/home/slayer/Desktop/assignment"
DIRSLIDES="/home/slayer/Desktop/slides"## Project Name
BOOL_NEXT_NAME="FALSE"
BOOL_PROJECT_NAME="FALSE"## Program Name
BOOL_NEXT_PROGRAM="FALSE"
PROGRAMNAME="FALSE"## Programming Language
BOOL_C="FALSE"
BOOL_JAVA="FALSE"
BOOL_CPP="FALSE"#### School Project Flags
BOOL_CS1="FALSE"
BOOL_OOP="FALSE"
BOOL_NMG="FALSE"#### Build Configuration
BOOL_CMAKE="TRUE"
FORCE_NO_CMAKE="FALSE"## Documentation Settings
BOOL_DOXYGEN="TRUE"
BOOL_TREE="TRUE"
BOOL_FREEMIND="TRUE"#### General
BOOL_COPY_SLIDES="FALSE"
BOOL_COPY_ASSIGNMENT="FALSE"

################################################################################
# FUNCTIONS
################################################################################
###########################
# Computer Science I #
###########################
CreateProgrammingProject()
{
mkdir -p $PROJECTNAME
cd $PROJECTNAME

#create hiearchy
echo " -Creating folder hiearchy."
mkdir -p src
#mkdir -p include #rarely used
mkdir -p build
mkdir -p bin
mkdir -p doc

## Header based on Project Type
if [ "$BOOL_C" = "TRUE" ]; then
echo " -Building a C Project"
BOOL_CMAKE="TRUE"
echo " -Making Project ""$PROJECTNAME"""
cp /home/slayer/templates/main.c src/"$PROGRAMNAME"."$EXT"
elif [ "$BOOL_JAVA" = "TRUE" ]; then
echo " -Building a Java Project"
cp /home/slayer/templates/main.c src/"$PROGRAMNAME"."$EXT"
elif [ "$BOOL_CPP" = "TRUE" ]; then
echo " -Building a C++ Project"
BOOL_CMAKE="TRUE"
cp /home/slayer/templates/main.c src/"$PROGRAMNAME"."$EXT"
fi

echo " -Setting custom template info"
SetTemplateInfo

if [ "$BOOL_DOXYGEN" = "TRUE" ]; then
echo " -Adding Doxygen"
AddDoxygen
fi

## FreeMind
if [ "$BOOL_FREEMIND" = "TRUE" ]; then
echo " -Adding FreeMind"
AddFreeMind
fi

## Tree
if [ "$BOOL_TREE" = "TRUE" ]; then
if [ "$BOOL_CMAKE" = "TRUE" ] && [ "$FORCE_NO_CMAKE" = "FALSE" ]; then
echo "Files Added, Current Directory Structure (cmake to be added):"
else
echo "Files Added, Current Directory Structure:"
fi

tree
sleep 2
fi

## Build CMAKE
if [ "$BOOL_CMAKE" = "TRUE" ] && [ "$FORCE_NO_CMAKE" = "FALSE" ]; then
BuildCmake
fi
}

###########################
# FreeMind #
###########################
AddFreeMind()
{
cp /home/slayer/templates/notes.mm doc
sed -i "s|defaultdate|"$DATE"|g" doc/notes.mm
sed -i "s|defaulttitle|"$1"|g" doc/notes.mm
}

###########################
# Doxygen #
###########################
AddDoxygen()
{
cp /home/slayer/templates/Doxyfile build
sed -i "s|defaultprojectname|"$PROJECTNAME"|g" build/Doxyfile
}

###########################
# Template Customization #
###########################
SetTemplateInfo(){
if [ "$BOOL_CSI" = "TRUE" ]; then
sed -i "s|defaultcoursename|COP3502C\ Compute\ Science\ I|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultclassnumber|16173|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultemail|nickguthrie@knights.ucf.edu|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultsectionnumber|0001|g" src/"$PROGRAMNAME"."$EXT"

elif [ "$BOOL_OOP" = "TRUE" ]; then
sed -i "s|defaultcoursename|COP3330\ Object\ Oriented\Programming|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultclassnumber|15881|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultemail|nickguthrie@knights.ucf.edu|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultsectionnumber|0001|g" src/"$PROGRAMNAME"."$EXT"
else
sed -i "s|defaultcoursename|none|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultclassnumber|none|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultemail|nickg4317@gmail.com|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultsectionnumber|none|g" src/"$PROGRAMNAME"."$EXT"
fi

#add info to source file
sed -i "s|defaultdate|"$DATE"|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaulttitle|"$PROGRAMNAME"|g" src/"$PROGRAMNAME"."$EXT"
sed -i "s|defaultfilename|"$PROGRAMNAME".c|g" src/"$PROGRAMNAME"."$EXT"
}

###########################
# Build Cmake #
###########################
BuildCmake()
{
echo " -Building CMake:"
mkdir -p build/cmake
cp /home/slayer/templates/CMakeLists.txt build/cmake
cd build;
mkdir Make;
cd Make;
cmake ../cmake/;
cd ../..;
}

################################################################################
# Main
################################################################################
if [ -z "$1" ]; then
echo c = make new c project
echo java = make new java project
echo name = project name
else
##Title Block
clear
echo "----- Starting New Programming Project Program -----"
echo " Date = $DATE"
echo " Month = $MONTH"
echo " Time = $HOUR"

echo " -Reading in Program Arguments"
## Read in Program Arguments
for var in "$@"
do

if [ "$var" = "c" ] || [ "$var" = "cs1" ]; then
BOOL_C="TRUE"
EXT="c"
if [ "var" = "cs1" ]; then
BOOL_CS1="TRUE"
fi
elif [ "$var" = "java" ] || [ "$var" = "oop" ]; then
BOOL_JAVA="TRUE"
EXT="java"
BOOL_DOXYGEN="FALSE"
FORCE_NO_CMAKE="TRUE"
if [ "$var" = "oop" ]; then
BOOL_OOP="TRUE"
fi
elif [ "$var" = "cpp" ] || [ "$var" = "nmg" ]; then
BOOL_CPP="TRUE"
EXT="cpp"
if [ "$var" = "nmg" ]; then
BOOL_NMG="TRUE"
fi
elif [ "$var" = "proj" ] || [ "$var" = "project" ]; then
BOOL_NEXT_NAME="TRUE"
elif [ "$BOOL_NEXT_NAME" = "TRUE" ]; then
PROJECTNAME=$var
BOOL_NEXT_NAME="FALSE"
BOOL_PROJECT_NAME="TRUE"
elif [ "$var" = "prog" ] || [ "$var" = "program" ]; then
BOOL_NEXT_PROGRAM="TRUE"
elif [ "$BOOL_NEXT_PROGRAM" = "TRUE" ]; then
PROGRAMNAME=$var
BOOL_NEXT_PROGRAM="FALSE"
elif [ "$var" = "nocmake" ]; then
FORCE_NO_CMAKE="TRUE"
elif [ "$var" = "open" ]; then
BOOL_OPEN="TRUE"
else
echo "Argument not found"
fi
done

echo " -Setting Program Name"

if [ "$PROGRAMNAME" = "FALSE" ]; then
PROGRAMNAME=$PROJECTNAME
fi

# Create Project
if [ "$BOOL_PROJECT_NAME" = "TRUE" ]; then
CreateProgrammingProject
else
echo "Please name a project, use flag proj then project name."
fi

if [ "$BOOL_OPEN" = "TRUE" ]; then
## Open File with Emacs
emacs src/*.* &
## Open Freemind if exists
if [ -f doc/notes.mm ]; then
freemind doc/"notes.mm" &
fi
fi
fi #END MAIN
echo "----- Ending New Programming Project Program -----"

################################################################################
## Archived Functions (not in use)
################################################################################
###########################
# Lecture Slides #
###########################
CopySlides()
{
if [ -d $DIRASLIDES ] && [ -f $DIRSLIDES/* ]; then
echo "\tfound slides"

# Check for doc folder
if ![ -e $1/doc ]; then
mkdir doc
fi

# Move lecture slides to dir
for i in $DIRSLIDES/*
do
BASENAME=$(basename $i)
EXTENSION=${BASENAME##*.}
mv -i "$i" "lecture.$EXTENSION"
done

##else
##echo "\tdid not find slides"
fi
}

###########################
# Assignment #
###########################
CopyAssignment()
{
if [ -d $DIRASSIGNMENT ] && [ -n "$(ls -A $DIRASSIGNMENT)" ]; then
echo "\tfound assignment"

# Check for doc folder
if ![ -d $DIR/doc ]; then
mkdir $DIR/doc
fi

# Move lecture slides to dir
for i in $DIRASSIGNMENT/*
do
BASENAME=$(basename $i)
EXTENSION=${BASENAME##*.}
mv -i "$i" "assignment.$EXTENSION"
done

##else
##echo "\tdid not find asignment"
fi
if [ -f doc/assignment.pdf ]; then
xpdf /doc/assignment.pdf &
fi
}
 

Sources

Cmake.org. CMake Logo Triangle High-Res PNG Image. Accessed May 21, 2012. http://www.cmake.org/files/logos/CMake-logo-triangle-high-res.png.
CBC Conversion Program
getchar VS scanf

Categorized Under

CC++Programming

About Nick Guthrie

» has written 38 posts

Leave a Reply

You must be logged in to post a comment.

History