mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 13:22:11 +00:00
Add a default exec path logic.
This adds default/fallback logic to determine the b2 exec absolute path as possible. It uses the arg0 and current dir or path to construct the liekliest path. fixes #25
This commit is contained in:
@@ -28,9 +28,10 @@
|
||||
*/
|
||||
|
||||
#include "jam.h"
|
||||
#include "pathsys.h"
|
||||
|
||||
#include "cwd.h"
|
||||
#include "filesys.h"
|
||||
#include "pathsys.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
@@ -364,3 +365,105 @@ std::string b2::paths::normalize(const std::string &p)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* executable_path()
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
char buf[ 1024 ];
|
||||
DWORD const ret = GetModuleFileNameA( NULL, buf, sizeof( buf ) );
|
||||
return ( !ret || ret == sizeof( buf ) ) ? NULL : strdup( buf );
|
||||
}
|
||||
#elif defined(__APPLE__) /* Not tested */
|
||||
# include <mach-o/dyld.h>
|
||||
char *executable_path( char const * argv0 )
|
||||
{
|
||||
char buf[ 1024 ];
|
||||
uint32_t size = sizeof( buf );
|
||||
return _NSGetExecutablePath( buf, &size ) ? NULL : strdup( buf );
|
||||
}
|
||||
#elif defined(sun) || defined(__sun) /* Not tested */
|
||||
# include <stdlib.h>
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
const char * execname = getexecname();
|
||||
return execname ? strdup( execname ) : NULL;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
int mib[ 4 ] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
char buf[ 1024 ];
|
||||
size_t size = sizeof( buf );
|
||||
sysctl( mib, 4, buf, &size, NULL, 0 );
|
||||
return ( !size || size == sizeof( buf ) ) ? NULL : strndup( buf, size );
|
||||
}
|
||||
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__)
|
||||
# include <unistd.h>
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
char buf[ 1024 ];
|
||||
ssize_t const ret = readlink( "/proc/self/exe", buf, sizeof( buf ) );
|
||||
return ( !ret || ret == sizeof( buf ) ) ? NULL : strndup( buf, ret );
|
||||
}
|
||||
#elif defined(OS_VMS)
|
||||
# include <unixlib.h>
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
char * vms_path = NULL;
|
||||
char * posix_path = NULL;
|
||||
char * p;
|
||||
|
||||
/* On VMS argv[0] shows absolute path to the image file.
|
||||
* So, just remove VMS file version and translate path to POSIX-style.
|
||||
*/
|
||||
vms_path = strdup( argv0 );
|
||||
if ( vms_path && ( p = strchr( vms_path, ';') ) ) *p = '\0';
|
||||
posix_path = decc$translate_vms( vms_path );
|
||||
if ( vms_path ) free( vms_path );
|
||||
|
||||
return posix_path > 0 ? strdup( posix_path ) : NULL;
|
||||
}
|
||||
#else
|
||||
char * executable_path( char const * argv0 )
|
||||
{
|
||||
char * result = nullptr;
|
||||
/* If argv0 is an absolute path, assume it is the right absolute path. */
|
||||
if (!result && b2::paths::is_rooted(argv0))
|
||||
result = strdup( argv0 );
|
||||
// If argv0 is a relative path, we can compute the absolute one from the
|
||||
// current working dir.
|
||||
if (!result && b2::paths::is_relative(argv0))
|
||||
{
|
||||
auto p = b2::paths::normalize(b2::cwd_str()+"/"+argv0);
|
||||
result = strdup( p.c_str() );
|
||||
}
|
||||
// If it's a bare basename, search the PATH for a match.
|
||||
if (!result)
|
||||
{
|
||||
std::string path_env = getenv( "PATH" );
|
||||
std::string::size_type i = 0;
|
||||
while (i != std::string::npos)
|
||||
{
|
||||
std::string::size_type e = path_env.find_first_of(':', i);
|
||||
std::string p = e == std::string::npos
|
||||
? path_env.substr(i)
|
||||
: path_env.substr(i, e-i);
|
||||
if (b2::filesys::is_file(p+"/"+argv0))
|
||||
{
|
||||
result = strdup( (p+"/"+argv0).c_str() );
|
||||
break;
|
||||
}
|
||||
i = e == std::string::npos ? e : e+1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user