summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-09-05 18:16:40 +1000
committerChris Johns <chrisj@rtems.org>2014-09-05 18:16:40 +1000
commit5679661069a8b9acaec26d61c8da797f0726506b (patch)
treeb3a8af2246ebbdfdd988a41a7c9658b374d0f165
parent566f389fb9f7f2b124e6055947c9edc8820107b6 (diff)
Add support for RTEMS BSP or user supplied CFLAGS. Remove march/mcpu.
Added support to read an RTEMS BSP pkgconfig file and ste the CC flags.
-rw-r--r--rld-cc.cpp181
-rw-r--r--rld-cc.h65
-rw-r--r--rld-path.cpp34
-rw-r--r--rld-path.h22
-rw-r--r--rld-rtems.cpp146
-rw-r--r--rld-rtems.h82
-rw-r--r--rld.h20
7 files changed, 529 insertions, 21 deletions
diff --git a/rld-cc.cpp b/rld-cc.cpp
index 56dc6ad..f69b7c9 100644
--- a/rld-cc.cpp
+++ b/rld-cc.cpp
@@ -33,6 +33,10 @@ namespace rld
std::string cflags;
std::string cxxflags;
std::string ldflags;
+ std::string warning_cflags;
+ std::string include_cflags;
+ std::string machine_cflags;
+ std::string spec_cflags;
std::string install_path;
std::string programs_path;
std::string libraries_path;
@@ -89,6 +93,183 @@ namespace rld
args.push_back (ldflags);
}
+ const std::string
+ strip_cflags (const std::string& flags)
+ {
+ std::string oflags;
+ rld::strings flags_;
+ rld::split (flags_, flags);
+
+ for (rld::strings::iterator si = flags_.begin ();
+ si != flags_.end ();
+ ++si)
+ {
+ if (!rld::starts_with ((*si), "-O") && !rld::starts_with ((*si), "-g"))
+ oflags += ' ' + *si;
+ }
+
+ return rld::trim (oflags);
+ }
+
+ const std::string
+ filter_flags (const std::string& flags,
+ const std::string& ,
+ const std::string& ,
+ flag_type type,
+ std::string& warnings,
+ std::string& includes,
+ std::string& machines,
+ std::string& specs)
+ {
+ /*
+ * Defintion of flags to be filtered.
+ */
+ enum flag_group
+ {
+ fg_warning,
+ fg_include,
+ fg_machine,
+ fg_specs
+ };
+ struct flag_def
+ {
+ flag_group group; ///< The group this flag belong to.
+ const char* opt; ///< Option start.
+ int count; ///< Number of arguments with the option.
+ bool path; ///< Is this a path ?
+ int out; ///< If the flag type is set drop the opt..
+ };
+ const flag_def flag_defs[] =
+ {
+ { fg_warning, "-W", 1, false, ft_cppflags | ft_cflags | ft_ldflags },
+ { fg_include, "-I", 2, true, 0 },
+ { fg_include, "-isystem", 2, true, 0 },
+ { fg_include, "-sysroot", 2, true, 0 },
+ { fg_machine, "-O", 1, false, 0 },
+ { fg_machine, "-m", 1, false, 0 },
+ { fg_machine, "-f", 1, false, 0 },
+ { fg_specs, "-q", 1, false, 0 },
+ { fg_specs, "-B", 2, true, 0 },
+ { fg_specs, "--specs", 2, false, 0 }
+ };
+ const int flag_def_size = sizeof (flag_defs) / sizeof (flag_def);
+
+ std::string oflags;
+ rld::strings flags_;
+
+ rld::split (flags_, strip_cflags (flags));
+
+ warnings.clear ();
+ includes.clear ();
+ machines.clear ();
+ specs.clear ();
+
+ for (rld::strings::iterator si = flags_.begin ();
+ si != flags_.end ();
+ ++si)
+ {
+ std::string opts;
+ std::string& opt = *(si);
+ bool in = true;
+
+ for (int fd = 0; fd < flag_def_size; ++fd)
+ {
+ if (rld::starts_with (opt, flag_defs[fd].opt))
+ {
+ int opt_count = flag_defs[fd].count;
+ if (opt_count > 1)
+ {
+ /*
+ * See if the flag is just the option. If is not take one less
+ * because the option's argument is joined to the option.
+ */
+ if (opt != flag_defs[fd].opt)
+ {
+ opt_count -= 1;
+ /*
+ * @todo Path processing here. Not sure what it is needed for.
+ */
+ }
+ }
+ opts += ' ' + opt;
+ while (opt_count > 1)
+ {
+ ++si;
+ /*
+ * @todo Path processing here. Not sure what it is needed for.
+ */
+ opts += ' ' + (*si);
+ --opt_count;
+ }
+ switch (flag_defs[fd].group)
+ {
+ case fg_warning:
+ warnings += ' ' + opts;
+ break;
+ case fg_include:
+ includes += ' ' + opts;
+ break;
+ case fg_machine:
+ machines += ' ' + opts;
+ break;
+ case fg_specs:
+ specs += ' ' + opts;
+ break;
+ default:
+ throw rld::error ("Invalid group", "flag group");
+ }
+ if ((flag_defs[fd].out & type) != 0)
+ in = false;
+ break;
+ }
+ }
+
+ if (in)
+ oflags += ' ' + opts;
+ }
+
+ rld::trim (warnings);
+ rld::trim (includes);
+ rld::trim (machines);
+ rld::trim (specs);
+
+ return rld::trim (oflags);
+ }
+
+ const std::string
+ filter_flags (const std::string& flags,
+ const std::string& arch,
+ const std::string& path,
+ flag_type type)
+ {
+ if (type != ft_cflags)
+ {
+ std::string warnings;
+ std::string includes;
+ std::string machines;
+ std::string specs;
+ return filter_flags (flags,
+ arch,
+ path,
+ type,
+ warnings,
+ includes,
+ machines,
+ specs);
+ }
+ else
+ {
+ return filter_flags (flags,
+ arch,
+ path,
+ type,
+ warning_cflags,
+ include_cflags,
+ machine_cflags,
+ spec_cflags);
+ }
+ }
+
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 db1163e..f5365c4 100644
--- a/rld-cc.h
+++ b/rld-cc.h
@@ -34,6 +34,17 @@ namespace rld
{
namespace cc
{
+ /*
+ * Defintion of flags to be filtered.
+ */
+ enum flag_type
+ {
+ ft_cppflags = 1 << 0,
+ ft_cflags = 1 << 1,
+ ft_cxxflags = 1 << 2,
+ ft_ldflags = 1 << 3
+ };
+
extern std::string cc; //< The CC executable as absolute path.
extern std::string cc_name; //< The CC name, ie gcc, clang.
extern std::string exec_prefix; //< The CC executable prefix.
@@ -43,6 +54,11 @@ namespace rld
extern std::string cxxflags; //< The CXX flags.
extern std::string ldflags; //< The LD flags.
+ extern std::string warning_cflags; //< The warning flags in cflags.
+ extern std::string include_cflags; //< The include flags in cflags.
+ extern std::string machine_cflags; //< The machine flags in cflags.
+ extern std::string spec_cflags; //< The spec flags in cflags.
+
extern std::string install_path; //< The CC reported install path.
extern std::string programs_path; //< The CC reported programs path.
extern std::string libraries_path; //< The CC reported libraries path.
@@ -73,6 +89,55 @@ namespace rld
void add_ldflags (rld::process::arg_container& args);
/**
+ * Strip the flags of -O and -g options.
+ *
+ * @param flags The flags a space delimited list to strip.
+ * @return const std::string The stripped flags.
+ */
+ const std::string strip_cflags (const std::string& flags);
+
+ /**
+ * Filter the flags. Provide the type of flags being passed, the flags as a
+ * space separated list, the architure, and a path. Provide strings
+ * containers for the different flag groups so they can be sorted and
+ * returned.
+ *
+ * @param flags The flags a space delimited list to strip.
+ * @param arch The architecure per the OS specific name.
+ * @param path A path to adjust based on the architecture.
+ * @param type The type of flags being passed.
+ * @param warnings Return warning flags in this string.
+ * @param includes Return include flags in this string.
+ * @param machines Return machine flags in this string.
+ * @param specs Return spec flags in this string.
+ * @return const std::string The filtered flags.
+ */
+ const std::string filter_flags (const std::string& flags,
+ const std::string& arch,
+ const std::string& path,
+ flag_type type,
+ std::string& warnings,
+ std::string& includes,
+ std::string& machines,
+ std::string& specs);
+
+ /**
+ * Filter the cflags and update the warnings, includes, machines and specs
+ * if the type of flags is cflags. Provide the cflags as a space separated
+ * list, the architure, and a path.
+ *
+ * @param flags The flags a space delimited list to strip.
+ * @param arch The architecure per the OS specific name.
+ * @param path A path to adjust based on the architecture.
+ * @param type The type of flags being passed.
+ * @return const std::string The filtered flags.
+ */
+ const std::string filter_flags (const std::string& flags,
+ const std::string& arch,
+ const std::string& path,
+ flag_type type);
+
+ /**
* Get the standard libraries paths from the compiler.
*/
void get_standard_libpaths (rld::path::paths& libpaths);
diff --git a/rld-path.cpp b/rld-path.cpp
index 50eb992..51288ce 100644
--- a/rld-path.cpp
+++ b/rld-path.cpp
@@ -18,14 +18,7 @@
#include "config.h"
#endif
-#include <algorithm>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
#include <sys/stat.h>
-#include <unistd.h>
#include <rld.h>
@@ -78,16 +71,27 @@ namespace rld
}
void
- path_join (const std::string& path_, const std::string& file_, std::string& joined)
+ path_join (const std::string& base, const std::string& part, std::string& joined)
{
- if ((path_[path_.size () - 1] != RLD_PATH_SEPARATOR) &&
- (file_[0] != RLD_PATH_SEPARATOR))
- joined = path_ + RLD_PATH_SEPARATOR + file_;
- else if ((path_[path_.size () - 1] == RLD_PATH_SEPARATOR) &&
- (file_[0] == RLD_PATH_SEPARATOR))
- joined = path_ + &file_[1];
+ if ((base[base.size () - 1] != RLD_PATH_SEPARATOR) &&
+ (part[0] != RLD_PATH_SEPARATOR))
+ joined = base + RLD_PATH_SEPARATOR + part;
+ else if ((base[base.size () - 1] == RLD_PATH_SEPARATOR) &&
+ (part[0] == RLD_PATH_SEPARATOR))
+ joined = base + &part[1];
else
- joined = path_ + file_;
+ joined = base + part;
+ }
+
+ void path_join (const std::string& base, const paths& parts, std::string& joined)
+ {
+ joined = base;
+ for (paths::const_iterator pi = parts.begin ();
+ pi != parts.end ();
+ ++pi)
+ {
+ path_join (joined, *pi, joined);
+ }
}
bool
diff --git a/rld-path.h b/rld-path.h
index d9bb991..f501fb4 100644
--- a/rld-path.h
+++ b/rld-path.h
@@ -77,14 +77,26 @@ namespace rld
paths& paths);
/**
- * Make a path by joining the parts with required separator.
+ * Make a path by joining the base and part with required separator.
*
- * @param path_ The path component to be joined.
- * @param file_ The file name to add to the path.
+ * @param base The path component to be joined.
+ * @param part The file name to add to the path.
* @param joined The joined path and file name with a path separator.
*/
- void path_join (const std::string& path_,
- const std::string& file_,
+ void path_join (const std::string& base,
+ const std::string& part,
+ std::string& joined);
+
+ /**
+ * Make a path by joining the parts with the base and the required
+ * separator.
+ *
+ * @param base The path component to be joined.
+ * @param parts The files to add to the path.
+ * @param joined The joined path and file name with a path separator.
+ */
+ void path_join (const std::string& base,
+ const paths& parts,
std::string& joined);
/**
diff --git a/rld-rtems.cpp b/rld-rtems.cpp
new file mode 100644
index 0000000..b332aa4
--- /dev/null
+++ b/rld-rtems.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2011-2014, Chris Johns <chrisj@rtems.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <rld.h>
+#include <rld-cc.h>
+
+#include <pkgconfig.h>
+
+namespace rld
+{
+ namespace rtems
+ {
+ std::string version = "4.11";
+ std::string path;
+ bool installed;
+ std::string arch_bsp;
+
+ const std::string
+ arch (const std::string& ab)
+ {
+ std::string::size_type slash = ab.find_first_of ('/');
+ if (slash == std::string::npos)
+ throw rld::error ("Invalid BSP name", ab);
+ return ab.substr (0, slash);
+ std::string bsp = ab.substr (slash + 1);
+ }
+
+ const std::string
+ bsp (const std::string& ab)
+ {
+ std::string::size_type slash = ab.find_first_of ('/');
+ if (slash == std::string::npos)
+ throw rld::error ("Invalid BSP name", ab);
+ return ab.substr (slash + 1);
+ }
+
+ const std::string
+ rtems_bsp (const std::string& ab)
+ {
+ const std::string a = arch (ab);
+ const std::string b = bsp (ab);
+ return a + "-rtems" + version + '-' + b;
+ }
+
+ void
+ load_cc ()
+ {
+ path::paths parts;
+ std::string rtems_pkgconfig;
+ std::string bsp;
+
+ if (path.empty ())
+ throw rld::error ("Not set; see -r", "RTEMS path");
+
+ bsp = rtems_bsp (arch_bsp);
+
+ parts.push_back ("lib");
+ parts.push_back ("pkgconfig");
+
+ rld::path::path_join (path, parts, rtems_pkgconfig);
+
+ if (!path::check_directory (rtems_pkgconfig))
+ throw rld::error ("Invalid RTEMS path", path);
+
+ rld::path::path_join (rtems_pkgconfig, bsp + ".pc", rtems_pkgconfig);
+
+ if (!path::check_file (rtems_pkgconfig))
+ throw rld::error ("RTEMS BSP not found", arch_bsp);
+
+ if (rld::verbose () >= RLD_VERBOSE_INFO)
+ std::cout << " rtems: " << arch_bsp << ": "
+ << rtems_pkgconfig << std::endl;
+
+ pkgconfig::package pkg (rtems_pkgconfig);
+
+ std::string flags;
+
+ if (pkg.get ("CPPFLAGS", flags))
+ {
+ rld::cc::cppflags = rld::cc::filter_flags (flags,
+ arch_bsp,
+ path,
+ rld::cc::ft_cppflags);
+ if (rld::verbose () >= RLD_VERBOSE_INFO)
+ std::cout << " rtems: " << arch_bsp
+ << ": CPPFLAGS=" << rld::cc::cppflags << std::endl;
+ }
+
+ if (pkg.get ("CFLAGS", flags))
+ {
+ rld::cc::cflags = rld::cc::filter_flags (flags,
+ arch_bsp,
+ path,
+ rld::cc::ft_cflags);
+ if (rld::verbose () >= RLD_VERBOSE_INFO)
+ {
+ std::cout << " rtems: " << arch_bsp
+ << ": CFLAGS=" << rld::cc::cflags << std::endl;
+ std::cout << " rtems: " << arch_bsp
+ << ": WARNINGS=" << rld::cc::warning_cflags << std::endl;
+ std::cout << " rtems: " << arch_bsp
+ << ": INCLUDES=" << rld::cc::include_cflags << std::endl;
+ std::cout << " rtems: " << arch_bsp
+ << ": MACHINES=" << rld::cc::machine_cflags << std::endl;
+ std::cout << " rtems: " << arch_bsp
+ << ": SPECS=" << rld::cc::spec_cflags << std::endl;
+ }
+ }
+
+ if (pkg.get ("CXXFLAGS", flags))
+ {
+ rld::cc::cxxflags = rld::cc::filter_flags (flags,
+ arch_bsp,
+ path,
+ rld::cc::ft_cxxflags);
+ if (rld::verbose () >= RLD_VERBOSE_INFO)
+ std::cout << " rtems: " << arch_bsp
+ << ": CXXFLAGS=" << rld::cc::cxxflags << std::endl;
+ }
+
+ if (pkg.get ("LDFLAGS", flags))
+ {
+ rld::cc::ldflags = rld::cc::filter_flags (flags,
+ arch_bsp,
+ path,
+ rld::cc::ft_ldflags);
+ if (rld::verbose () >= RLD_VERBOSE_INFO)
+ std::cout << " rtems: " << arch_bsp
+ << ": LDFLAGS=" << rld::cc::ldflags << std::endl;
+ }
+ }
+ }
+}
diff --git a/rld-rtems.h b/rld-rtems.h
new file mode 100644
index 0000000..97dc67e
--- /dev/null
+++ b/rld-rtems.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011-2014, Chris Johns <chrisj@rtems.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems-ld
+ *
+ * @brief Support to manage RTEMS.
+ *
+ */
+
+#if !defined (_RLD_RTEMS_H_)
+#define _RLD_RTEMS_H_
+
+#include <string>
+
+namespace rld
+{
+ namespace rtems
+ {
+ /**
+ * The RTEMS default version.
+ */
+ extern std::string version;
+
+ /**
+ * The path to RTEMS.
+ */
+ extern std::string path;
+
+ /**
+ * Is the RTEMS installed.
+ */
+ extern bool installed;
+
+ /**
+ * The BSP name.
+ */
+ extern std::string arch_bsp;
+
+ /**
+ * Return the architecture given an arch/bsp string.
+ */
+ const std::string arch (const std::string& ab);
+
+ /**
+ * Return the bsp given an arch/bsp string.
+ */
+ const std::string bsp (const std::string& ab);
+
+ /**
+ * Return the RTEMS bsp string given an arch/bsp string.
+ */
+ const std::string rtems_bsp (const std::string& ab);
+
+ /**
+ * Load the configuration. Set the various values via the command or a
+ * configuration file then check the configuration.
+ */
+ void load_cc ();
+
+ /**
+ * Process the BSP name updating the various CC flags.
+ */
+ void set_cc (void);
+ }
+}
+
+#endif
diff --git a/rld.h b/rld.h
index 1f5e60b..efe3f46 100644
--- a/rld.h
+++ b/rld.h
@@ -122,6 +122,14 @@ namespace rld
typedef std::vector < std::string > strings;
/**
+ * 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;
+ }
+
+ /**
* Trim from start.
*/
inline std::string& ltrim (std::string &s)
@@ -195,7 +203,7 @@ namespace rld
*/
inline strings& split (strings& se,
const std::string& s,
- char delimiter,
+ char delimiter = ' ',
bool strip_quotes = true,
bool strip_whitespace = true,
bool empty = false)
@@ -236,6 +244,16 @@ namespace rld
}
/**
+ * 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;
+ }
+
+ /**
* Increment the verbose level.
*/
void verbose_inc ();