📄 build.cxx
字号:
//####COPYRIGHTBEGIN####
//
// ----------------------------------------------------------------------------
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
//
// This program is part of the eCos host tools.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// ----------------------------------------------------------------------------
//
//####COPYRIGHTEND####
//==========================================================================
//
// build.cxx
//
// The implementation of build tree and makefile generation using
// CDL data
//
//==========================================================================
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jld
// Date: 1999-11-08
//
//####DESCRIPTIONEND####
//==========================================================================
#ifdef _WIN32
#include <windows.h> /* for GetShortPathNameA() */
#endif
#ifdef __CYGWIN__
#include <sys/cygwin.h> /* for cygwin_conv_to_posix_path() */
#endif
#ifdef __WXMSW__
// We take advantage of wxWindows' recursive wxFileName::Mkdir function
// to workaround a bug in Tcl on Windows 9x
#include "wx/filename.h"
# ifdef new
# undef new
# endif
#endif
#include "flags.hxx"
#include "build.hxx"
// Two methods of generating Cygwin filenames
// ECOS_USE_CYGDRIVE = 0: use e.g. //c/, but this is deprecated in new versions of Cygwin
// ECOS_USE_CYGDRIVE = 1: use e.g. /cygdrive/c/
// ECOS_USE_CYGDRIVE = 2: use e.g. c:/ notation
#define ECOS_USE_CYGDRIVE 1
// Use registry functions to find out location of /cygdrive
#define ECOS_USE_REGISTRY 1
// Don't use Reg... functions in command-line version until we know how
// to add advapi32.lib
#if defined(_WIN32) && !defined(__WXMSW__) && !defined(ECOS_CT)
#undef ECOS_USE_REGISTRY
#define ECOS_USE_REGISTRY 0
#endif
std::string makefile_header = "# eCos makefile\n\n# This is a generated file - do not edit\n\n";
bool eval_tcl_command (const std::string command) {
Tcl_Interp * interp = Tcl_CreateInterp ();
#ifdef _MSC_VER
Tcl_Channel outchan = Tcl_OpenFileChannel (interp, "nul", "a+", 777);
Tcl_SetStdChannel (outchan, TCL_STDOUT); // direct standard output to the null device
#endif
int nStatus = Tcl_Eval (interp, (char *) command.c_str ());
#ifdef _MSC_VER
Tcl_SetStdChannel (NULL, TCL_STDOUT);
Tcl_UnregisterChannel (interp, outchan);
#endif
Tcl_DeleteInterp (interp);
return (TCL_OK == nStatus);
}
// generate a copy of a string where each occurance of a specified char is replaced with another char
std::string replace_char (const std::string input, const char old_char, const char new_char) {
std::string output;
for (unsigned int n = 0; n < input.size (); n++) { // for each char
output += (old_char == input [n]) ? new_char : input [n]; // convert during copy
}
return output;
}
// convert a filepath into a vector of path components
static void path_to_vector (std::string input, std::vector <std::string> & output) {
std::string component;
output.clear ();
for (unsigned int n = 0; n < input.size (); n++) { // for each char in the path
if (('/' == input [n]) || ('\\' == input [n])) { // if char is a directory separator
output.push_back (component); // add path component to output vector
component.erase (); // clear path component string
} else { // char is not a separator
component += input [n]; // add char to path component string
}
}
output.push_back (component); // add final path component to output vector
}
// eliminate spaces from a DOS filepath by substituting the
// short form of path components containing spaces
#ifdef _WIN32
std::string nospace_path (const std::string input) {
// split the path into a vector of path components
std::vector <std::string> long_path_vector;
path_to_vector (input, long_path_vector);
// convert the path to its short form and split
// the result into a vector of path components
char buffer [MAX_PATH + 1];
GetShortPathNameA (input.c_str (), buffer, sizeof (buffer));
std::vector <std::string> short_path_vector;
path_to_vector (buffer, short_path_vector);
// append the short or long form of each path component to the output string as appropriate
std::string output;
for (unsigned int n = 0; n < long_path_vector.size (); n++) { // for each component of the path
if (long_path_vector [n].end () != std::find (long_path_vector [n].begin (), long_path_vector [n].end (), ' ')) { // if there is a space in the path component
output += short_path_vector [n]; // add the short form of the path component
} else { // there is no space in the path component
output += long_path_vector [n]; // add the long form of the path component
}
output += '\\'; // add a directory separator
}
output.resize (output.size () - 1); // remove the trailing separator
return output;
}
#endif
// convert a DOS filepath to a Cygwin filepath
std::string cygpath (const std::string input) {
#ifdef _WIN32
// remove spaces from the DOS filepath
const std::string path = nospace_path (input);
std::string output;
// convert the DOS filepath to Cygwin notation - using Cygwin if available
#ifdef __CYGWIN__
char buffer [MAX_PATH + 1];
cygwin_conv_to_posix_path (path.c_str (), buffer);
output = buffer;
#else
#if ECOS_USE_CYGDRIVE == 1
std::string strCygdrive("/cygdrive");
#if ECOS_USE_REGISTRY
HKEY hKey = 0;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Cygnus Solutions\\Cygwin\\mounts v2",
0, KEY_READ, &hKey))
{
DWORD type;
BYTE value[256];
DWORD sz;
if (ERROR_SUCCESS == RegQueryValueEx(hKey, "cygdrive prefix", NULL, & type, value, & sz))
{
strCygdrive = (const char*) value;
}
RegCloseKey(hKey);
}
#endif
strCygdrive = strCygdrive + "/";
for (unsigned int n = 0; n < path.size (); n++) { // for each char
if ((1 == n) && (':' == path [n])) { // if a DOS logical drive letter is present
output = strCygdrive + output; // convert to Cygwin notation
} else {
output += ('\\' == path [n]) ? '/' : path [n]; // convert backslash to slash
}
}
#elif ECOS_USE_CYGDRIVE == 2
// Convert to c:/foo/bar notation
for (unsigned int n = 0; n < path.size (); n++) { // for each char
output += ('\\' == path [n]) ? '/' : path [n]; // convert backslash to slash
}
#else
for (unsigned int n = 0; n < path.size (); n++) { // for each char
if ((1 == n) && (':' == path [n])) { // if a DOS logical drive letter is present
output = "//" + output; // convert to Cygwin notation
} else {
output += ('\\' == path [n]) ? '/' : path [n]; // convert backslash to slash
}
}
#endif
// ECOS_USE_CYGDRIVE
#endif
return output;
#else
return input;
#endif
}
// create a directory
bool create_directory (const std::string directory) {
// We take advantage of wxWindows' recursive wxFileName::Mkdir function
// to workaround a bug in Tcl on Windows 9x
#if defined(__WXMSW__)
if (wxDirExists(directory.c_str()))
return TRUE;
return wxFileName::Mkdir(directory.c_str(), 0777, TRUE);
#else
return eval_tcl_command ("file mkdir \"" + directory + "\"");
#endif
}
// copy a file
bool copy_file (const std::string file, const std::string destination) {
return eval_tcl_command ("file copy \"" + file + "\" \"" + destination + "\"");
return true;
}
// returns the directory of the specified file
std::string file_to_directory (const std::string file) {
for (unsigned int n = file.size (); n >= 0; n--) {
if ('/' == file [n]) {
std::string directory = file;
directory.resize (n);
return directory;
}
}
return "";
}
std::string tab_indent (const std::string input) {
std::string output;
bool indent = true;
for (unsigned int n = 0; n < input.size (); n++) {
if (indent) {
output += '\t';
indent = false;
} else {
indent = ('\n' == input [n]);
}
output += input [n];
}
return output;
}
// return the tests of the specified loadable
std::string get_tests (const CdlConfiguration config, const CdlBuildInfo_Loadable & build_info) {
CdlValuable tests = dynamic_cast <CdlValuable> (config->lookup (build_info.name + "_TESTS"));
if (tests) { // if there are tests
return tests->get_value ();
} else { // there are no tests
return "";
}
}
// replaces all occurances of a substring with a new substring
std::string replace_substr (const std::string input, const std::string old_substring, const std::string new_substring) {
std::string output = input;
std::string::size_type index = 0;
while (index = output.find (old_substring, index), std::string::npos != index) {
output.replace (index, old_substring.size (), new_substring);
}
return output;
}
// resolve tokens in custom make rule targets and dependencies
std::string resolve_tokens (const std::string input) {
std::string output = input;
output = replace_substr (output, "<PREFIX>", "$(PREFIX)");
output = replace_substr (output, "<PACKAGE>", "$(REPOSITORY)/$(PACKAGE)");
return output;
}
// create the makefile for a loadable
bool generate_makefile (const CdlConfiguration config, const CdlBuildInfo_Loadable & info, const std::string install_tree, const std::string filename) {
unsigned int count;
unsigned int library;
// obtain the command prefix
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -