📄 build.cxx
字号:
cdlbuildloadablebody_cookie = CdlBuildLoadableBody_Invalid; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------std::stringCdlBuildLoadableBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlBuildLoadable::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "build_loadable";}// ----------------------------------------------------------------------------boolCdlBuildLoadableBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlBuildLoadableBody_Magic != cdlbuildloadablebody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); return CdlContainerBody::check_this(zeal) && CdlNodeBody::check_this(zeal);}//}}}//{{{ Property parsers // ----------------------------------------------------------------------------voidCdlBuildLoadableBody::add_property_parsers(std::vector<CdlInterpreterCommandEntry>& parsers){ CYG_REPORT_FUNCNAME("CdlBuildLoadable::add_property_parsers"); static CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("library", &CdlBuildLoadableBody::parse_library ), CdlInterpreterCommandEntry("makefile", &CdlBuildLoadableBody::parse_makefile ), CdlInterpreterCommandEntry("include_dir", &CdlBuildLoadableBody::parse_include_dir ), CdlInterpreterCommandEntry("include_files", &CdlBuildLoadableBody::parse_include_files ), CdlInterpreterCommandEntry("", 0 ) }; for (int i = 0; commands[i].command != 0; i++) { std::vector<CdlInterpreterCommandEntry>::const_iterator j; for (j = parsers.begin(); j != parsers.end(); j++) { if (commands[i].name == j->name) { if (commands[i].command != j->command) { CYG_FAIL("Property names are being re-used"); } break; } } if (j == parsers.end()) { parsers.push_back(commands[i]); } } CYG_REPORT_RETURN();}voidCdlBuildLoadableBody::check_properties(CdlInterpreter interp){ CYG_REPORT_FUNCNAME("CdlBuildLoadable::check_properties"); CYG_REPORT_FUNCARG2XV(this, interp); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); CdlNodeBody::check_properties(interp); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// syntax: library <filename>//// NOTE: there should probably be a check that the library name is in// a valid format, i.e. libxxx.aintCdlBuildLoadableBody::parse_library(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_library", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_Library, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// syntax: makefile <filename>//// NOTE: possibly there should be a check that the makefile exists.// Do we want to allow build_proc's to generate makefiles?intCdlBuildLoadableBody::parse_makefile(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_makefile", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_Makefile, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// syntax: include_dir <directory name>intCdlBuildLoadableBody::parse_include_dir(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_include_dir", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_IncludeDir, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// Syntax: include_files <file1 file2 ...>//// This lists the header files that should be copied into the install tree// as part of the build operation. In the absence of an include_files property// there should be an include subdirectory, and all files in that subdirectory// are assumed to be exportable headers.//// NOTE: add a finalizer to check that the files exist or get created.intCdlBuildLoadableBody::parse_include_files(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_include_files", "result %d"); int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_IncludeFiles, 0, 0, true); CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ update_build_info() // ----------------------------------------------------------------------------// This utility routine takes care of filling in a Buildinfo_Loadable// structure with the appropriate header file information. This involves// the following://// 1) there may be an include_dir property. This affects the destination// of any header files that are listed.//// 2) the loadable may or may not have an include subdirectory. For// non-trivial packages the include subdirectory provides a clean// way of separating interface and implementation. For simple// packages it is too heavyweight.//// 3) there may be one or more include_files property. If so then these// specify all the files that should be exported.//// 4) otherwise if there is an include subdirectory then we need to// know all the header files in that subdirectory. A Tcl script is// used for this.//// 5) otherwise all the header files below the package directory itself// are of interest.static voidupdate_header_file_info(CdlConstBuildLoadable loadable, CdlBuildInfo_Loadable& build_info){ CYG_REPORT_FUNCNAME("update_header_file_info"); CYG_REPORT_FUNCARG2XV(loadable, &build_info); CYG_PRECONDITION_CLASSC(loadable); std::string dest_dir = ""; CdlProperty include_dir_prop = loadable->get_property(CdlPropertyId_IncludeDir); if (0 != include_dir_prop) { CdlProperty_String strprop = dynamic_cast<CdlProperty_String>(include_dir_prop); CYG_ASSERT_CLASSC(strprop); dest_dir = strprop->get_string(); } bool has_include_subdir = loadable->has_subdirectory("include"); std::vector<CdlProperty> include_file_properties; loadable->get_properties(CdlPropertyId_IncludeFiles, include_file_properties); if (include_file_properties.size() > 0) { std::vector<CdlProperty>::const_iterator prop_i; for (prop_i = include_file_properties.begin(); prop_i != include_file_properties.end(); prop_i++) { CdlProperty_StringVector strvprop = dynamic_cast<CdlProperty_StringVector>(*prop_i); CYG_ASSERT_CLASSC(strvprop); const std::vector<std::string>& filenames = strvprop->get_strings(); std::vector<std::string>::const_iterator file_i; for (file_i = filenames.begin(); file_i != filenames.end(); file_i++) { std::string path = loadable->find_relative_file(*file_i, "include"); // Assume that the header file will be generated by a build_proc if ("" == path) { if (has_include_subdir) { path = "include/" + *file_i; } else { path = *file_i; } } CdlBuildInfo_Header local_copy; local_copy.source = path; local_copy.destination = ""; if ("" != dest_dir) { local_copy.destination = dest_dir + "/"; } // At this stage "path" may begin with "include/", which should not // be present in the destination. const char* tmp = path.c_str(); if (0 == strncmp("include/", tmp, 8)) { local_copy.destination += &(tmp[8]); } else { local_copy.destination += path; } build_info.headers.push_back(local_copy); } } CYG_REPORT_RETURN(); return; } // It is necessary to search for the appropriate files. CdlInterpreter interp = loadable->get_interpreter(); std::string path = loadable->get_toplevel()->get_directory() + "/" + loadable->get_directory(); if (has_include_subdir) { std::vector<std::string> files; std::vector<std::string>::const_iterator file_i; interp->locate_all_files(path + "/include", files); for (file_i = files.begin(); file_i != files.end(); file_i++) { // NOTE: for now discard any header files in the pkgconf subdirectory if (0 == strncmp("pkgconf/", file_i->c_str(), 8)) { continue; } CdlBuildInfo_Header local_copy; local_copy.source = "include/" + *file_i; local_copy.destination = ""; if ("" != dest_dir) { local_copy.destination = dest_dir + "/"; } local_copy.destination += *file_i; build_info.headers.push_back(local_copy); } } else { // Look for all header files, which for now means files with // a .h, .hxx, .inl or .inc extension. // FIXME: the definition of what constitutes a header file // should not be hard-wired here. std::vector<std::string> files; std::vector<std::string>::const_iterator file_i; interp->locate_all_files(path, files); for (file_i = files.begin(); file_i != files.end(); file_i++) { // Problems with libstdc++ versions, use C comparisons instead. const char* c_string = file_i->c_str(); unsigned int len = strlen(c_string); if (((len >= 2) && (0 == strncmp(c_string + len - 2, ".h", 2))) || ((len >= 4) && (0 == strncmp(c_string + len - 4, ".hxx", 4))) || ((len >= 4) && (0 == strncmp(c_string + len - 4, ".inl", 4))) || ((len >= 4) && (0 == strncmp(c_string + len - 4, ".inc", 4)))) { CdlBuildInfo_Header local_copy; local_copy.source = *file_i; local_copy.destination = ""; if ("" != dest_dir) { local_copy.destination = dest_dir + "/"; } local_copy.destination += *file_i; build_info.headers.push_back(local_copy); } } } CYG_REPORT_RETURN(); return;}// ----------------------------------------------------------------------------// Updating a loadable build's info involves two steps. First, there// is some information associated with the loadable as a whole such as// header files. Second, each buildable in the loadable (including itself)// may contain properties such as compile etc. This is all handled via// a CdlBuildable member function.voidCdlBuildLoadableBody::update_build_info(CdlBuildInfo& build_info) const{ CYG_REPORT_FUNCNAME("CdlBuildLoadable::update_build_info"); CYG_REPORT_FUNCARG2XV(this, &build_info); CYG_PRECONDITION_THISC(); // It is not possible to disable a loadable itself: either the // loadable is present or it is not (although in some cases users // may be able to change versions). However, because of reparenting // it is possible for a loadable to be below a disabled container, // and hence it is still necessary to check whether or not the // loadable is active. if (!is_active()) { CYG_REPORT_RETURN(); return; } // Time to add a new CdlBuildInfo_Loadable object to the current // vector. The name and directory can be filled in straightaway, // the vectors will all be initialized to empty. CdlBuildInfo_Loadable tmp_info; build_info.entries.push_back(tmp_info); CdlBuildInfo_Loadable& this_info = *(build_info.entries.rbegin()); this_info.name = get_name(); this_info.directory = get_directory(); // Take care of the header files update_header_file_info(this, this_info); // Work out the library name appropriate for this loadable. // There may be a library property, otherwise the global default // should be used. std::string loadable_library = default_library_name; if (has_property(CdlPropertyId_Library)) { CdlProperty_String strprop = dynamic_cast<CdlProperty_String>(get_property(CdlPropertyId_Library)); loadable_library = strprop->get_string(); } const std::vector<CdlNode>& contents = get_owned(); std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { CdlBuildable buildable = dynamic_cast<CdlBuildable>(*node_i); if (0 != buildable) { buildable->update_build_info(this_info, loadable_library); } } CYG_REPORT_RETURN();}// This is much the same as the above, but there is no test for// active either at the loadable level or for the individual buildables.voidCdlBuildLoadableBody::update_all_build_info(CdlBuildInfo& build_info) const{ CYG_REPORT_FUNCNAME("CdlBuildLoadable::update_all_build_info"); CYG_REPORT_FUNCARG2XV(this, &build_info); CYG_PRECONDITION_THISC(); CdlBuildInfo_Loadable tmp_info; build_info.entries.push_back(tmp_info); CdlBuildInfo_Loadable& this_info = *(build_info.entries.rbegin()); this_info.name = get_name(); this_info.directory = get_directory(); std::string loadable_library = default_library_name; if (has_property(CdlPropertyId_Library)) { CdlProperty_String strprop = dynamic_cast<CdlProperty_String>(get_property(CdlPropertyId_Library)); loadable_library = strprop->get_string(); } const std::vector<CdlNode>& contents = get_owned();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -