Windows port: clang to autoprobe for system include / library pathes

Hi !

João Matos ripzonetriton@gmail.com has made some patch to autoprobe for Visual studio system include and library pathes -

commit -
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120903/063802.html

http://llvm.org/viewvc/llvm-project?view=rev&revision=163076

But I guess this commit was reverted - since I cannot find this function in rev 163370.

What do you think if I’ll bring it back into clang once again.

There is several issues - one - developer should be able to specify manually which VS environment he wants to use
(vs2008, vs2010, vs2012…) - VS environment can be autoprobed, but it’s only for hello world style apps.
Now I have prototyped by using special env variable VSENV = 8/9/10 - 2005 - 8, 2008 - 9, 2010 - 10.

Attaching console code snipet:

#include “stdafx.h”
#ifndef _WIN32
#error “failed”
#endif

#ifdef _WIN32
#include
#include
#include <stdio.h>

static std::string exec(const char* cmd)
{
FILE* pipe = _popen(cmd, “r”);
if (!pipe) return “ERROR”;
char buffer[1024];
std::string result = “”;
while(!feof(pipe)) {
if(fgets(buffer, sizeof(buffer), pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}

#pragma comment(lib, “shlwapi.lib”) //_popen, _pclose
#include <shlwapi.h>

//
// Returns true if got settings, false if not.
//
bool GetVisualStudioEnv(
const char* envVar, // [in] “INCLUDE” / “LIBPATH”
std::vectorstd::string& vecPathes,
int iProbeFrom = 0, int iProbeTo = 0 // 2005 - 8, 2008 - 9, 2010 - 10
)
{
std::string s;

if( iProbeFrom == 0 && iProbeTo == 0 )
{
// Environment variable specifies which VS to use.
if( getenv(“VSENV”) != NULL )
{
int iVer = atoi( getenv(“VSENV”) );

if( iVer == 0 )
return false;

return GetVisualStudioEnv(envVar, vecPathes, iVer, iVer );
}

From = 20;
iProbeTo = 8;
} //if

for( int iProbeVer = iProbeFrom; iProbeVer >= iProbeTo; iProbeVer-- )
{
char envvar[64];
sprintf(envvar, “VS%d0COMNTOOLS”, iProbeVer);

// Not defined
if( getenv(envvar) == NULL )
continue;

std::string cmd = getenv(envvar);
cmd += “\…\…\vc\vcvarsall.bat”;

if( !PathFileExistsA( cmd.c_str() ) )
continue;

//printf(“Located: %s”, envvar);

cmd = “cmd /C “” + cmd + “” ^>nul ^& set”;
s = exec(cmd.c_str());
break;
}

if( s.length() == 0 )
return false;

char* envline;

vecPathes.clear();

for (envline = strtok( &s[0], “\n” ); envline; envline = strtok( NULL, “\n” ))
{
char* varend = strchr( envline, ‘=’);
if( !varend )
continue;

*varend = 0;

if( strcmp(envline,envVar) == 0 )
{
char* val;
for (val = strtok( varend + 1, “;” ); val; val = strtok( NULL, “;” ))
{
vecPathes.push_back(val);
}

return true;
}
*varend = ‘=’;
} //for

return false;
} //GetVisualStudioEnv

#endif //_WIN32

int _tmain(int argc, _TCHAR* argv[])
{
std::vectorstd::string vecPathes;

if(GetVisualStudioEnv(“INCLUDE”,vecPathes) )
{
for( unsigned int i = 0; i < vecPathes.size(); i++ )
{
printf("’%s’\n", vecPathes[i].c_str());
}
}

//printf(“env: ‘%s’\n”,exec(“set INCLUDE”).c_str());
return 0;
}

So this is my initial proposal for API / include / folder pathes obtaining.