Full support for --sysroot.

This commit is contained in:
Ian Lance Taylor
2007-10-04 05:49:04 +00:00
parent 4638dbaa96
commit ad2d6943a4
18 changed files with 421 additions and 85 deletions

View File

@@ -20,9 +20,13 @@
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#include <iostream>
#include "gold.h"
#include <iostream>
#include <sys/stat.h>
#include "filenames.h"
#include "libiberty.h"
#include "options.h"
namespace gold
@@ -216,6 +220,51 @@ help(int, char**, char*, gold::Command_line*)
return 0;
}
// If the default sysroot is relocatable, try relocating it based on
// the prefix FROM.
char*
get_relative_sysroot(const char* from)
{
char* path = make_relative_prefix(gold::program_name, from,
TARGET_SYSTEM_ROOT);
if (path != NULL)
{
struct stat s;
if (::stat(path, &s) == 0 && S_ISDIR(s.st_mode))
return path;
free(path);
}
return NULL;
}
// Return the default sysroot. This is set by the --with-sysroot
// option to configure.
std::string
get_default_sysroot()
{
const char* sysroot = TARGET_SYSTEM_ROOT;
if (*sysroot == '\0')
return "";
if (TARGET_SYSTEM_ROOT_RELOCATABLE)
{
char* path = get_relative_sysroot (BINDIR);
if (path == NULL)
path = get_relative_sysroot (TOOLBINDIR);
if (path != NULL)
{
std::string ret = path;
free(path);
return ret;
}
}
return sysroot;
}
} // End anonymous namespace.
namespace gold
@@ -285,8 +334,8 @@ options::Command_line_options::options[] =
NULL, ONE_DASH, &General_options::set_shared),
GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
NULL, ONE_DASH, &General_options::set_static),
GENERAL_ARG('\0', "sysroot", N_("Currently ignored"), NULL, TWO_DASHES,
&General_options::ignore),
GENERAL_ARG('\0', "sysroot", N_("Set target system root directory"),
N_("--sysroot DIR"), TWO_DASHES, &General_options::set_sysroot),
POSDEP_NOARG('\0', "as-needed",
N_("Only set DT_NEEDED for dynamic libs if used"),
NULL, TWO_DASHES, &Position_dependent_options::set_as_needed),
@@ -321,7 +370,8 @@ General_options::General_options()
rpath_(),
rpath_link_(),
is_shared_(false),
is_static_(false)
is_static_(false),
sysroot_()
{
}
@@ -334,6 +384,66 @@ Position_dependent_options::Position_dependent_options()
{
}
// Add the sysroot, if any, to the search paths.
void
General_options::add_sysroot()
{
if (this->sysroot_.empty())
{
this->sysroot_ = get_default_sysroot();
if (this->sysroot_.empty())
return;
}
const char* sysroot = this->sysroot_.c_str();
char* canonical_sysroot = lrealpath(sysroot);
for (Dir_list::iterator p = this->search_path_.begin();
p != this->search_path_.end();
++p)
p->add_sysroot(sysroot, canonical_sysroot);
free(canonical_sysroot);
}
// Search_directory methods.
// This is called if we have a sysroot. Apply the sysroot if
// appropriate. Record whether the directory is in the sysroot.
void
Search_directory::add_sysroot(const char* sysroot,
const char* canonical_sysroot)
{
gold_assert(*sysroot != '\0');
if (this->put_in_sysroot_)
{
if (!IS_DIR_SEPARATOR(this->name_[0])
&& !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
this->name_ = '/' + this->name_;
this->name_ = sysroot + this->name_;
this->is_in_sysroot_ = true;
}
else
{
// Check whether this entry is in the sysroot. To do this
// correctly, we need to use canonical names. Otherwise we will
// get confused by the ../../.. paths that gcc tends to use.
char* canonical_name = lrealpath(this->name_.c_str());
int canonical_name_len = strlen(canonical_name);
int canonical_sysroot_len = strlen(canonical_sysroot);
if (canonical_name_len > canonical_sysroot_len
&& IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
{
canonical_name[canonical_sysroot_len] = '\0';
if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
this->is_in_sysroot_ = true;
}
free(canonical_name);
}
}
// Input_arguments methods.
// Add a file to the list.
@@ -414,8 +524,12 @@ Command_line::process(int argc, char** argv)
char first = opt[0];
int skiparg = 0;
char* arg = strchr(opt, '=');
bool argument_with_equals = arg != NULL;
if (arg != NULL)
*arg = '\0';
{
*arg = '\0';
++arg;
}
else if (i + 1 < argc)
{
arg = argv[i + 1];
@@ -438,6 +552,8 @@ Command_line::process(int argc, char** argv)
{
if (!options[j].takes_argument())
{
if (argument_with_equals)
this->usage(_("unexpected argument"), argv[i]);
arg = NULL;
skiparg = 0;
}
@@ -517,8 +633,10 @@ Command_line::process(int argc, char** argv)
}
// FIXME: We should only do this when configured in native mode.
this->options_.add_to_search_path("/lib");
this->options_.add_to_search_path("/usr/lib");
this->options_.add_to_search_path_with_sysroot("/lib");
this->options_.add_to_search_path_with_sysroot("/usr/lib");
this->options_.add_sysroot();
}
// Apply a command line option.