source: rtems-tools/linkers/rld-gcc.cpp @ ec24a37

4.104.115
Last change on this file since ec24a37 was ec24a37, checked in by Chris Johns <chrisj@…>, on May 6, 2012 at 10:47:11 PM

Add to git.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2011, 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-gcc.h>
23#include <rld-process.h>
24
25namespace rld
26{
27  namespace gcc
28  {
29    std::string exec_prefix;
30    std::string march;
31    std::string mcpu;
32    std::string install_path;
33    std::string programs_path;
34    std::string libraries_path;
35
36    /**
37     * The list of standard libraries.
38     */
39    #define RPS RLD_PATHSTR_SEPARATOR_STR
40    static const char* std_lib_c         = "libgcc.a" RPS "libssp.a" RPS "libc.a";
41    static const char* std_lib_cplusplus = "libstdc++.a";
42
43    static void
44    make_cc_command (rld::process::arg_container& args)
45    {
46      std::string cmd = "gcc";
47      if (!exec_prefix.empty ())
48        cmd = exec_prefix + "-rtems" + rld::rtems_version () + '-' + cmd;
49      args.push_back (cmd);
50      if (!march.empty ())
51        args.push_back ("-march=" + march);
52      if (!mcpu.empty ())
53        args.push_back ("-mcpu=" + mcpu);
54    }
55
56    static bool
57    match_and_trim (const char* prefix, std::string& line, std::string& result)
58    {
59      std::string::size_type pos = ::strlen (prefix);
60      if (line.substr (0, pos) == prefix)
61      {
62        if (line[pos] == '=')
63          ++pos;
64        result = line.substr (pos, line.size () - pos - 1);
65        return true;
66      }
67      return false;
68    }
69
70    static void
71    search_dirs ()
72    {
73      rld::process::arg_container args;
74
75      make_cc_command (args);
76      args.push_back ("-print-search-dirs");
77     
78      rld::process::tempfile out;
79      rld::process::tempfile err;
80      rld::process::status   status;
81
82      status = rld::process::execute ("gcc", args, out.name (), err.name ());
83
84      if ((status.type == rld::process::status::normal) &&
85          (status.code == 0))
86      {
87        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
88          out.output ("gcc", std::cout, true);
89        out.open ();
90        while (true)
91        {
92          std::string line;
93          out.getline (line);
94          if (line.size () == 0)
95            break;
96          if (match_and_trim ("install: ", line, install_path))
97            continue;
98          if (match_and_trim ("programs: ", line, programs_path))
99            continue;
100          if (match_and_trim ("libraries: ", line, libraries_path))
101            continue;
102        }
103        out.close ();
104        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
105        {
106          std::cout << "gcc::install: " << install_path << std::endl
107                    << "gcc::programs: " << programs_path << std::endl
108                    << "gcc::libraries: " << libraries_path << std::endl;
109        }
110      }
111      else
112      {
113        err.output ("gcc", std::cout);
114      }
115    }
116
117    void
118    get_library_path (std::string& name, std::string& path)
119    {
120      rld::process::arg_container args;
121
122      make_cc_command (args);
123      args.push_back ("-print-file-name=" + name);
124     
125      rld::process::tempfile out;
126      rld::process::tempfile err;
127      rld::process::status   status;
128
129      status = rld::process::execute ("gcc", args, out.name (), err.name ());
130
131      if ((status.type == rld::process::status::normal) &&
132          (status.code == 0))
133      {
134        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
135          out.output ("gcc", std::cout, true);
136        out.open ();
137        out.get (path);
138        out.close ();
139        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
140          std::cout << "gcc::libpath: " << name << " -> " << path << std::endl;
141      }
142      else
143      {
144        err.output ("gcc", std::cout);
145      }
146    }
147
148    void
149    get_standard_libpaths (rld::files::paths& libpaths)
150    {
151      search_dirs ();
152      rld::split (libraries_path, libpaths, RLD_PATHSTR_SEPARATOR);
153    }
154
155    void
156    get_standard_libs (rld::files::paths& libs, 
157                       rld::files::paths& libpaths,
158                       bool               cplusplus)
159    {
160      strings libnames;
161
162      rld::split (std_lib_c, libnames, RLD_PATHSTR_SEPARATOR);
163      if (cplusplus)
164        rld::files::path_split (std_lib_cplusplus, libnames);
165
166      for (strings::iterator lni = libnames.begin ();
167           lni != libnames.end ();
168           ++lni)
169      {
170        if (rld::verbose () >= RLD_VERBOSE_INFO)
171          std::cout << "gcc::stdlib: " << *lni << std::endl;
172
173        std::string path;
174
175        rld::files::find_file (path, *lni, libpaths);
176        if (path.empty ())
177          throw rld::error ("Library not found: " + *lni, "getting standard libs");
178
179        libs.push_back (path);
180      }
181    }
182  }
183}
Note: See TracBrowser for help on using the repository browser.