summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-09-08 16:06:48 +1000
committerChris Johns <chrisj@rtems.org>2014-09-08 16:06:48 +1000
commit52d988128d5014002b0431f7d4f5de0ff50f92a9 (patch)
treee8101d9dd4926db4077413fecbaa18f490c5e26b
parent4c9a892d009c5b8f1952cf3450dda32148af887e (diff)
RTEMS trace linker builds trace applications.
The trace linker builds the both_hello example in examples-v2. Move the various string support functions into a C++ file and stop being inlined. Make them return const std::string. Add ld support to rld-cc. Add search path support to rld-config so installed common files can be used. Fix the path bugs. Add an absolute path function to rld-path.
-rw-r--r--rld-cc.cpp49
-rw-r--r--rld-cc.h20
-rw-r--r--rld-config.cpp47
-rw-r--r--rld-config.h18
-rw-r--r--rld-path.cpp62
-rw-r--r--rld-path.h25
-rw-r--r--rld.cpp149
-rw-r--r--rld.h139
-rw-r--r--rtems-ld.cpp2
-rw-r--r--rtems-tld.cpp126
-rw-r--r--wscript2
11 files changed, 489 insertions, 150 deletions
diff --git a/rld-cc.cpp b/rld-cc.cpp
index 29eebbb..a2b1be4 100644
--- a/rld-cc.cpp
+++ b/rld-cc.cpp
@@ -30,7 +30,12 @@ namespace rld
static std::string cc; //< The CC executable as absolute path.
static bool cc_set; //< True when the CC has been set.
static std::string cc_name = "gcc"; //< The CC name, ie gcc, clang.
- static std::string exec_prefix; //< The CC executable prefix.
+
+ static std::string ld; //< The LD executable as absolute path.
+ static bool ld_set; //< True when the LD has been set.
+ static std::string ld_name = "gcc"; //< The LD name, ie gcc, clang.
+
+ static std::string exec_prefix; //< The CC/LD executable prefix.
static std::string cppflags; //< The CPP flags.
static std::string cflags; //< The CC flags.
@@ -250,6 +255,25 @@ namespace rld
}
void
+ set_ld (const std::string& ld_)
+ {
+ ld = ld_;
+ ld_set = true;
+ }
+
+ const std::string
+ get_ld ()
+ {
+ return ld;
+ }
+
+ bool
+ is_ld_set ()
+ {
+ return ld_set;
+ }
+
+ void
set_exec_prefix (const std::string& exec_prefix_)
{
exec_prefix = exec_prefix_;
@@ -418,8 +442,10 @@ namespace rld
/*
* Use the absolute path to CC if provided.
*/
- if (!cc.empty ())
+ if (is_cc_set ())
+ {
args.push_back (cc);
+ }
else
{
std::string cmd = cc_name;
@@ -429,6 +455,25 @@ namespace rld
}
}
+ void
+ make_ld_command (rld::process::arg_container& args)
+ {
+ /*
+ * Use the absolute path to LD if provided.
+ */
+ if (is_ld_set ())
+ {
+ args.push_back (get_ld ());
+ }
+ else
+ {
+ std::string cmd = ld_name;
+ if (!exec_prefix.empty ())
+ cmd = exec_prefix + "-rtems" + rld::rtems::version () + '-' + cmd;
+ args.push_back (cmd);
+ }
+ }
+
static bool
match_and_trim (const char* prefix, std::string& line, std::string& result)
{
diff --git a/rld-cc.h b/rld-cc.h
index a16bd3e..6c200d2 100644
--- a/rld-cc.h
+++ b/rld-cc.h
@@ -121,6 +121,21 @@ namespace rld
bool is_cc_set ();
/**
+ * Set LD. The exec-prefix is ignored if this is set.
+ */
+ void set_ld (const std::string& ld);
+
+ /**
+ * Get the LD.
+ */
+ const std::string get_ld ();
+
+ /**
+ * Is the LD set ?
+ */
+ bool is_ld_set ();
+
+ /**
* Set the exec-prefix. If CC is set the exec-prefix is ignored.
*/
void set_exec_prefix (const std::string& exec_prefix);
@@ -178,6 +193,11 @@ namespace rld
void make_cc_command (rld::process::arg_container& args);
/**
+ * Make a LD command from the set arguments.
+ */
+ void make_ld_command (rld::process::arg_container& args);
+
+ /**
* Get the standard libraries paths from the compiler.
*/
void get_standard_libpaths (rld::path::paths& libpaths);
diff --git a/rld-config.cpp b/rld-config.cpp
index ee619c8..3a372ad 100644
--- a/rld-config.cpp
+++ b/rld-config.cpp
@@ -56,7 +56,7 @@ namespace rld
throw error ("not found", "config record: " + this->name + '/' + name);
}
- std::string
+ const std::string
section::get_record_item (const std::string& rec_name) const
{
const record& rec = get_record (rec_name);
@@ -78,8 +78,9 @@ namespace rld
}
}
- config::config()
+ config::config(const std::string& search_path)
{
+ set_search_path (search_path);
}
config::~config()
@@ -87,6 +88,13 @@ namespace rld
}
void
+ config::set_search_path (const std::string& search_path)
+ {
+ if (!search_path.empty ())
+ rld::path::path_split (search_path, search);
+ }
+
+ void
config::clear ()
{
secs.clear ();
@@ -97,10 +105,34 @@ namespace rld
{
CSimpleIniCaseA ini (false, true, true);
- if (ini.LoadFile (path.c_str ()) != SI_OK)
+ std::string checked_path;
+
+ if (rld::path::check_file (path))
+ {
+ checked_path = path;
+ }
+ else
+ {
+ bool found = false;
+ for (rld::path::paths::const_iterator spi = search.begin ();
+ spi != search.end ();
+ ++spi)
+ {
+ rld::path::path_join (*spi, path, checked_path);
+ if (rld::path::check_file (checked_path))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ throw rld::error ("Not found.", "load config: " + path);
+ }
+
+ if (ini.LoadFile (checked_path.c_str ()) != SI_OK)
throw rld::error (::strerror (errno), "load config: " + path);
- paths_.push_back (path);
+ paths_.push_back (checked_path);
/*
* Merge the loaded configuration into our configuration.
@@ -162,12 +194,7 @@ namespace rld
have_includes = true;
/*
- * Include records are a path which we can just load.
- *
- * @todo Add a search path. See 'rld::files' for details. We can default
- * the search path to the install $prefix of this tool and we can
- * then provide a default set of function signatures for RTEMS
- * APIs.
+ * Include records are a paths which we can load.
*/
for (rld::strings::const_iterator isi = is.begin ();
diff --git a/rld-config.h b/rld-config.h
index b8bd495..52153d2 100644
--- a/rld-config.h
+++ b/rld-config.h
@@ -95,7 +95,7 @@ namespace rld
* Return the single item in a record. If the record is duplicated an
* error is thrown.
*/
- std::string get_record_item (const std::string& name) const;
+ const std::string get_record_item (const std::string& name) const;
/**
* Return the list of items in a record in a strings container.
@@ -122,10 +122,19 @@ namespace rld
/**
* Construct an empty configuration.
*/
- config();
+ config(const std::string& search_path = "");
+
+ /**
+ * Desctruct the configuration object.
+ */
virtual ~config();
/**
+ * Set the search path.
+ */
+ void set_search_path (const std::string& search_path);
+
+ /**
* Clear the current configuration.
*/
void clear ();
@@ -154,8 +163,9 @@ namespace rld
private:
- paths paths_; /**< The path's of the loaded files. */
- sections secs; /**< The sections loaded from configuration files */
+ paths search; //< The paths to search for config files in.
+ paths paths_; //< The path's of the loaded files.
+ sections secs; //< The sections loaded from configuration files
};
/**
diff --git a/rld-path.cpp b/rld-path.cpp
index 2163706..70a9c24 100644
--- a/rld-path.cpp
+++ b/rld-path.cpp
@@ -27,7 +27,7 @@ namespace rld
{
namespace path
{
- std::string
+ const std::string
basename (const std::string& name)
{
size_t b = name.find_last_of (RLD_PATH_SEPARATOR);
@@ -36,16 +36,16 @@ namespace rld
return name;
}
- std::string
+ const std::string
dirname (const std::string& name)
{
size_t b = name.find_last_of (RLD_PATH_SEPARATOR);
if (b != std::string::npos)
- return name.substr (0, b - 1);
+ return name.substr (0, b);
return name;
}
- std::string
+ const std::string
extension (const std::string& name)
{
size_t b = name.find_last_of ('.');
@@ -96,6 +96,60 @@ namespace rld
}
}
+ const std::string
+ path_abs (const std::string& path)
+ {
+ std::string apath;
+
+ if (path[0] == RLD_PATH_SEPARATOR)
+ {
+ apath = path;
+ }
+ else
+ {
+ char* buf = 0;
+ try
+ {
+ buf = new char[32 * 1024];
+ if (!::getcwd (buf, 132 * 1024))
+ throw rld::error (::strerror (errno), "get current working directory");
+ path_join (buf, path, apath);
+ }
+ catch (...)
+ {
+ delete [] buf;
+ throw;
+ }
+ }
+
+ strings ps;
+ strings aps;
+
+ rld::split (ps, apath, RLD_PATH_SEPARATOR);
+
+ for (strings::iterator psi = ps.begin ();
+ psi != ps.end ();
+ ++psi)
+ {
+ const std::string& dir = *psi;
+
+ if (dir.empty () || dir == ".")
+ {
+ /* do nothing */
+ }
+ else if (dir == "..")
+ {
+ aps.pop_back ();
+ }
+ else
+ {
+ aps.push_back (dir);
+ }
+ }
+
+ return RLD_PATH_SEPARATOR + rld::join (aps, RLD_PATH_SEPARATOR_STR);
+ }
+
bool
check_file (const std::string& path)
{
diff --git a/rld-path.h b/rld-path.h
index 0e1329a..d73c59b 100644
--- a/rld-path.h
+++ b/rld-path.h
@@ -45,29 +45,29 @@ namespace rld
* Return the basename of the file name.
*
* @param name The full file name.
- * @return std::string The basename of the file.
+ * @return const std::string The basename of the file.
*/
- std::string basename (const std::string& name);
+ const std::string basename (const std::string& name);
/**
* Return the dirname of the file name.
*
* @param name The full file name.
- * @return std::string The dirname of the file.
+ * @return const std::string The dirname of the file.
*/
- std::string dirname (const std::string& name);
+ const std::string dirname (const std::string& name);
/**
* Return the extension of the file name.
*
* @param name The full file name.
- * @return std::string The extension of the file.
+ * @return const std::string The extension of the file.
*/
- std::string extension (const std::string& name);
+ const std::string extension (const std::string& name);
/**
- * Split a path from a string with a delimiter to the path container. Add
- * only the paths that exist and ignore those that do not.
+ * Split a path from a string with the path seperator to the path
+ * container. Add only the paths that exist and ignore those that do not.
*
* @param path The paths as a single string delimited by the path
* separator.
@@ -100,6 +100,15 @@ namespace rld
std::string& joined);
/**
+ * Return the absolute path given a path and using the current working
+ * directory. The path is flattened removing any '..' sequences.
+ *
+ * @param path The path to be return as absolute.
+ * @return const std::string The absolute path.
+ */
+ const std::string path_abs (const std::string& path);
+
+ /**
* Check the path is a file using a stat call.
*
* @param path The path to check.
diff --git a/rld.cpp b/rld.cpp
index a239ddc..ca29297 100644
--- a/rld.cpp
+++ b/rld.cpp
@@ -39,6 +39,7 @@
namespace rld
{
static int verbose_level = 0;
+ static std::string progname;
/**
* The option container.
@@ -63,7 +64,119 @@ namespace rld
/**
* The output passed on the command line.
*/
- static std::string output;
+ //static std::string output;
+
+ bool
+ starts_with(const std::string& s1, const std::string& s2)
+ {
+ return s2.size () <= s1.size () && s1.compare (0, s2.size (), s2) == 0;
+ }
+
+ const std::string
+ ltrim (const std::string& s)
+ {
+ std::string t = s;
+ t.erase (t.begin (),
+ std::find_if (t.begin (), t.end (),
+ std::not1 (std::ptr_fun < int, int > (std::isspace))));
+ return t;
+ }
+
+ const std::string
+ rtrim (const std::string& s)
+ {
+ std::string t = s;
+ t.erase (std::find_if (t.rbegin (), t.rend (),
+ std::not1 (std::ptr_fun < int, int > (std::isspace))).base(),
+ t.end());
+ return t;
+ }
+
+ const std::string
+ trim (const std::string& s)
+ {
+ return ltrim (rtrim (s));
+ }
+
+ const std::string
+ dequote (const std::string& s)
+ {
+ if (!s.empty ())
+ {
+ char front = s[0];
+ char back = s[s.length () - 1];
+ if ((front == '"') || (front == '\''))
+ {
+ if (front != back)
+ throw rld::error ("invalid quoting", "string: " + s);
+ return s.substr (1, s.length () - (1 + 1));
+ }
+ }
+ return s;
+ }
+
+ const std::string
+ find_replace(const std::string& sin,
+ const std::string& out,
+ const std::string& in)
+ {
+ std::string s = sin;
+ size_t pos = 0;
+ while ((pos = s.find (out, pos)) != std::string::npos)
+ {
+ s.replace (pos, out.length (), in);
+ pos += in.length ();
+ }
+ return s;
+ }
+
+ const strings
+ split (strings& se,
+ const std::string& s,
+ char delimiter,
+ bool strip_quotes,
+ bool strip_whitespace,
+ bool empty)
+ {
+ std::stringstream ss(s);
+ std::string e;
+ se.clear ();
+ while (std::getline (ss, e, delimiter))
+ {
+ if (strip_whitespace)
+ e = trim (e);
+ if (strip_quotes)
+ e = dequote (e);
+ if (empty || !e.empty ())
+ {
+ se.push_back (e);
+ }
+ }
+ return se;
+ }
+
+ const std::string
+ join (const strings& ss, const std::string& separator)
+ {
+ std::string s;
+ for (strings::const_iterator ssi = ss.begin ();
+ ssi != ss.end ();
+ ++ssi)
+ {
+ s += *ssi;
+ if ((ssi + 1) != ss.end ())
+ s += separator;
+ }
+ return s;
+ }
+
+ const std::string
+ tolower (const std::string& sin)
+ {
+ std::string s = sin;
+ std::transform (s.begin (), s.end (), s.begin (), ::tolower);
+ return s;
+ }
void
verbose_inc ()
@@ -93,6 +206,40 @@ namespace rld
}
void
+ set_progname (const std::string& progname_)
+ {
+ progname = rld::path::path_abs (progname_);
+ }
+
+ const std::string
+ get_progname ()
+ {
+ return progname;
+ }
+
+ const std::string
+ get_program_name ()
+ {
+ return rld::path::basename (progname);
+ }
+
+ const std::string
+ get_program_path ()
+ {
+ return rld::path::dirname (progname);
+ }
+
+ const std::string
+ get_prefix ()
+ {
+ std::string pp = get_program_path ();
+ std::cout << "PP=" << pp << std::endl;
+ if (rld::path::basename (pp) == "bin")
+ pp = rld::path::dirname (pp);
+ return pp;
+ }
+
+ void
map (rld::files::cache& cache, rld::symbols::table& symbols)
{
std::cout << "Archive files : " << cache.archive_count () << std::endl;
diff --git a/rld.h b/rld.h
index 6a42923..115b7b8 100644
--- a/rld.h
+++ b/rld.h
@@ -126,76 +126,34 @@ namespace rld
/**
* Does a string start with another string ?
*/
- inline bool starts_with(const std::string& s1, const std::string& s2)
- {
- return s2.size () <= s1.size () && s1.compare (0, s2.size (), s2) == 0;
- }
+ bool starts_with(const std::string& s1, const std::string& s2);
/**
* Trim from start.
*/
- inline std::string& ltrim (std::string &s)
- {
- s.erase (s.begin (),
- std::find_if (s.begin (), s.end (),
- std::not1 (std::ptr_fun < int, int > (std::isspace))));
- return s;
- }
+ const std::string ltrim (const std::string& s);
/**
* Trim from end.
*/
- inline std::string& rtrim (std::string &s)
- {
- s.erase (std::find_if (s.rbegin (), s.rend (),
- std::not1 (std::ptr_fun < int, int > (std::isspace))).base(),
- s.end());
- return s;
- }
+ const std::string rtrim (const std::string& s);
/**
* Trim from both ends.
*/
- inline std::string& trim (std::string &s)
- {
- return ltrim (rtrim (s));
- }
+ const std::string trim (const std::string& s);
/**
* Dequote a string.
*/
- inline std::string dequote (const std::string& s)
- {
- if (!s.empty ())
- {
- char front = s[0];
- char back = s[s.length () - 1];
- if ((front == '"') || (front == '\''))
- {
- if (front != back)
- throw rld::error ("invalid quoting", "string: " + s);
- return s.substr (1, s.length () - (1 + 1));
- }
- }
- return s;
- }
+ const std::string dequote (const std::string& s);
/**
* Find and replace.
*/
- inline std::string find_replace(const std::string& sin,
- const std::string& out,
- const std::string& in)
- {
- std::string s = sin;
- size_t pos = 0;
- while ((pos = s.find (out, pos)) != std::string::npos)
- {
- s.replace (pos, out.length (), in);
- pos += in.length ();
- }
- return s;
- }
+ const std::string find_replace(const std::string& sin,
+ const std::string& out,
+ const std::string& in);
/**
* Split the string in a contain of strings based on the the
@@ -203,57 +161,22 @@ namespace rld
*
* @todo The split should optionally honour string quoting.
*/
- inline strings split (strings& se,
- const std::string& s,
- char delimiter = ' ',
- bool strip_quotes = true,
- bool strip_whitespace = true,
- bool empty = false)
- {
- std::stringstream ss(s);
- std::string e;
- se.clear ();
- while (std::getline (ss, e, delimiter))
- {
- if (strip_whitespace)
- trim (e);
- if (strip_quotes)
- e = dequote (e);
- if (empty || !e.empty ())
- {
- se.push_back (e);
- }
- }
- return se;
- }
+ const strings split (strings& se,
+ const std::string& s,
+ char delimiter = ' ',
+ bool strip_quotes = true,
+ bool strip_whitespace = true,
+ bool empty = false);
/**
* Join the strings together with the separator.
*/
- inline std::string join (const strings& ss,
- const std::string& separator)
- {
- std::string s;
- for (strings::const_iterator ssi = ss.begin ();
- ssi != ss.end ();
- ++ssi)
- {
- s += *ssi;
- if ((ssi != ss.begin ()) && (ssi != ss.end ()))
- s += separator;
- }
- return s;
- }
+ const std::string join (const strings& ss, const std::string& separator);
/**
* Convert a string to lower case.
*/
- inline std::string tolower (const std::string& sin)
- {
- std::string s = sin;
- std::transform (s.begin (), s.end (), s.begin (), ::tolower);
- return s;
- }
+ const std::string tolower (const std::string& sin);
/**
* Increment the verbose level.
@@ -277,12 +200,40 @@ namespace rld
typedef std::vector < std::string > strings;
/**
+ * Set the progname.
+ */
+ void set_progname (const std::string& progname);
+
+ /**
+ * Get the progname. This is an absolute path.
+ */
+ const std::string get_progname ();
+
+ /**
+ * Get the program name.
+ */
+ const std::string get_program_name ();
+
+ /**
+ * Get the program path.
+ */
+ const std::string get_program_path ();
+
+ /**
+ * Get the current install prefix. If the path to the executable has 'bin' as
+ * the executable's parent directory it is assumed the executable has been
+ * installed under a standard PREFIX. If "bin" is not found return the
+ * executable's absolute path.
+ */
+ const std::string get_prefix ();
+
+ /**
* Map of the symbol table.
*/
void map (rld::files::cache& cache, rld::symbols::table& symbols);
/**
- * Warn is externals in referenced object files are not used.
+ * Warn if externals in referenced object files are not used.
*/
void warn_unused_externals (rld::files::object_list& objects);
}
diff --git a/rtems-ld.cpp b/rtems-ld.cpp
index dfa5c14..f678cde 100644
--- a/rtems-ld.cpp
+++ b/rtems-ld.cpp
@@ -356,7 +356,7 @@ main (int argc, char* argv[])
if (!rtems_arch_bsp.empty ())
{
if (rtems_path.empty ())
- throw rld::error ("arch/bsp provide and no RTEMS path", "options");
+ throw rld::error ("No RTEMS path provide with arch/bsp", "options");
rld::rtems::set_path (rtems_path);
rld::rtems::set_arch_bsp (rtems_arch_bsp);
}
diff --git a/rtems-tld.cpp b/rtems-tld.cpp
index c6d5c55..28f154d 100644
--- a/rtems-tld.cpp
+++ b/rtems-tld.cpp
@@ -90,7 +90,7 @@ namespace rld
/**
* Return the function's declaration.
*/
- const std::string decl () const;
+ const std::string decl (const std::string& prefix = "") const;
};
/**
@@ -194,6 +194,11 @@ namespace rld
void generate_traces (rld::process::tempfile& c);
/**
+ * Get the traces.
+ */
+ const rld::strings& get_traces () const;
+
+ /**
* Dump the wrapper.
*/
void dump (std::ostream& out) const;
@@ -321,9 +326,9 @@ namespace rld
}
const std::string
- signature::decl () const
+ signature::decl (const std::string& prefix) const
{
- std::string ds = ret + ' ' + name + '(';
+ std::string ds = ret + ' ' + prefix + name + '(';
int arg = 0;
for (function_args::const_iterator ai = args.begin ();
ai != args.end ();
@@ -485,7 +490,6 @@ namespace rld
* configuration and may contain:
*
* # name The name of trace being linked.
- * # bsp The architecture/bsp name of the BSP.
* # options A list of options as per the long command line args.
* # traces The list of sections containing function lists to trace.
* # functions The list of sections containing function details.
@@ -503,7 +507,6 @@ namespace rld
config.includes (section);
name = section.get_record_item ("name");
- bsp = section.get_record_item ("bsp");
load_functions (config, section);
load_traces (config, section);
@@ -640,7 +643,7 @@ namespace rld
const signature& sig = (*si).second;
c.write_line("");
- c.write_line(sig.decl ());
+ c.write_line(sig.decl ("__wrap_"));
c.write_line("{");
std::string l;
@@ -655,7 +658,7 @@ namespace rld
l = " ret =";
}
- l += " " + generator_.map_sym_prefix + sig.name + '(';
+ l += " __real_" + sig.name + '(';
for (size_t a = 0; a < sig.args.size (); ++a)
{
if (a)
@@ -679,6 +682,12 @@ namespace rld
}
}
+ const rld::strings&
+ tracer::get_traces () const
+ {
+ return traces;
+ }
+
void
tracer::dump (std::ostream& out) const
{
@@ -710,6 +719,16 @@ namespace rld
linker::load_config (const std::string& path,
const std::string& trace)
{
+ std::string sp = get_prefix ();
+
+ rld::path::path_join (sp, "share", sp);
+ rld::path::path_join (sp, "rtems", sp);
+ rld::path::path_join (sp, "trace-linker", sp);
+
+ if (rld::verbose () || true)
+ std::cout << "search path: " << sp << std::endl;
+
+ config.set_search_path (sp);
config.clear ();
config.load (path);
tracer_.load (config, trace);
@@ -759,9 +778,38 @@ namespace rld
void
linker::link (rld::process::tempfile& o,
- const std::string& ld_cmds)
+ const std::string& ld_cmd)
{
+ rld::process::arg_container args;
+
+ if (rld::verbose ())
+ std::cout << "linking: " << o.name () << std::endl;
+
+ std::string wrap = " -Wl,--wrap -Wl,";
+
+ rld::cc::make_ld_command (args);
+
+ args.push_back (o.name ());
+
+ rld::process::args_append (args, ld_cmd);
+ rld::process::args_append (args,
+ wrap + rld::join (tracer_.get_traces (), wrap));
+
+ rld::process::tempfile out;
+ rld::process::tempfile err;
+ rld::process::status status;
+
+ status = rld::process::execute (rld::cc::get_ld (),
+ args,
+ out.name (),
+ err.name ());
+ if ((status.type != rld::process::status::normal) ||
+ (status.code != 0))
+ {
+ err.output (rld::cc::get_cc (), std::cout);
+ throw rld::error ("Linker error", "linking");
+ }
}
void
@@ -792,9 +840,10 @@ static struct option rld_opts[] = {
{ "verbose", no_argument, NULL, 'v' },
{ "warn", no_argument, NULL, 'w' },
{ "keep", no_argument, NULL, 'k' },
+ { "compiler", required_argument, NULL, 'c' },
{ "linker", required_argument, NULL, 'l' },
{ "exec-prefix", required_argument, NULL, 'E' },
- { "cflags", required_argument, NULL, 'c' },
+ { "cflags", required_argument, NULL, 'f' },
{ "rtems", required_argument, NULL, 'r' },
{ "rtems-bsp", required_argument, NULL, 'B' },
{ "config", required_argument, NULL, 'C' },
@@ -807,19 +856,20 @@ usage (int exit_code)
{
std::cout << "rtems-trace-ld [options] objects" << std::endl
<< "Options and arguments:" << std::endl
- << " -h : help (also --help)" << std::endl
- << " -V : print linker version number and exit (also --version)" << std::endl
- << " -v : verbose (trace import parts), can supply multiple times" << std::endl
- << " to increase verbosity (also --verbose)" << std::endl
- << " -w : generate warnings (also --warn)" << std::endl
- << " -k : keep temporary files (also --keep)" << std::endl
- << " -l linker : target linker is not standard (also --linker)" << std::endl
- << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl
- << " -c cflags : C compiler flags (also --cflags)" << std::endl
- << " -r path : RTEMS path (also --rtems)" << std::endl
- << " -B bsp : RTEMS arch/bsp (also --rtems-bsp)" << std::endl
- << " -W wrapper : wrapper file name without ext (also --wrapper)" << std::endl
- << " -C ini : user configuration INI file (also --config)" << std::endl;
+ << " -h : help (also --help)" << std::endl
+ << " -V : print linker version number and exit (also --version)" << std::endl
+ << " -v : verbose (trace import parts), can supply multiple times" << std::endl
+ << " to increase verbosity (also --verbose)" << std::endl
+ << " -w : generate warnings (also --warn)" << std::endl
+ << " -k : keep temporary files (also --keep)" << std::endl
+ << " -c compiler : target compiler is not standard (also --compiler)" << std::endl
+ << " -l linker : target linker is not standard (also --linker)" << std::endl
+ << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl
+ << " -f cflags : C compiler flags (also --cflags)" << std::endl
+ << " -r path : RTEMS path (also --rtems)" << std::endl
+ << " -B bsp : RTEMS arch/bsp (also --rtems-bsp)" << std::endl
+ << " -W wrappe r : wrapper file name without ext (also --wrapper)" << std::endl
+ << " -C ini : user configuration INI file (also --config)" << std::endl;
::exit (exit_code);
}
@@ -867,6 +917,7 @@ main (int argc, char* argv[])
try
{
rld::trace::linker linker;
+ std::string cc;
std::string ld;
std::string ld_cmd;
std::string configuration;
@@ -877,7 +928,7 @@ main (int argc, char* argv[])
while (true)
{
- int opt = ::getopt_long (argc, argv, "hvwkVl:E:c:C:r:B:W:", rld_opts, NULL);
+ int opt = ::getopt_long (argc, argv, "hvwkVc:l:E:f:C:r:B:W:", rld_opts, NULL);
if (opt < 0)
break;
@@ -903,6 +954,10 @@ main (int argc, char* argv[])
rld::process::set_keep_temporary_files ();
break;
+ case 'c':
+ cc = optarg;
+ break;
+
case 'l':
ld = optarg;
break;
@@ -911,7 +966,7 @@ main (int argc, char* argv[])
rld::cc::set_exec_prefix (optarg);
break;
- case 'c':
+ case 'f':
rld::cc::append_flags (optarg, rld::cc::ft_cflags);
break;
@@ -941,6 +996,11 @@ main (int argc, char* argv[])
}
}
+ /*
+ * Set the program name.
+ */
+ rld::set_progname (argv[0]);
+
argc -= optind;
argv += optind;
@@ -953,16 +1013,30 @@ main (int argc, char* argv[])
if (!rtems_arch_bsp.empty ())
{
if (rtems_path.empty ())
- throw rld::error ("arch/bsp provide and no RTEMS path", "options");
+ throw rld::error ("No RTEMS path provide with arch/bsp", "options");
rld::rtems::set_path (rtems_path);
rld::rtems::set_arch_bsp (rtems_arch_bsp);
}
+ /**
+ * Set the compiler and/or linker if provided.
+ */
+ if (!cc.empty ())
+ rld::cc::set_cc (cc);
+ if (!ld.empty ())
+ rld::cc::set_ld (ld);
+
/*
* Load the remaining command line arguments into the linker command line.
*/
while (argc--)
- ld_cmd += ' ' + *argv++;
+ {
+ /*
+ * Create this value because 'ld_cmd += ' ' + *argv++' fails on clang.
+ */
+ std::string av = *argv++;
+ ld_cmd += ' ' + av;
+ }
ld_cmd = rld::trim (ld_cmd);
/*
diff --git a/wscript b/wscript
index 7540566..400a792 100644
--- a/wscript
+++ b/wscript
@@ -165,6 +165,8 @@ def build(bld):
cxxflags = bld.cxxflags + bld.warningflags,
linkflags = bld.linkflags,
use = modules)
+ bld.install_files('${PREFIX}/share/rtems/trace-linker',
+ ['rtems.ini', 'rtld-base.ini'])
#
# Build the symbols.