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

4.104.115
Last change on this file since a136346 was a136346, checked in by Chris Johns <chrisj@…>, on Aug 5, 2014 at 1:01:15 PM

Fix temporary file handling and add tempfile write support.

Move the static objects into the rld-process file and change the
clean up to a call.

Add support to write to tempfiles.

  • 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.read_line (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.read (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.