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:
CBuildWizDlg::OnInitDialog():
InitListCtrl(&m_List);
FillListCtrl(&m_List);
OnDetail();
CenterWindow();
m_log.m_pWnd = this;
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);
InitBuildEnv();
Here is the details about our initialization of the List control:
void CBuildWizDlg::FillListCtrl(CXListCtrl *pList)
{
m_objSet.InitSettings();
CString strTitle;
strTitle.Format("BuildWiz - script by %s ",
m_objSet.m_stuBWS_COMM.szAuthor);
SetWindowText(strTitle);
pList->LockWindowUpdate();
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);
if (nSubItem == 0) str.Format("%s", bwsItem.szComponent);
else if (nSubItem == 1) str.Format("%s", bwsItem.szComments);
else if (nSubItem == 2) {
str = _T(" ");
pList ->SetItemImage(nItem, nSubItem, BLDWIZ_STATUS_NA);
}
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(); }
For building projects, we need some environment for the compilers, such as 'include', 'lib', 'path'; we do this in:
void CBuildWizDlg::InitBuildEnv()
{
TCHAR tszEnv[MAX_ENVVAR_LEN + 1] = {0};
CString strEnv;
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);
}
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);
}
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);
}
if(strlen(m_objSet.m_stuBWS_COMM.szBaseDir) > 0)
{
SetEnvironmentVariable("BWBASEDIR", m_objSet.m_stuBWS_COMM.szBaseDir);
}
else
SetEnvironmentVariable("BWBASEDIR", "");
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:
CTraceCollector objTracer(&m_log);
objTracer.Run();
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.)