Click here to Skip to main content
15,891,657 members
Articles / Programming Languages / C++

Batch Build VC Projects Wizard

Rate me:
Please Sign up or sign in to vote.
4.53/5 (6 votes)
16 May 2008CPOL2 min read 44.6K   864   29   11
Build all your projects using a wizard, just like the 'BCGControl Bar Pro Build Wizard', including the outputs.

Screenshot - Snap.png

Introduction

This is a useful tool for building a serial project for your team when your software contains many components, created using VC++ 6.0, VC++ 2003, VC++ 2005, and also VC++ 2008. At the same time, you can create batch files to do some additional tasks, such as increasing the version of the project, copying/deleting files, and calculating the MD5 of the final output binary, etc.

You can compile them by selecting and then getting the compile status from the 'Status' icon, and even stop the build process while compiling. Of course, you have the option to view the run-time output of compiling.

Background

Recently, I had an opportunity to manage a project which had many VC++ projects. We had to compile them one by one first, and later we used a batch file to do this. But this was a long time to wait for the final result, and the control flow was poor: if one of the projects failed, we had to recompile them all. So, I searched the web and learnt that CodeJock and BCGSoft all have their GUI build wizard, and thought why not create a common one for us? So, here it is . ^)^

Using the Code

We use some common stuff in this tool, including the INI reader, the console redirector, and XListCtrl. All the initialization starts from:

C++
CBuildWizDlg::OnInitDialog(): 

InitListCtrl(&m_List);
FillListCtrl(&m_List);

// Toggle the state of output
OnDetail();

// Center Main Dialog.
CenterWindow();
m_log.m_pWnd = this;

// Set the Header Control
m_HeaderCtrl.SetTitleText(m_objSet.m_stuBWS_COMM.szPrjName);
m_HeaderCtrl.SetDescText(m_objSet.m_stuBWS_COMM.szComments);

m_HeaderCtrl.SetIconHandle(AfxGetApp()->LoadIcon(IDI_MSDEV));
m_HeaderCtrl.Init(this);
m_HeaderCtrl.MoveCtrls(this);

// Init the Build Envirement.
InitBuildEnv();

Here is the details about our initialization of the List control:

C++
// Create the Project List items from the BuildWiz.ini.
void CBuildWizDlg::FillListCtrl(CXListCtrl *pList)
{
    // Read Settings From INI
    m_objSet.InitSettings();

    //
    CString        strTitle;
    strTitle.Format("BuildWiz - script by %s ", 
                    m_objSet.m_stuBWS_COMM.szAuthor);
    SetWindowText(strTitle);

    pList->LockWindowUpdate();
    // ***** lock window updates while filling list *****
    
    pList->DeleteAllItems();
    
    CString                str = _T("");
    int                    nItem, nSubItem;
    STU_BWS_ITEM        bwsItem;

    for(nItem = 0; nItem < m_objSet.m_stuBWS_COMM.nItems; nItem ++)
    {
        for (nSubItem = 0; nSubItem < BWS_COLS; nSubItem++)
        {
            str = _T("");
            bwsItem = m_objSet.m_arrBWItems.GetAt(nItem);

            // Text
            if (nSubItem == 0)                // Enable
                str.Format("%s", bwsItem.szComponent);
            else if (nSubItem == 1)                // Label
                str.Format("%s", bwsItem.szComments);
            else if (nSubItem == 2)                // Status
            {
                str = _T(" ");
                pList ->SetItemImage(nItem, nSubItem, BLDWIZ_STATUS_NA);
            }

            // Do it.
            if (nSubItem == 0)
            {
                pList->InsertItem(nItem, str);

                if(strnicmp(bwsItem.szStatus, "yes", 3) == 0)
                    pList->SetCheckbox(nItem, nSubItem, ITEM_STATUS_CHECKED);
                else if(strnicmp(bwsItem.szStatus, "no", 2) == 0)
                    pList->SetCheckbox(nItem, nSubItem, ITEM_STATUS_UNCHECKED);
                else
                    pList->SetCheckbox(nItem, nSubItem, ITEM_STATUS_HIDDEN);
            }
            else
                pList->SetItemText(nItem, nSubItem, str);

        }

    }
    
    pList->UnlockWindowUpdate();    // ***** unlock window updates *****
}

For building projects, we need some environment for the compilers, such as 'include', 'lib', 'path'; we do this in:

C++
// Set the Env: 'include', 'lib', 'path'.
void CBuildWizDlg::InitBuildEnv()
{
    TCHAR        tszEnv[MAX_ENVVAR_LEN + 1] = {0};
    CString        strEnv;

    // Include
    if(strlen(m_objSet.m_stuBWS_COMM.szIncDir) > 0)
    {
        GetEnvironmentVariable("INCLUDE", tszEnv, sizeof(tszEnv));
        strEnv.Format("%s;%s", m_objSet.m_stuBWS_COMM.szIncDir, tszEnv);
        SetEnvironmentVariable("INCLUDE", strEnv);
    }

    // Library 
    if(strlen(m_objSet.m_stuBWS_COMM.szLibDir ) > 0)
    {
        GetEnvironmentVariable("LIB", tszEnv, sizeof(tszEnv));
        strEnv.Format("%s;%s", m_objSet.m_stuBWS_COMM.szLibDir, tszEnv);
        SetEnvironmentVariable("LIB", strEnv);
    }

    // Path 
    if(strlen(m_objSet.m_stuBWS_COMM.szExeDir) > 0)
    {
        GetEnvironmentVariable("PATH", tszEnv, sizeof(tszEnv));
        strEnv.Format("%s;%s", m_objSet.m_stuBWS_COMM.szExeDir, tszEnv);
        SetEnvironmentVariable("PATH", strEnv);
    }

    // 'BWBaseDir' variable
    if(strlen(m_objSet.m_stuBWS_COMM.szBaseDir) > 0)
    {
        SetEnvironmentVariable("BWBASEDIR", m_objSet.m_stuBWS_COMM.szBaseDir);
    }
    else
        SetEnvironmentVariable("BWBASEDIR", "");


    // Change the current directory.
    if(strlen(m_objSet.m_stuBWS_COMM.szBaseDir) > 0)
    {
        if(!SetCurrentDirectory(m_objSet.m_stuBWS_COMM.szBaseDir))
            OutputDebugString("\nError! Base Directory is invalid.");
        else
        {
            
        }
    }
}

For some reason, we have to use the 'redirect' technology for msdev.exe, .bat, .cmd; but, we have to use the 'pipeline' technology for VS2005's devenv.exe. You can see them in the 'CBuildWizDlg::OnBuild()' function:

C++
// This is the Piper.
    CTraceCollector objTracer(&m_log);
    objTracer.Run();

    // Here we start build and create a redirected application.
    if(!RunScript(m_objSet.m_stuBWS_COMM.szPreCompile))
    {
     ... ...

How to Use this Tool

First, you should know something about BuildWiz.ini. There is a [common] section for the common settings of your project, and there are many [item?] sections for each of your projects in your product. What I am sure is, once you run BuildWiz.exe after reviewing the demo BuildWiz.ini, you should know the meanings of each tag.

Please download the binary first.

Points of Interest

  • BuildWiz supports VC++ 6.0 and VC++ 2005 projects, and MinGW, Cygin, C51, are also supported, I think.
  • We use both the pipeline and redirect technologies.
  • BuildWiz can be improved to support user defined environment variables.
  • As a project manager, you can make your software build more faster and easier than ever. :)
  • It gives you more control while building sources.

History

  • 2008-05-16: Rev. 1.2. BuildWiz.ini now has the 'BaseDir={PWD}' support.
  • 2008-01-23: Rev. 1.1. BuildWiz.ini now has the %basedir% variable support.
  • By using this new variable, we can simplify the .ini.

  • 2007-10-08: First version. (This is my third article on CodeProject.)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer emware
China China
software development is so nice and we can make our world better than ever, even the real world.
vc++6 is enough for me, althought i tried to upgrade to higher version, each time, i down-grade to vc6. ^_^

Comments and Discussions

 
General'vcbuild' instead 'devenv' or 'msbuild' for VS.net project Pin
dotnfc16-May-08 0:11
dotnfc16-May-08 0:11 
Questionclick button"build" second ,question Pin
andrew20030704@yahoo.com24-Jan-08 23:01
andrew20030704@yahoo.com24-Jan-08 23:01 
AnswerRe: click button"build" second ,question Pin
dotnfc16-May-08 0:12
dotnfc16-May-08 0:12 
GeneralIt is not 100% right Pin
_elli_23-Jan-08 18:40
_elli_23-Jan-08 18:40 
>but is console

It is not 100% right, msbuild.exe itslef use only the a front end. The real build stuff is located
in a normal assembly and accessable with normal c# and c++.cli code ...

You have full control over all events, messages ... and can display them in good GUI ...
And some stuff is implemented in MONO !

elli


using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;


private Engine buildEngine;
private Project buildProject;

public void Build(string fileName, BuildPropertyGroup buildProperties)
{
this.fileName = fileName;


this.buildEngine = new Engine(Path.GetDirectoryName(new uri(typeof(string).Assembly.EscapedCodeBase).LocalPath));
if ( buildProperties != null )
{
buildEngine.GlobalProperties = buildProperties;
}

this.buildProject = buildEngine.CreateNewProject();

try
{
this.buildProject.Load(fileName);
}
catch (Exception e)
{
return;
}

this.buildEngine.RegisterLogger(this);

this.Events.ProjectStarted += new ProjectStartedEventHandler(this.onEventProjectStarted);
this.Events.ProjectFinished += new ProjectFinishedEventHandler(this.onEventProjectFinished);
this.Events.WarningRaised += new BuildWarningEventHandler(this.onEventWarningRaised);
this.Events.ErrorRaised += new BuildErrorEventHandler(this.onEventErrorRaised);
this.Events.BuildFinished += new BuildFinishedEventHandler(this.onEventBuildFinished);
this.Events.BuildStarted += new BuildStartedEventHandler(this.onEventBuildStarted);
this.Events.MessageRaised += new BuildMessageEventHandler(this.onEventMessageRaised);
this.Events.CustomEventRaised += new CustomBuildEventHandler(this.onEventCustomEventRaised);
this.Events.TargetStarted += new TargetStartedEventHandler(this.onEventTargetStarted);
this.Events.TargetFinished += new TargetFinishedEventHandler(this.onEventTargetFinished);

// this.Events.TaskFinished +=new TaskFinishedEventHandler(Events_TaskFinished);


buildThread = new Thread(new ThreadStart(this.buildThreadProc));

buildThread.Name = "Build Thread";

buildThread.SetApartmentState (ApartmentState.STA);
buildThread.Start();
}

private void buildThreadProc()
{
buildEngine.BuildProject(buildProject);
}
QuestionYou know MSBuild ? Pin
_elli_23-Jan-08 1:07
_elli_23-Jan-08 1:07 
AnswerRe: You know MSBuild ? Pin
dotnfc23-Jan-08 17:25
dotnfc23-Jan-08 17:25 
QuestionPurpose? Pin
bolivar1239-Nov-07 9:50
bolivar1239-Nov-07 9:50 
AnswerRe: Purpose? Pin
dotnfc11-Nov-07 14:25
dotnfc11-Nov-07 14:25 
GeneralRe: Purpose? Pin
bolivar12311-Nov-07 15:37
bolivar12311-Nov-07 15:37 
GeneralBuildWiz_Binary download not working Pin
rajas9-Nov-07 3:07
rajas9-Nov-07 3:07 
GeneralRe: BuildWiz_Binary download not working Pin
dotnfc11-Nov-07 14:18
dotnfc11-Nov-07 14:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.