summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-09-07 10:47:00 +1000
committerChris Johns <chrisj@rtems.org>2014-09-07 10:47:00 +1000
commit5c75d3435ae8e049a3049a6eec1295f1de2694cf (patch)
treef16740b1b5ce05adff8e9451cd58b347091ec0d4
parent7eb74f8b5318e14508eba980dc97c2813624963e (diff)
rtems-tld: Add --wrapper option to aid testing.
The --wrapper option lets a user control the wrapper file name and location to aid testing. Add keep support to tempfiles so specific tempfile can be set to be kept. Add unlink to the rld::path namespace.
-rw-r--r-- bin0 -> 1704 bytes
-rw-r--r--rld-path.cpp28
-rw-r--r--rld-path.h7
-rw-r--r--rld-process.cpp92
-rw-r--r--rld-process.h54
-rw-r--r--rld.h2
-rw-r--r--rtems-tld.cpp46
7 files changed, 169 insertions, 60 deletions
diff --git a/ b/
new file mode 100644
index 0000000..f646398
--- /dev/null
+++ b/
Binary files differ
diff --git a/rld-path.cpp b/rld-path.cpp
index 8e24d3a..2163706 100644
--- a/rld-path.cpp
+++ b/rld-path.cpp
@@ -19,6 +19,7 @@
#endif
#include <sys/stat.h>
+#include <unistd.h>
#include <rld.h>
@@ -83,7 +84,8 @@ namespace rld
joined = base + part;
}
- void path_join (const std::string& base, const paths& parts, std::string& joined)
+ void
+ path_join (const std::string& base, const paths& parts, std::string& joined)
{
joined = base;
for (paths::const_iterator pi = parts.begin ();
@@ -128,5 +130,29 @@ namespace rld
path.clear ();
}
+ void
+ unlink (const std::string& path, bool not_present_error)
+ {
+ struct stat sb;
+ if (::stat (path.c_str (), &sb) >= 0)
+ {
+ if (!S_ISREG (sb.st_mode))
+ throw rld::error ("Not a regular file", "unlinking: " + path);
+
+ int r;
+#if _WIN32
+ r = ::remove(path.c_str ());
+#else
+ r = ::unlink (path.c_str ());
+#endif
+ if (r < 0)
+ throw rld::error (::strerror (errno), "unlinking: " + path);
+ }
+ else
+ {
+ if (not_present_error)
+ throw rld::error ("Not found", "unlinking: " + path);
+ }
+ }
}
}
diff --git a/rld-path.h b/rld-path.h
index f501fb4..0e1329a 100644
--- a/rld-path.h
+++ b/rld-path.h
@@ -128,6 +128,13 @@ namespace rld
const std::string& name,
paths& search_paths);
+ /**
+ * Unlink the file.
+ *
+ * @param path The path of the file to unlink.
+ */
+ void unlink (const std::string& path, bool not_present_error = false);
+
}
}
diff --git a/rld-process.cpp b/rld-process.cpp
index 2174cce..1f0392f 100644
--- a/rld-process.cpp
+++ b/rld-process.cpp
@@ -60,7 +60,7 @@ namespace rld
namespace process
{
/**
- * Keep the temporary files if true. Used to help debug a system.
+ * Global keep of temporary files if true. Used to help debug a system.
*/
bool keep_temporary_files = false;
@@ -79,58 +79,54 @@ namespace rld
}
const std::string
- temporary_files::get (const std::string& suffix)
+ temporary_files::get (const std::string& suffix, bool keep)
{
char* temp = ::make_temp_file (suffix.c_str ());
if (!temp)
throw rld::error ("bad temp name", "temp-file");
- std::string name = temp;
-
- name = rld::find_replace (name,
- RLD_PATH_SEPARATOR_STR RLD_PATH_SEPARATOR_STR,
- RLD_PATH_SEPARATOR_STR);
-
- tempfiles.push_back (name);
-
+ const std::string name = rld::find_replace (temp,
+ RLD_PATH_SEPARATOR_STR RLD_PATH_SEPARATOR_STR,
+ RLD_PATH_SEPARATOR_STR);
+ tempfile_ref ref (name, keep);
+ tempfiles.push_back (ref);
return name;
}
void
- temporary_files::unlink (const std::string& name)
+ temporary_files::unlink (const tempfile_ref& ref)
{
- if (!keep_temporary_files)
+ if (!keep_temporary_files && !ref.keep)
+ rld::path::unlink (ref.name);
+ }
+
+ void
+ temporary_files::erase (const std::string& name)
+ {
+ for (tempfile_container::iterator tfi = tempfiles.begin ();
+ tfi != tempfiles.end ();
+ ++tfi)
{
- struct stat sb;
- if ((::stat (name.c_str (), &sb) >= 0) && S_ISREG (sb.st_mode))
+ if ((*tfi).name == name)
{
- int r;
-#if _WIN32
- r = ::remove(name.c_str ());
-#else
- r = ::unlink (name.c_str ());
-#endif
- if (r < 0)
- {
- std::cerr << "error: unlinking temp file: " << name << std::endl;
- ::exit (100);
- }
+ unlink (*tfi);
+ tempfiles.erase (tfi);
+ break;
}
}
}
void
- temporary_files::erase (const std::string& name)
+ temporary_files::keep (const std::string& name)
{
for (tempfile_container::iterator tfi = tempfiles.begin ();
tfi != tempfiles.end ();
++tfi)
{
- if (*tfi == name)
+ if ((*tfi).name == name)
{
- unlink (name);
- tempfiles.erase (tfi);
+ (*tfi).keep = true;
break;
}
}
@@ -147,12 +143,13 @@ namespace rld
}
}
- tempfile::tempfile (const std::string& suffix)
+ tempfile::tempfile (const std::string& suffix, bool _keep)
: suffix (suffix),
+ overridden (false),
fd (-1),
level (0)
{
- _name = temporaries.get (suffix);
+ _name = temporaries.get (suffix, _keep);
}
tempfile::~tempfile ()
@@ -164,10 +161,23 @@ namespace rld
void
tempfile::open (bool writable)
{
- if ((fd < 0) && rld::path::check_file (_name))
+ if (fd < 0)
{
+ bool ok = rld::path::check_file (_name);
+ int flags = writable ? O_RDWR : O_RDONLY;
+
+ if (overridden)
+ {
+ flags |= O_CREAT | O_TRUNC;
+ }
+ else
+ {
+ if (!ok)
+ throw rld::error ("Not found.", "tempfile open:" + _name);
+ }
+
level = 0;
- fd = ::open (_name.c_str (), writable ? O_RDWR : O_RDONLY);
+ fd = ::open (_name.c_str (), flags);
if (fd < 0)
throw rld::error (::strerror (errno), "tempfile open:" + _name);
}
@@ -184,6 +194,22 @@ namespace rld
}
}
+ void
+ tempfile::override (const std::string& name_)
+ {
+ if (fd >= 0)
+ throw rld::error ("Already open", "tempfile override");
+ rld::path::unlink (_name);
+ overridden = true;
+ _name = name_ + suffix;
+ }
+
+ void
+ tempfile::keep ()
+ {
+ temporaries.keep (_name);
+ }
+
const std::string&
tempfile::name () const
{
diff --git a/rld-process.h b/rld-process.h
index 30033a7..6c714f2 100644
--- a/rld-process.h
+++ b/rld-process.h
@@ -34,6 +34,20 @@ namespace rld
namespace process
{
/**
+ * Temporary file is a name and keep state.
+ */
+ struct tempfile_ref
+ {
+ const std::string name; //< The name of the tempfile.
+ bool keep; //< If true do not delete this file.
+
+ tempfile_ref (const std::string& name, bool keep = false)
+ : name (name),
+ keep (keep) {
+ }
+ };
+
+ /**
* Manage temporary files. We keep these so we can delete them when
* we exit.
*/
@@ -43,7 +57,7 @@ namespace rld
/**
* Container of temporary file names.
*/
- typedef std::list < std::string > tempfile_container;
+ typedef std::list < tempfile_ref > tempfile_container;
/**
* Construct the temporary files.
@@ -58,7 +72,8 @@ namespace rld
/**
* Get a new temporary file name.
*/
- const std::string get (const std::string& suffix = ".rldxx");
+ const std::string get (const std::string& suffix = ".rldxx",
+ bool keep = false);
/**
* Remove the temporary file.
@@ -66,6 +81,11 @@ namespace rld
void erase (const std::string& name);
/**
+ * Set the tempfile reference keep state to true.
+ */
+ void keep (const std::string& name);
+
+ /**
* Remove all temporary files.
*/
void clean_up ();
@@ -73,9 +93,9 @@ namespace rld
private:
/*
- * Delete the file.
+ * Delete the tempfile given the reference if not keeping.
*/
- void unlink (const std::string& name);
+ void unlink (const tempfile_ref& ref);
tempfile_container tempfiles; //< The temporary files.
@@ -89,9 +109,9 @@ namespace rld
public:
/**
- * Get a temporary file name.
+ * Get a temporary file name given a suffix.
*/
- tempfile (const std::string& suffix = ".rldxx");
+ tempfile (const std::string& suffix = ".rldxx", bool keep = false);
/**
* Clean up the temporary file.
@@ -109,6 +129,17 @@ namespace rld
void close ();
/**
+ * Override the temp file name automatically assigned with this name. The
+ * suffix is appended.
+ */
+ void override (const std::string& name);
+
+ /**
+ * Set the temp file keep state to true so it is not deleted.
+ */
+ void keep ();
+
+ /**
* The name of the temp file.
*/
const std::string& name () const;
@@ -157,11 +188,12 @@ namespace rld
private:
- std::string _name; //< The name of the file.
- const std::string suffix; //< The temp file's suffix.
- int fd; //< The file descriptor
- char buf[256]; //< The read buffer.
- int level; //< The level of data in the buffer.
+ std::string _name; //< The name of the file.
+ const std::string suffix; //< The temp file's suffix.
+ bool overridden; //< The name is overridden; may no exist.
+ int fd; //< The file descriptor
+ char buf[256]; //< The read buffer.
+ int level; //< The level of data in the buffer.
};
/**
diff --git a/rld.h b/rld.h
index 2c5fdd2..0a6cd9c 100644
--- a/rld.h
+++ b/rld.h
@@ -272,7 +272,7 @@ namespace rld
const std::string version ();
/**
- * The RTEMS version string.
+ * The RTEMS version string. @todo move to rld-rtems.
*/
const std::string rtems_version ();
diff --git a/rtems-tld.cpp b/rtems-tld.cpp
index 7a5ca65..41269da 100644
--- a/rtems-tld.cpp
+++ b/rtems-tld.cpp
@@ -727,8 +727,10 @@ namespace rld
rld::cc::make_cc_command (args);
rld::cc::append_flags (rld::cc::ft_cflags, args);
+ args.push_back ("-O2");
+ args.push_back ("-g");
args.push_back ("-c");
- args.push_back ("-o ");
+ args.push_back ("-o");
args.push_back (o.name ());
args.push_back (c.name ());
@@ -782,6 +784,7 @@ static struct option rld_opts[] = {
{ "rtems", required_argument, NULL, 'r' },
{ "rtems-bsp", required_argument, NULL, 'B' },
{ "config", required_argument, NULL, 'C' },
+ { "wrapper", required_argument, NULL, 'W' },
{ NULL, 0, NULL, 0 }
};
@@ -790,17 +793,18 @@ 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
- << " -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
- << " -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
+ << " -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;
::exit (exit_code);
}
@@ -851,11 +855,12 @@ main (int argc, char* argv[])
std::string ld_cmd;
std::string configuration;
std::string trace = "tracer";
+ std::string wrapper;
bool arch_bsp_load = false;
while (true)
{
- int opt = ::getopt_long (argc, argv, "hvwkVE:c:C:r:B:", rld_opts, NULL);
+ int opt = ::getopt_long (argc, argv, "hvwkVE:c:C:r:B:W:", rld_opts, NULL);
if (opt < 0)
break;
@@ -902,6 +907,10 @@ main (int argc, char* argv[])
configuration = optarg;
break;
+ case 'W':
+ wrapper = optarg;
+ break;
+
case '?':
usage (3);
break;
@@ -945,10 +954,19 @@ main (int argc, char* argv[])
*/
try
{
+ linker.load_config (configuration, trace);
+
rld::process::tempfile c (".c");
rld::process::tempfile o (".o");
- linker.load_config (configuration, trace);
+ if (!wrapper.empty ())
+ {
+ c.override (wrapper);
+ c.keep ();
+ o.override (wrapper);
+ o.keep ();
+ }
+
linker.generate_wrapper (c);
linker.compile_wrapper (c, o);