【kernel tool】导入linux内核源码文件到vs2008工程上进行阅读
毫无疑问,vs2008是一个很好的阅读linux内核源码的IDE,界面好看,反应快,能自动同步,跳转。但是,linux内核源码非常大,一个个源文件手动拖进去是不现实的,估计拖个一周都无法完成。所以,写了一个自动导入源码到vs2008工程的工具,实测可以使用。
vs2008的源码配置文件是 *.vcproj 文件,所喂的导入,就是修改该文件,原理非常简单,以下是工具的源码,复制进VS2008集即可运行。
步骤:
1. 新建一个vs2008工程,在源码目录中的位置如下
F:\linux-4.19\vs\linux-4.19\linux-4.19.vcproj
F:\linux-4.19\vs\linux-4.19.sln
2.然后把 generate_vcproj.exe vcproj_head.txt vcproj_tail.txt 三个文件放在 *.vcproj 同一目录下。点击 exe文件,就会替换原来的 *.vcproj 文件。
#include <io.h>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
struct DirectoryStruct
{
vector<string> FileName;
vector<string> DirectoryName;
vector<DirectoryStruct*> pNext;
};
void GetFilesType(string path, DirectoryStruct &Directory)
{
//文件信息,声明一个存储文件信息的结构体
struct _finddata_t fileinfo;
long hFile = _findfirst((path + "\\*").c_str(), &fileinfo);
if (hFile != -1)//若查找成功,则进入
{
do
{
//如果是目录,迭代之(即文件夹内还有文件夹)
if ((fileinfo.attrib & _A_SUBDIR))
{
//文件名不等于"."&&文件名不等于".."
//.表示当前目录
//..表示当前目录的父目录
//判断时,两者都要忽略,不然就无限递归跳不出去了!
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
Directory.DirectoryName.push_back(fileinfo.name);
DirectoryStruct *p = new DirectoryStruct;
Directory.pNext.push_back(p);
GetFilesType(path + "\\" + fileinfo.name, *Directory.pNext[Directory.DirectoryName.size()-1]);
}
}
//如果不是,加入列表
else
{
Directory.FileName.push_back(fileinfo.name);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile); //函数结束查找
}
}
bool CheckFileType(string Filename, string Type)
{
if (Filename.length() < Type.length())return false;
int j = Filename.length() - Type.length();
for (int i=0; i<Type.length(); i++, j++)
{
if (Filename[j] != Type[i])
return false;
}
return true;
}
bool CheckFileType(string Filename, vector<string> vFileType)
{
for (int i=0; i<vFileType.size(); i++)
{
if (CheckFileType(Filename, vFileType[i]) == true)//if (str.find(vFileType[i]) != string::npos)
{
return true;
}
}
return false;
}
bool FilterDirectory(DirectoryStruct &Directory, vector<string> vFileType)
{
for (int i=0; i<Directory.DirectoryName.size(); i++)
{
if (Directory.pNext[i] != NULL)
{
if (FilterDirectory(*Directory.pNext[i], vFileType) == true)
{
// 删除空文件夹
delete Directory.pNext[i];
Directory.pNext.erase(Directory.pNext.begin() + i);
Directory.DirectoryName.erase(Directory.DirectoryName.begin() + i);
i--;
}
}
}
for (int i=0; i<Directory.FileName.size(); i++)
{
if (CheckFileType(Directory.FileName[i], vFileType) == false)
{
// 删除非源文件。
Directory.FileName.erase(Directory.FileName.begin() + i);
i--;
}
}
if (Directory.pNext.empty() == true && Directory.FileName.empty() == true && Directory.DirectoryName.empty() == true)
{
return true;// 返回是空文件夹
}
return false; // 返回不是空文件夹
}
void PrintLine(ofstream &fout, int TabNum, string str)
{
for (int j=0; j<TabNum; j++)
{
fout.write(" ", 1);
}
string strline = str + "\r\n";
fout.write(strline.c_str(), strline.length());
}
void PrintFile(ofstream &fout, int TabNum, vector<string> PrePath, string Path)
{
PrintLine(fout, TabNum, "<File");
string DstPath;
for (int i=0; i<PrePath.size(); i++)
{
DstPath += PrePath[i];
DstPath += "\\";
}
DstPath += Path;
PrintLine(fout, TabNum + 1, "RelativePath=\x22" + DstPath + "\x22");
PrintLine(fout, TabNum + 1, ">");
PrintLine(fout, TabNum, "</File>");
}
void PrintFilter(ofstream &fout, int TabNum, string Path)
{
PrintLine(fout, TabNum, "<Filter");
PrintLine(fout, TabNum + 1, "Name=\x22" + Path + "\x22");
PrintLine(fout, TabNum + 1, ">");
}
void OutputDirectoryBase(DirectoryStruct Directory, string strPrePath, ofstream &fout)
{
static int TabCnt = 1;
static vector<string> PrePath;
if (PrePath.empty() == true)PrePath.push_back(strPrePath);
TabCnt++;
for (int i=0; i<Directory.DirectoryName.size(); i++)
{
PrintFilter(fout, TabCnt, Directory.DirectoryName[i]);
if (Directory.pNext[i] != NULL)
{
PrePath.push_back(Directory.DirectoryName[i]);
OutputDirectoryBase(*Directory.pNext[i], strPrePath, fout);
}
PrintLine(fout, TabCnt, "</Filter>");
}
for (int i=0; i<Directory.FileName.size(); i++)
{
PrintFile(fout, TabCnt, PrePath, Directory.FileName[i]);
}
TabCnt--;
if (PrePath.empty() == false)
PrePath.pop_back();
}
string ReadTxt(string FileName)
{
ifstream fin;
fin.open(FileName.c_str());
if (!fin)
{
printf("Error: Open file <<%s>> filed!!!\n", fin);
}
string strHead;
for (string str; getline(fin, str); )
{
strHead = strHead + str + "\n";
}
fin.close();
return strHead;
}
void OutputDirectory(DirectoryStruct Directory, string PrePath, string Out_vcproj)
{
string strHead = ReadTxt("vcproj_head.txt");
string strTail = ReadTxt("vcproj_tail.txt");
ofstream fout;
fout.open(Out_vcproj.c_str(), ios::binary);
if (!fout)
{
printf("Error: Open file <<%s>> filed!!!\n", fout);
}
fout.write(strHead.c_str(), strHead.length());
OutputDirectoryBase(Directory, PrePath, fout);
fout.write(strTail.c_str(), strTail.length());
fout.close();
}
void GenerateFile(string filePath, string PrePath, string Out_vcproj, vector<string> vFileType)
{
printf("-------------------------\r\n");
获取该路径下的所有文件
DirectoryStruct RootDirectory;
GetFilesType(filePath, RootDirectory);
printf("Pick end.\r\n");
FilterDirectory(RootDirectory, vFileType);
printf("filter end.\r\n");
OutputDirectory(RootDirectory, PrePath, Out_vcproj);
printf("Out End\r\n");
}
void GenerateTotalFile(vector<string> vFileType)
{
string filePath = "Z:/home/hui/linux-all/linux-4.19";//自己设置目录
string g_PrePath = "..\\..\\..\\linux-4.19";
string g_Out_vcproj = "linux-4.19.vcproj";
GenerateFile(filePath, g_PrePath, g_Out_vcproj, vFileType);
}
void GeneratePerFile(string FileName, vector<string> vFileType)
{
string filePath = "Z:/home/hui/linux-all/linux-4.19/" + FileName;//自己设置目录
string g_PrePath = "..\\..\\" + FileName;
string g_Out_vcproj = FileName + ".vcproj";
GenerateFile(filePath, g_PrePath, g_Out_vcproj, vFileType);
}
vector<string> Int_FileType(void)
{
vector<string> vFileType;
vFileType.push_back("Kconfig");
vFileType.push_back("Makefile");
vFileType.push_back("README");
vFileType.push_back("Kbuild");
vFileType.push_back(".h");
vFileType.push_back(".H");
vFileType.push_back(".c");
vFileType.push_back(".C");
vFileType.push_back(".cpp");
vFileType.push_back(".CPP");
vFileType.push_back(".s");
vFileType.push_back(".S");
return vFileType;
}
#include <direct.h>
#include <stdio.h>
string Get_CurrPath(void)
{
char buffer[1000] = {0};
getcwd(buffer, 1000);
string str = buffer;
return str;
}
void Back_2_directory(string &strPath, string &directory_name, string &vcproj_name)// 退回2级目录,
{
int flag = 0;
int i;
for (i=strPath.length()-1; i>=0; i--)
{
if (strPath[i] == '\\' || strPath[i] == '/')
{
flag++;
if (flag >= 2)
{
break;
}
}
}
strPath = strPath.substr(0, i);
int j;
for (j=strPath.length()-1; j>=0; j--)
{
if (strPath[j] == '\\' || strPath[j] == '/')
{
string str = strPath.substr(j+1, i-j);
vcproj_name = str + ".vcproj";
directory_name = "../../../" + str;
break;
}
}
}
int main()
{
printf("Start\r\n");
vector<string> vFileType = Int_FileType();
string strPath = Get_CurrPath();
cout<<strPath<<endl;
string directory_name;
string vcproj_name;
// 退回2级目录,进入源代码根级目录。
Back_2_directory(strPath, directory_name, vcproj_name);
cout<<strPath<<endl;
cout<<directory_name<<endl;
cout<<vcproj_name<<endl;
string filePath = strPath;
string g_PrePath = directory_name;
string g_Out_vcproj = vcproj_name;
GenerateFile(filePath, g_PrePath, g_Out_vcproj, vFileType);
printf("End\r\n");
system("pause");
}
vcproj_head.txt
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="linux-4.19"
ProjectGUID="{AFF555F9-C9A5-41E3-992B-628446E4A4A7}"
RootNamespace="linux419"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
GenerateDebugInformation="true"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
vcproj_tail.txt
</Files>
<Globals>
</Globals>
</VisualStudioProject>