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

4.104.115
Last change on this file since 40fd7a0 was 40fd7a0, checked in by Chris Johns <chrisj@…>, on 09/01/14 at 03:26:47

rld: Split the file into a path module for path specific functions.

This allows resued for other parts of the system not dependent on
objcet files or archives.

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