从我的代码调用gccxml(Windows)

时间:2014-10-31 17:34:28

标签: windows visual-studio-2012 gcc

我正在编写一个使用gccxml的工具。基本上我正在解析由gccxml创建的输出xml文件。除了几个缺点之外,这在我的视觉工作室的Windows机器上工作得很好。这是我项目的当前状态:

cmake_gui给了我一个完美编译的视觉工作室解决方案(x64发布)。它设置为在E:\ cmake_builds \ GCCXML \ bin \ Release中创建三个可执行文件。

我自己的C ++工具位于不同的VS解决方案文件中。如果它应该使用gccxml,则使用以下代码:

bool Parser::ParseFile( const std::string& _szFileName, std::string& _gccxmlPath, 
                             const std::string& _tempFileLocation,
                             std::string& _errorStr)
{
   bool retVal = true;

   printf("Parsing file %s...\n\n", _szFileName.c_str());

   /* format _gccxmlPath, adding a final forward slash to the path if required */
   char lastChar = _gccxmlPath.at(_gccxmlPath.length()-1);
   if(lastChar != '/' && lastChar != '\\')
      _gccxmlPath += "/";

   /* set up a temporary environment path variable so that the gccxml exe files may locate each other */
   char envPath[500];
   sprintf_s(envPath, "PATH=%s", _gccxmlPath.c_str());
   const char* gccxml_env[] =
   {
      /* set path to gccxml directory where all exe files from gccxml are located */
      envPath,
      0
   };

   /* path & filename of gccxml.exe */
   char gccxml_exe[500];
   sprintf_s(gccxml_exe, "%sgccxml.exe", _gccxmlPath.c_str());
   /* parameter string used to set gccxml output filename */
   char fxmlParam[500];
   sprintf_s(fxmlParam, "-fxml=\"%s\"", _tempFileLocation.c_str());


   /* synthesize argument list for gccxml*/
   /* see: http://gccxml.github.io/HTML/Running.html */
   /* and: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Invoking-GCC.html */
   const char* gccxml_args[GCCXML_PARAM_LEN];
   unsigned int curPos = 0;
   /* 1st argument: exe name */
   gccxml_args[curPos++] = "gccxml.exe";
   /* the source code to be compiled */
   gccxml_args[curPos++] = _szFileName.c_str();
   /* try to find out which msvc compiler to use */
   gccxml_args[curPos++] = "--gccxml-compiler cl";
   /* the output xml file */
   gccxml_args[curPos++] = fxmlParam;
   /* last argument: zero termination */
   gccxml_args[curPos++] = 0;


   /* call gccxml & compile the source code file */
   if(0 != _spawnvpe(P_WAIT, gccxml_exe, gccxml_args, gccxml_env))
   {
      _errorStr += "GCCXML Compiler Error";
      return false;
   }
   /* now parse the gccxml output file from tempfile ... */
   ...
   ...
   return retVal;
}

正如您所看到的,我必须设置一个本地环境PATH变量,以确保三个可执行文件能够找到彼此。

这对我想做的事情非常有用。

不幸的是,当我三个可执行文件移动到另一个目录时,我无法使用此方法调用gccxml.exe。当然我提供了新的_gccxmlPath字符串,但gccxml返回

"Support item Vc10/Include is not available..."

告诉我它在我移动可执行文件的文件夹中查找。然而,我所有的Vc10 / Include本地副本都位于完全不同的地方,我不明白在移动可执行文件之前它是如何找到其中一个的。

似乎可以通过使用参数" patch_dir"调用gccxml_vcconfig.exe来解决此问题。并提供目录" gccxml / Source / GCC_XML / VcInstall"来自我的gccxml源文件。但是,我无法使用任何spawn *命令以这种方式解决我的问题。 如果我这样做,gccxml_vcconfig.exe运行得很好,但之后我试图调用gccxml.exe,结果发现它仍然看起来和以前一样。

所以gccxml_vcconfig.exe可能不是我想要的?

我试图找到一种方法来向不想在其计算机上重新编译gccxml的用户提供我的工具,因此我想分发三进制数据库(以及还需要什么) )。

1 个答案:

答案 0 :(得分:1)

只是为了让你知道。我找到了一种做我想做的事情的方法。诀窍如下:

在vpe生成gccxml之前使用自己的位置作为环境(如上所示)vp-spawn gccxml_vcconfig.exe而不提供任何环境路径变量。这可能看起来像这样

     std::string VcInstallDir = resolveRelativePath(_gccxmlPath + "../share/gccxml-0.9/VcInstall");
     std::string GCCXML09Dir = resolveRelativePath(_gccxmlPath + "../share/gccxml-0.9");

     std::vector<const char*> gccxml_config_args;
     gccxml_config_args.push_back("gccxml_vcconfig.exe");
     gccxml_config_args.push_back(VcInstallDir.c_str());
     gccxml_config_args.push_back(GCCXML09Dir.c_str());
     gccxml_config_args.push_back(0);

     if(0 != _spawnvp(_P_WAIT, gccxml_vcconfig_exe.c_str(), gccxml_config_args.data()))
     {
        _errorStr += "GCCXML Configuration Error";
        return false;
     }

请注意,resolveRelativePath是一个自编写的字符串操作函数,可生成有效的绝对路径; gccxml_vcconfig_exe包含我的exe文件的绝对路径

我稍微改变了我的编码风格,从数组到std :: vectors,你可以看到