// options.c -- handle command line options for gold
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
#include "script.h"
#include "target-select.h"
#include "options.h"
+#include "plugin.h"
namespace gold
{
cmdline->script_options().define_symbol(arg);
}
+void
+General_options::parse_incremental_changed(const char*, const char*,
+ Command_line*)
+{
+ this->implicit_incremental_ = true;
+ this->incremental_disposition_ = INCREMENTAL_CHANGED;
+}
+
+void
+General_options::parse_incremental_unchanged(const char*, const char*,
+ Command_line*)
+{
+ this->implicit_incremental_ = true;
+ this->incremental_disposition_ = INCREMENTAL_UNCHANGED;
+}
+
+void
+General_options::parse_incremental_unknown(const char*, const char*,
+ Command_line*)
+{
+ this->implicit_incremental_ = true;
+ this->incremental_disposition_ = INCREMENTAL_CHECK;
+}
+
void
General_options::parse_library(const char*, const char* arg,
Command_line* cmdline)
cmdline->inputs().add_file(file);
}
+#ifdef ENABLE_PLUGINS
+void
+General_options::parse_plugin(const char*, const char* arg,
+ Command_line*)
+{
+ this->add_plugin(arg);
+}
+
+// Parse --plugin-opt.
+
+void
+General_options::parse_plugin_opt(const char*, const char* arg,
+ Command_line*)
+{
+ this->add_plugin_option(arg);
+}
+#endif // ENABLE_PLUGINS
+
void
General_options::parse_R(const char* option, const char* arg,
Command_line* cmdline)
gold::gold_fatal(_("unable to parse version script file %s"), arg);
}
+void
+General_options::parse_dynamic_list(const char*, const char* arg,
+ Command_line* cmdline)
+{
+ if (!read_dynamic_list(arg, cmdline, &this->dynamic_list_))
+ gold::gold_fatal(_("unable to parse dynamic-list script file %s"), arg);
+}
+
void
General_options::parse_start_group(const char*, const char*,
Command_line* cmdline)
// If the default sysroot is relocatable, try relocating it based on
// the prefix FROM.
-char*
+static char*
get_relative_sysroot(const char* from)
{
char* path = make_relative_prefix(gold::program_name, from,
// get_relative_sysroot, which is a small memory leak, but is
// necessary since we store this pointer directly in General_options.
-const char*
+static const char*
get_default_sysroot()
{
const char* sysroot = TARGET_SYSTEM_ROOT;
// We handle -z as a special case.
static gold::options::One_option dash_z("", gold::options::DASH_Z,
- 'z', "", "-z", "Z-OPTION", false,
+ 'z', "", NULL, "Z-OPTION", false,
NULL);
gold::options::One_option* retval = NULL;
if (this_argv[pos_in_argv_i] == 'z')
General_options::General_options()
: execstack_status_(General_options::EXECSTACK_FROM_INPUT), static_(false),
- do_demangle_(false)
+ do_demangle_(false), plugins_(),
+ incremental_disposition_(INCREMENTAL_CHECK), implicit_incremental_(false)
{
}
free(canonical_sysroot);
}
+// Return whether FILENAME is in a system directory.
+
+bool
+General_options::is_in_system_directory(const std::string& filename) const
+{
+ for (Dir_list::const_iterator p = this->library_path_.value.begin();
+ p != this->library_path_.value.end();
+ ++p)
+ {
+ // We use a straight string comparison rather than calling
+ // FILENAME_CMP because we are only interested in the cases
+ // where we found the file in a system directory, which means
+ // that we used the directory name as a prefix for a -L search.
+ if (p->is_system_directory()
+ && filename.compare(0, p->name().size(), p->name()) == 0)
+ return true;
+ }
+ return false;
+}
+
+// Add a plugin to the list of plugins.
+
+void
+General_options::add_plugin(const char* filename)
+{
+ if (this->plugins_ == NULL)
+ this->plugins_ = new Plugin_manager(*this);
+ this->plugins_->add_plugin(filename);
+}
+
+// Add a plugin option to a plugin.
+
+void
+General_options::add_plugin_option(const char* arg)
+{
+ if (this->plugins_ == NULL)
+ gold_fatal("--plugin-opt requires --plugin.");
+ this->plugins_->add_plugin_option(arg);
+}
+
// Set up variables and other state that isn't set up automatically by
// the parse routine, and ensure options don't contradict each other
// and are otherwise kosher.
if (this->strip_debug_non_line())
this->set_strip_debug_gdb(true);
+ if (this->Bshareable())
+ this->set_shared(true);
+
// If the user specifies both -s and -r, convert the -s to -S.
// -r requires us to keep externally visible symbols!
if (this->strip_all() && this->relocatable())
this->set_user_set_Map();
}
+ // Using -n or -N implies -static.
+ if (this->nmagic() || this->omagic())
+ this->set_static(true);
+
// If --thread_count is specified, it applies to
// --thread-count-{initial,middle,final}, though it doesn't override
// them.
this->add_to_library_path_with_sysroot("/usr/lib");
}
+ if (this->shared() && !this->user_set_allow_shlib_undefined())
+ this->set_allow_shlib_undefined(true);
+
// Normalize library_path() by adding the sysroot to all directories
// in the path, as appropriate.
this->add_sysroot();
// Now that we've normalized the options, check for contradictory ones.
+ if (this->shared() && this->is_static())
+ gold_fatal(_("-shared and -static are incompatible"));
+
if (this->shared() && this->relocatable())
gold_fatal(_("-shared and -r are incompatible"));
"[0.0, 1.0)"),
this->hash_bucket_empty_fraction());
+ if (this->implicit_incremental_ && !this->incremental())
+ gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
+ "--incremental-unknown require the use of --incremental"));
+
// FIXME: we can/should be doing a lot more sanity checking here.
}