📄 xmake.cpp
字号:
Enumerator<XMLNode*>* sources = node->getChildNodes();
while ( sources->hasMoreElements() ) {
XMLNode* source = sources->nextElement();
XMLAttr* attr = source->getAttrByName( "outputAs" );
String outputFilename;
if ( NULL != attr ) {
outputFilename = attr->getValue();
}
attr = source->getAttrByName( "name" );
outputFilename = XMLMake::getOutputFileName( attr->getValue(), outputFilename );
if ( XMLMake::deleteFile( outputFilename ) ) {
printf( "deleted %s\n", outputFilename.c_str() );
}
else {
printf( "error deleting %s\n", outputFilename.c_str() );
}
}
break;
}
else if ( node->getName() == "config" ) {
XMLAttr* attr = node->getAttrByName( "name" );
if ( attr->getValue() == XMLMake::configToBuild ) {
attr = node->getAttrByName( "srcBinaryExt" );
if ( attr ) {
XMLMake::srcBinExt = attr->getValue();
}
else {
XMLMake::srcBinExt = ".obj";
}
}
}
}
}
bool XMLMake::deleteFile( const String& filename )
{
bool result = false;
#ifdef WIN32
if ( DeleteFile( filename.c_str() ) ){
result = true;
}
else {
printf( "GetLastError() %d\n", GetLastError() );
}
#endif
#ifdef GCC
int nResult = remove(filename.c_str());
if (result == 0)
result = true;
else
result = false;
#endif
return result;
}
bool XMLMake::fileNewerThan( const String& file, const String& srcFile )
{
bool result = false;
#ifdef WIN32
HANDLE fileHandle = CreateFile( file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
HANDLE fileSrcHandle = CreateFile( srcFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
if ( (INVALID_HANDLE_VALUE != fileHandle) && (INVALID_HANDLE_VALUE != fileSrcHandle) ) {
FILETIME lastMod;
GetFileTime( fileHandle, NULL, NULL, &lastMod );
FILETIME lastMod_src;
GetFileTime( fileSrcHandle, NULL, NULL, &lastMod_src );
int res = CompareFileTime( &lastMod, &lastMod_src );
if ( res > 0 ) { //lastMod is newer than lastMod_src
result = true;
}
CloseHandle( fileHandle );
CloseHandle( fileSrcHandle );
}
else {
if ( (fileSrcHandle == INVALID_HANDLE_VALUE) && (fileHandle != INVALID_HANDLE_VALUE) ){
//there is no srcFile but the file does exist
result = true;
}
}
#endif
// ------------------------- GCC ----------------------------
#ifdef GCC
struct stat bufFile, bufSrc;
int noSuccessFile = stat(file.c_str(), &bufFile);
int noSuccessSrc = stat(srcFile.c_str(), &bufSrc);
if (noSuccessFile == 0 && noSuccessSrc == 0)
{
time_t lastMod = bufFile.st_mtime;
time_t lastModSrc = bufSrc.st_mtime;
if (lastMod > lastModSrc)
{
result = true;
}
}
else
{
if (noSuccessSrc != 0 && noSuccessFile == 0)
{
result = true;
}
}
#endif
// ----------------------------------------------------------
return result;
}
bool XMLMake::verifyFileName( const String& filename, const bool& autoBuildDir )
{
bool result = false;
#ifdef WIN32
char tmpPath[MAX_PATH+1];
GetFullPathName( filename.c_str(), MAX_PATH, tmpPath, NULL );
String tmpFilename = tmpPath;
HANDLE fileHandle = CreateFile( tmpFilename.c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE, //for now
NULL, //for now
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( (autoBuildDir) && (fileHandle == INVALID_HANDLE_VALUE) ) {
std::vector<String> dirPaths;
String tmp = tmpFilename;
int pos = tmp.find( "\\" );
while ( pos != String::npos ) {
dirPaths.push_back( tmp.substr( 0, pos ) );
tmp.erase( 0, pos+1 );
pos = tmp.find( "\\" );
}
if ( dirPaths.size() == 1 ) {
String dir = dirPaths[0];
if ( dir[dir.size()-1] != ':' ) {
throw std::logic_error("invalid directory path");
}
}
if ( dirPaths.size() == 0 ) {
throw std::logic_error("invalid directory path");
}
std::vector<String>::iterator it = dirPaths.begin();
String dirPath = *it;
it++;
while ( it != dirPaths.end() ) {
dirPath += "\\" + *it;
if ( FALSE == ::CreateDirectory( dirPath.c_str(), NULL ) ) {
int err = GetLastError();
if ( ERROR_ALREADY_EXISTS != err ) {
std::logic_error( "Unable to create directory \"" + tmpFilename + "\"" );
}
}
it++;
}
}
else if ( fileHandle != INVALID_HANDLE_VALUE ) {
result = true;
}
CloseHandle( fileHandle );
#endif
// ----------------------- GCC ---------------------------------------------------
#ifdef GCC
// * char tmpPath[MAX_PATH+1];
// verify if the file can be opened
String fullName;
fullName = filename; // this should be changed in the future to allow a different source tree
FILE* fileHandle = fopen(fullName.c_str(),"r");
String tmpFilename = fullName;
if ( (autoBuildDir) && (fileHandle == NULL) ) {
// try to make the directories
std::vector<String> dirPaths;
String tmp = tmpFilename;
int pos = tmp.find( "/" );
while ( pos != String::npos ) {
dirPaths.push_back( tmp.substr( 0, pos ) );
tmp.erase( 0, pos+1 );
pos = tmp.find( "/" );
}
// * if ( dirPaths.size() == 0 ) {
// * throw std::logic_error("invalid directory path");
// * }
// create the dirs if necessary
for (int i=0;i<dirPaths.size();i++)
{
String dirName = "";
for (int j=0;j<=i;j++)
{
dirName += dirPaths[j];
if (j != i) dirName += "/";
}
if (dirPaths[i] != "..")
{
//cout << "creating dir: " << dirName << endl;
mkdir(dirName.c_str(),555); // TODO: verify correct mode constant in Unix documentation
}
}
}
else if ( fileHandle != NULL ) {
result = true;
}
if (fileHandle != NULL)
{
fclose(fileHandle);
}
#endif
// -----------------------------------------------------------------------
return result;
}
bool XMLMake::verifyOutputFileForSrc( const String& srcName, const String& outputName )
{
bool result = false;
#ifdef WIN32
char tmpPath[MAX_PATH+1];
//check to see if the binary file is in the same dir as the
//src file - if it is then move it to the output name
GetFullPathName( srcName.c_str(), MAX_PATH, tmpPath, NULL );
String tmp1 = tmpPath;
int pos = tmp1.find_last_of( "." );
if ( pos != String::npos ) {
tmp1.erase( pos, tmp1.size() );
}
//swap out the extensio with the right one for a binary
tmp1 += XMLMake::srcBinExt;
HANDLE fileHandle = CreateFile( tmp1.c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE, //for now
NULL, //for now
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( fileHandle != INVALID_HANDLE_VALUE ) {
CloseHandle( fileHandle );
GetFullPathName( outputName.c_str(), MAX_PATH, tmpPath, NULL );
if ( !DeleteFile( tmpPath ) ) {
// XMLMake::error( "deleting old output binary in preparation of the move failed" );
}
if ( !MoveFile( tmp1.c_str(), tmpPath ) ) {
XMLMake::error( "copying output binary failed" );
}
}
else { //just verify that it is the right place
GetFullPathName( outputName.c_str(), MAX_PATH, tmpPath, NULL );
fileHandle = CreateFile( tmpPath,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE, //for now
NULL, //for now
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
result = ( fileHandle != INVALID_HANDLE_VALUE );
CloseHandle( fileHandle );
}
#endif
return result;
}
long XMLMake::includeCount = 0;
StringList XMLMake::includeDirectories;
StringList XMLMake::dependencyList;
bool XMLMake::verbose = false;
bool XMLMake::runClean = false;
bool XMLMake::runInstall = false;
String XMLMake::configToBuild = "";
String XMLMake::srcBinExt = "";
String XMLMake::projectToBuild = "";
StringList XMLMake::buildList;
String XMLMake::makefile = "makefile.xml";
String XMLMake::defaultOutputDir = "";
String XMLMake::usage = "xmake - The XML based simple make system for building C and C++ projects\n"\
"Copyright 2002 Jim Crafton\n\n"\
"Please use the following flags and syntax to build a makefile:\n\n"\
"xmake <projectname>[-config configuration name [-f makefile name] || [-install] || [-clean]]\n"\
"arguments:\n"\
"\t <projectname> is the name of the project to build in this makefile. If left blank then\n"\
"\tthe first project found is the one that is built\n"\
"\t-config tells xmlmake which configuration to build\n\t as specified by the configuration name\n"\
"\t-f the makefile to use. If this is not specified then \n\txmlmake looks for a file named "\
"\"makefile.xml\" in the \n\tcurrent directory. If this is not found then an \n\terror results.\n"\
"\t-install runs the \"install\" section of the makefile if present\n"\
"\t-clean removes all binary files produced by the makefile\n\n"\
"please report bugs to either ddiego@one.net or\n"\
"http://sourceforge.net/tracker/?group_id=6796&atid=106796\n";
int main(int argc, char* argv[])
{
if ( XMLMake::parseCommandLine( argc, argv ) ) {
try {
XMLMake::projectToBuild = argv[1];
if ( XMLMake::projectToBuild[0] == '-' ) {
XMLMake::projectToBuild = "";
}
if ( XMLMake::runClean ) {
XMLMake::doClean();
}
else if ( XMLMake::runInstall ) {
XMLMake::doInstall();
}
else {
XMLMake::doBuild();
}
}
catch ( std::exception& e ) {
XMLMake::error( e.what() );
}
catch ( ... ) {
XMLMake::error( "unknown error" );
}
}
else {
printf( XMLMake::usage.c_str() );
}
return 0;
}
//* NOT USED FOR NOW... (removed due to Solaris problems)
//* StringList XMLMake::findFilesInDir(String dir)
//* {
//* StringList files;
//*
//* #ifdef GCC
//* struct dirent **namelist;
//* int n;
//*
//* n = scandir(dir.c_str(), &namelist, 0, alphasort);
//* if (n < 0)
//* // error
//* ;
//* else {
//* while(n--) {
//* files.push_back(namelist[n]->d_name);
//* free(namelist[n]);
//* }
//* free(namelist);
//* }
//* #endif
//*
//* return files;
//*}
String XMLMake::getFileName( const String& fullPathToFile )
{
String result;
#ifdef WIN32
int pos = XMLMake::findLastStringIn( fullPathToFile, "\\" );
if ( pos != String::npos ) {
result = fullPathToFile.substr( pos+1, fullPathToFile.size() - pos );
pos = XMLMake::findLastStringIn( result, "." );
if ( pos != String::npos ) {
result.erase( pos, result.size()-pos );
}
}
else { // try it with "/" forward slash unix style
pos = XMLMake::findLastStringIn( fullPathToFile, "/" );
if ( pos != String::npos ) {
result = fullPathToFile.substr( pos+1, fullPathToFile.size() - pos );
pos = XMLMake::findLastStringIn( result, "." );
if ( pos != String::npos ) {
result.erase( pos, result.size()-pos );
}
}
else {
result = fullPathToFile;
pos = XMLMake::findLastStringIn( result, "." );
if ( pos != String::npos ) {
result.erase( pos, result.size()-pos );
}
}
}
#else
int pos = XMLMake::findLastStringIn( fullPathToFile, "/" );
if ( pos != String::npos ) {
result = fullPathToFile.substr( pos+1, fullPathToFile.size() - pos );
pos = XMLMake::findLastStringIn( result, "." );
if ( pos != String::npos ) {
result.erase( pos, result.size()-pos );
}
}
else {
result = fullPathToFile;
pos = XMLMake::findLastStringIn( result, "." );
if ( pos != String::npos ) {
result.erase( pos, result.size()-pos );
}
}
#endif
return result;
}
String XMLMake::getOutputFileName( const String& srcFile, const String& outputName )
{
String result;
if ( !outputName.empty() ) {
result = outputName;
int pos = result.find_last_of(".");
if ( pos == String::npos ) {
result += XMLMake::srcBinExt;
}
}
else {
//result = XMLMake::defaultOutputXMLMake::findLastStringInDir;
String filename = XMLMake::getFileName( srcFile );
if ( !filename.empty() ) {
result += filename;
}
result += XMLMake::srcBinExt;
}
return result;
}
int XMLMake::findLastStringIn( const String& src, const String& searchFor )
{
int pos = String::npos;
pos = src.find( searchFor, 0 );
int result = pos;
while ( String::npos != pos ) {
pos = src.find( searchFor, pos+1 );
if ( String::npos != pos ) {
result = pos;
}
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -