source: rtems-tools/linkers/rld-cc.cpp @ 7461924

4.104.115
Last change on this file since 7461924 was 7461924, checked in by Chris Johns <chrisj@…>, on Sep 17, 2012 at 12:13:55 AM

Rename rld-gcc. Add -C option.

Add a -C (also --cc) option to allow the CC to be used when linking to be
provided by the user rather than using the path. This support allows user
who work with the full path to tools rather than the environment to make
use of the linker without them needing to play with environment table.

Rename rld-gcc.[h.cpp] to rld-cc.[h,cpp] because gcc may not be the
only compiler/linker used by the RTEMS project.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2011-2012, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <string.h>
18
19#include <fstream>
20
21#include <rld.h>
22#include <rld-cc.h>
23#include <rld-process.h>
24
25namespace rld
26{
27  namespace cc
28  {
29    std::string cc;
30    std::string exec_prefix;
31    std::string march;
32    std::string mcpu;
33    std::string install_path;
34    std::string programs_path;
35    std::string libraries_path;
36
37    /**
38     * The list of standard libraries.
39     */
40    #define RPS RLD_PATHSTR_SEPARATOR_STR
41    static const char* std_lib_c         = "libgcc.a" RPS "libssp.a" RPS "libc.a";
42    static const char* std_lib_cplusplus = "libstdc++.a";
43
44    static void
45    make_cc_command (rld::process::arg_container& args)
46    {
47      /*
48       * Use the absolute path to CC is provided.
49       */
50      if (!cc.empty ())
51        args.push_back (cc);
52      else
53      {
54        std::string cmd = "gcc";
55        if (!exec_prefix.empty ())
56          cmd = exec_prefix + "-rtems" + rld::rtems_version () + '-' + cmd;
57        args.push_back (cmd);
58      }
59      if (!march.empty ())
60        args.push_back ("-march=" + march);
61      if (!mcpu.empty ())
62        args.push_back ("-mcpu=" + mcpu);
63    }
64
65    static bool
66    match_and_trim (const char* prefix, std::string& line, std::string& result)
67    {
68      std::string::size_type pos = ::strlen (prefix);
69      if (line.substr (0, pos) == prefix)
70      {
71        if (line[pos] == '=')
72          ++pos;
73        result = line.substr (pos, line.size () - pos - 1);
74        return true;
75      }
76      return false;
77    }
78
79    static void
80    search_dirs ()
81    {
82      rld::process::arg_container args;
83
84      make_cc_command (args);
85      args.push_back ("-print-search-dirs");
86
87      rld::process::tempfile out;
88      rld::process::tempfile err;
89      rld::process::status   status;
90
91      status = rld::process::execute ("gcc", args, out.name (), err.name ());
92
93      if ((status.type == rld::process::status::normal) &&
94          (status.code == 0))
95      {
96        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
97          out.output ("gcc", std::cout, true);
98        out.open ();
99        while (true)
100        {
101          std::string line;
102          out.getline (line);
103          if (line.size () == 0)
104            break;
105          if (match_and_trim ("install: ", line, install_path))
106            continue;
107          if (match_and_trim ("programs: ", line, programs_path))
108            continue;
109          if (match_and_trim ("libraries: ", line, libraries_path))
110            continue;
111        }
112        out.close ();
113        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
114        {
115          std::cout << "cc::install: " << install_path << std::endl
116                    << "cc::programs: " << programs_path << std::endl
117                    << "cc::libraries: " << libraries_path << std::endl;
118        }
119      }
120      else
121      {
122        err.output ("gcc", std::cout);
123      }
124    }
125
126    void
127    get_library_path (std::string& name, std::string& path)
128    {
129      rld::process::arg_container args;
130
131      make_cc_command (args);
132      args.push_back ("-print-file-name=" + name);
133
134      rld::process::tempfile out;
135      rld::process::tempfile err;
136      rld::process::status   status;
137
138      status = rld::process::execute ("gcc", args, out.name (), err.name ());
139
140      if ((status.type == rld::process::status::normal) &&
141          (status.code == 0))
142      {
143        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
144          out.output ("cc", std::cout, true);
145        out.open ();
146        out.get (path);
147        out.close ();
148        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
149          std::cout << "cc::libpath: " << name << " -> " << path << std::endl;
150      }
151      else
152      {
153        err.output ("cc", std::cout);
154      }
155    }
156
157    void
158    get_standard_libpaths (rld::files::paths& libpaths)
159    {
160      search_dirs ();
161      rld::split (libraries_path, libpaths, RLD_PATHSTR_SEPARATOR);
162    }
163
164    void
165    get_standard_libs (rld::files::paths& libs,
166                       rld::files::paths& libpaths,
167                       bool               cplusplus)
168    {
169      strings libnames;
170
171      rld::split (std_lib_c, libnames, RLD_PATHSTR_SEPARATOR);
172      if (cplusplus)
173        rld::files::path_split (std_lib_cplusplus, libnames);
174
175      for (strings::iterator lni = libnames.begin ();
176           lni != libnames.end ();
177           ++lni)
178      {
179        if (rld::verbose () >= RLD_VERBOSE_INFO)
180          std::cout << "cc::stdlib: " << *lni << std::endl;
181
182        std::string path;
183
184        rld::files::find_file (path, *lni, libpaths);
185        if (path.empty ())
186          throw rld::error ("Library not found: " + *lni, "getting standard libs");
187
188        libs.push_back (path);
189      }
190    }
191  }
192}
Note: See TracBrowser for help on using the repository browser.