Index: linkers/rld-cc.cpp
===================================================================
--- linkers/rld-cc.cpp	(revision 2f48445837ea827663701a220ab7895ab13b1d30)
+++ linkers/rld-cc.cpp	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -34,4 +34,8 @@
     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;
@@ -88,4 +92,181 @@
       if (!ldflags.empty ())
         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);
+      }
     }
 
Index: linkers/rld-cc.h
===================================================================
--- linkers/rld-cc.h	(revision 2f48445837ea827663701a220ab7895ab13b1d30)
+++ linkers/rld-cc.h	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -35,4 +35,15 @@
   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.
@@ -43,4 +54,9 @@
     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.
@@ -74,4 +90,53 @@
 
     /**
+     * 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.
      */
Index: linkers/rld-path.cpp
===================================================================
--- linkers/rld-path.cpp	(revision 2f48445837ea827663701a220ab7895ab13b1d30)
+++ linkers/rld-path.cpp	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -19,12 +19,5 @@
 #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>
@@ -79,14 +72,25 @@
 
     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);
+      }
     }
 
Index: linkers/rld-path.h
===================================================================
--- linkers/rld-path.h	(revision 2f48445837ea827663701a220ab7895ab13b1d30)
+++ linkers/rld-path.h	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -78,12 +78,24 @@
 
     /**
-     * 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);
 
Index: linkers/rld-rtems.cpp
===================================================================
--- linkers/rld-rtems.cpp	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
+++ linkers/rld-rtems.cpp	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -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;
+      }
+    }
+  }
+}
Index: linkers/rld-rtems.h
===================================================================
--- linkers/rld-rtems.h	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
+++ linkers/rld-rtems.h	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -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
Index: linkers/rld.h
===================================================================
--- linkers/rld.h	(revision 2f48445837ea827663701a220ab7895ab13b1d30)
+++ linkers/rld.h	(revision 7ccb6701589449dd33cb1b41a7bfdf69ad5f0a26)
@@ -123,4 +123,12 @@
 
   /**
+   * 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.
    */
@@ -196,5 +204,5 @@
   inline strings& split (strings&           se,
                          const std::string& s,
-                         char               delimiter,
+                         char               delimiter = ' ',
                          bool               strip_quotes = true,
                          bool               strip_whitespace = true,
@@ -237,4 +245,14 @@
 
   /**
+   * 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.
    */
