从我的代码(Windows)调用gccxml



我正在编写一个使用gccxml的工具。基本上,我正在解析gccxml创建的输出xml文件。这在我的visualstudio的windows机器上运行得很好,除了几个缺点。以下是我项目的当前状态:

cmake_gui为我提供了一个可完美编译的visual studio解决方案(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...nn", _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源文件中提供目录"gccxml/Source/GCC_XML/VcInstall"来解决。然而,我无法使用任何spawn*命令以这种方式解决我的问题。如果我这样做,gccxml_vcconfig.exe运行得很好,但在那之后,我尝试调用gccxml.exe,结果发现它仍然和以前一样在同一目录中。

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

我正试图找到一种方法,为那些不想在自己的机器上重新编译gccxml的用户提供我的工具,所以我想分发thre二进制文件(以及其他需要的东西)。

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

就在vpe使用自己的位置作为环境生成gccxml之前(如上所示),vp在不提供任何环境路径变量的情况下生成gccxmlvcconfig.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,正如您所看到的

最新更新