⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmake.cpp

📁 利用XML来作为Makefile的make工具源代码.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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 + -