#include #include #ifndef WIN32 #include #endif #include "cmt_use.h" #include "cmt_fragment.h" #include "cmt_symbol.h" #include "cmt_system.h" #include "cmt.h" #include "cmt_deps_builder.h" #include "cmt_generator.h" #include "cmt_constituent.h" #include "cmt_language.h" #include "cmt_awk.h" static Variable DOCPATH ("DOCPATH"); static Variable PACKAGEPATH ("PACKAGEPATH"); static Variable PACKAGEPREFIX ("PACKAGEPREFIX"); static Variable PACKAGE ("PACKAGE"); static Variable VERSION ("VERSION"); static Variable MGRSTYLE ("MGRSTYLE"); static Variable TITLE ("TITLE"); static Variable GROUP ("GROUP"); static Variable CONSTITUENT ("CONSTITUENT"); static Variable CONSTITUENTSUFFIX ("CONSTITUENTSUFFIX"); static Variable LIBRARYSUFFIX ("LIBRARYSUFFIX"); static Variable USER ("USER"); static Variable DATE ("DATE"); static Variable PROTOTARGET ("PROTOTARGET"); static Variable OBJS ("OBJS"); static Variable CLASSES ("CLASSES"); static Variable PROTOSTAMPS ("PROTOSTAMPS"); static Variable NAME ("NAME"); static Variable FILEPATH ("FILEPATH"); static Variable FILESUFFIX ("FILESUFFIX"); static Variable SUFFIX ("SUFFIX"); static Variable FILENAME ("FILENAME"); static Variable LINKMACRO ("LINKMACRO"); static Variable LINE ("LINE"); static Variable ADDINCLUDE ("ADDINCLUDE"); static Variable FULLNAME ("FULLNAME"); static Variable OUTPUTNAME ("OUTPUTNAME"); static Variable ALLOS9SOURCES ("ALLOS9SOURCES"); static Variable NODEBUGUSELINKOPTS ("NODEBUGUSELINKOPTS"); static Variable DEBUGUSELINKOPTS ("DEBUGUSELINKOPTS"); static Variable USEINCLUDES ("USEINCLUDES"); //------------------------------------------------------------------------ //------------------------------------------------------------------------ class SourceFile { public: void set (const cmt_string name, Language& language, const cmt_string output) { m_name = name; m_language = &language; m_output = output; char sep = CmtSystem::file_separator (); if (sep == '/') m_name.replace_all ("\\", sep); else m_name.replace_all ("/", sep); } cmt_string name () const { return (m_name); } Language& language () const { return (*m_language); } cmt_string output () const { return (m_output); } private: cmt_string m_name; Language* m_language; cmt_string m_output; }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ class MakefileGenerator { public: void analyze_file (const Constituent& constituent, const cmt_string& file); void analyze_document_file (const cmt_string& file, const cmt_string& constituent_name, const cmt_string& output_suffix); void reset (); void prepare_proto_file (const cmt_string& file); void proto_file_action (const cmt_string& file, const Constituent& constituent); void module_file_action (SourceFile& file, const Constituent& constituent); void java_file_action (SourceFile& file, const Constituent& constituent); void fill_outputs (); void build_application_makefile (const cmt_string& package, const Constituent& constituent); void build_library_makefile (const cmt_string& package, const Constituent& constituent); void build_document_makefile (const cmt_string& package, const Constituent& constituent); void prepare_use_context (); void set_full_name (cmt_string& full_name, cmt_string& file); cmt_string PACKINCLUDES; bool PACKOS9; cmt_string GENERATOR; bool is_library; bool is_application; bool is_document; cmt_string srcdir; cmt_string docdir; cmt_string cmtdir; cmt_string incdir; cmt_string msdevdir; cmt_string src; cmt_string doc; cmt_string inc; cmt_string mgr; cmt_string cmt; cmt_string protos; cmt_string protonames; cmt_string os9sources; cmt_vector source_files; FILE* output_file; DepsBuilder deps_builder; }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ static MakefileGenerator Context; static FragmentHandle buildproto_fragment ("buildproto"); static FragmentHandle dependencies_fragment ("dependencies"); static FragmentHandle dependencies_and_triggers_fragment ("dependencies_and_triggers"); static FragmentHandle make_header_fragment ("make_header"); static FragmentHandle library_header_fragment ("library_header"); static FragmentHandle application_header_fragment ("application_header"); static FragmentHandle document_header_fragment ("document_header"); static FragmentHandle java_header_fragment ("java_header"); static FragmentHandle jar_header_fragment ("jar_header"); static FragmentHandle protos_header_fragment ("protos_header"); static FragmentHandle library_fragment ("library"); static FragmentHandle library_no_share_fragment ("library_no_share"); static FragmentHandle application_fragment ("application"); static FragmentHandle jar_fragment ("jar"); static FragmentHandle java_fragment ("java"); static FragmentHandle cleanup_header_fragment ("cleanup_header"); static FragmentHandle cleanup_fragment ("cleanup"); static FragmentHandle cleanup_library_fragment ("cleanup_library"); static FragmentHandle cleanup_application_fragment ("cleanup_application"); static FragmentHandle cleanup_java_fragment ("cleanup_java"); static FragmentHandle cleanup_objects_fragment ("cleanup_objects"); static FragmentHandle dsw_header_fragment ("dsw_header"); static FragmentHandle dsw_project_fragment ("dsw_project"); static FragmentHandle dsw_all_project_header_fragment ("dsw_all_project_header"); static FragmentHandle dsw_all_project_dependency_fragment ("dsw_all_project_dependency"); static FragmentHandle dsw_all_project_trailer_fragment ("dsw_all_project_trailer"); static FragmentHandle dsw_trailer_fragment ("dsw_trailer"); static FragmentHandle dsp_all_fragment ("dsp_all"); static FragmentHandle dsp_library_header_fragment ("dsp_library_header"); //static FragmentHandle dsp_shared_library_header_fragment ("dsp_shared_library_header"); static FragmentHandle dsp_application_header_fragment ("dsp_application_header"); static FragmentHandle dsp_windows_header_fragment ("dsp_windows_header"); static FragmentHandle dsp_contents_fragment ("dsp_contents"); static FragmentHandle dsp_trailer_fragment ("dsp_trailer"); static FragmentHandle make_setup_header_fragment ("make_setup_header"); static FragmentHandle make_setup_fragment ("make_setup"); static FragmentHandle constituents_header_fragment ("constituents_header"); static FragmentHandle constituent_fragment ("constituent"); static FragmentHandle readme_header_fragment ("readme_header"); static FragmentHandle readme_fragment ("readme"); static FragmentHandle readme_doc_fragment ("readme_doc"); static FragmentHandle readme_use_fragment ("readme_use"); static FragmentHandle readme_trailer_fragment ("readme_trailer"); static FragmentHandle check_application_fragment ("check_application"); static FragmentHandle check_java_fragment ("check_java"); static FragmentHandle check_application_header_fragment ("check_application_header"); //------------------------------------------------------------------------ //-------------------------------------------------- class Packager : public FAwk { public: void begin (); void filter (const cmt_string& line); cmt_string& package_name (); private: cmt_string m_package_name; }; //-------------------------------------------------- //-------------------------------------------------- static void filter_paths (cmt_string& text) { static CmtSystem::cmt_string_vector ps; CmtSystem::split (text, " ", ps); text = ""; for (int i = 0; i < ps.size (); i++) { cmt_string& s = ps[i]; CmtSystem::compress_path (s); //cout << " filter_paths " << s << endl; if (i > 0) text += " "; text += s; } text.replace_all ("./../src/", "$(src)"); text.replace_all (".\\..\\src\\", "$(src)"); text.replace_all ("../src/", "$(src)"); text.replace_all ("..\\src\\", "$(src)"); text.replace_all ("../doc/", "$(doc)"); text.replace_all ("..\\doc\\", "$(doc)"); text.replace_all ("$(src)$(src)", "$(src)"); } static void get_all_files (const cmt_string& full_name, CmtSystem::cmt_string_vector& files) { static cmt_string suffix; static cmt_string name; suffix = ""; name = ""; files.clear (); CmtSystem::get_dot_suffix (full_name, suffix); if (full_name.find ('*') != cmt_string::npos) { CmtSystem::scan_dir (full_name, files); if (Cmt::debug) { cout << "CMT> full_name=" << full_name << " pwd=" << CmtSystem::pwd () << endl; cout << "CMT> files.size=" << files.size () << endl; } for (int j = 0; j < files.size (); j++) { cmt_string& n = files[j]; static cmt_string s; CmtSystem::get_dot_suffix (n, s); if (s != suffix) { n = ""; } } } else { cmt_string& n = files.add (); n = full_name; } } //-------------------------------------------------- //-------------------------------------------------- void MakefileGenerator::analyze_file (const Constituent& constituent, const cmt_string& file) { static cmt_string suffix; static cmt_string name; static cmt_string obj; obj = file; if (Cmt::debug) { cout << "MakefileGenerator::analyze_file> constituent=" << constituent.name << " file=" << file << endl; } CmtSystem::get_suffix (file, suffix); CmtSystem::basename (file, suffix, name); Language& language = Language::find_with_suffix (suffix); if (LINKMACRO == "") { LINKMACRO = language.linker; } if (language == "java") { static Packager packager; obj = "$(javabin)"; packager.run (file); if (packager.package_name () != "") { obj += packager.package_name (); obj += CmtSystem::file_separator (); } obj += name; obj += ".class"; } else if (language != Language::null ()) { obj = "$(bin)"; if (Cmt::build_nmake) obj += CONSTITUENT; if (Cmt::build_nmake) obj += CmtSystem::file_separator (); obj += name; obj += language.output_suffix; obj += constituent.suffix; if (Cmt::build_nmake) obj += ".obj"; else obj += ".o"; for (int i = 0; i < language.extra_output_suffixes.size (); i++) { cmt_string& extra_suffix = language.extra_output_suffixes[i]; obj += " $(bin)"; obj += name; obj += extra_suffix; obj += language.output_suffix; obj += constituent.suffix; if (Cmt::build_nmake) obj += ".obj"; else obj += ".o"; } } else { cout << "#CMT> analyze_file file=" << file << " no language" << endl; } if (Cmt::debug) { cout << "MakefileGenerator::analyze_file> constituent=" << constituent.name << " obj=" << obj << endl; } SourceFile& source = source_files.add (); source.set (file, language, obj); } //-------------------------------------------------- void MakefileGenerator::analyze_document_file (const cmt_string& file, const cmt_string& constituent_name, const cmt_string& output_suffix) { static cmt_string output_dir; static cmt_string suffix; static cmt_string name; static cmt_string obj; CmtSystem::dirname (file, output_dir); output_dir += CmtSystem::file_separator (); filter_paths (output_dir); CmtSystem::get_suffix (file, suffix); CmtSystem::basename (file, suffix, name); //obj = output_dir; obj = "$("; obj += constituent_name; obj += "_output)"; obj += name; obj += output_suffix; SourceFile& source = source_files.add (); source.set (file, Language::null (), obj); } //-------------------------------------------------- void MakefileGenerator::reset () { DOCPATH = ""; PACKAGEPATH = ""; PACKAGEPREFIX = ""; PACKAGE = ""; VERSION = ""; MGRSTYLE = ""; TITLE = ""; GROUP = ""; CONSTITUENT = ""; CONSTITUENTSUFFIX = ""; LIBRARYSUFFIX = ""; USER = ""; DATE = ""; PROTOTARGET = ""; OBJS = ""; CLASSES = ""; PROTOSTAMPS = ""; NAME = ""; FILEPATH = ""; FILESUFFIX = ""; SUFFIX = ""; FILENAME = ""; LINKMACRO = ""; LINE = ""; ADDINCLUDE = ""; FULLNAME = ""; OUTPUTNAME = ""; ALLOS9SOURCES = ""; NODEBUGUSELINKOPTS = ""; DEBUGUSELINKOPTS = ""; USEINCLUDES = ""; PACKINCLUDES = ""; PACKOS9 = false; GENERATOR = ""; is_library = false; is_application = false; is_document = false; srcdir = ""; docdir = ""; cmtdir = ""; incdir = ""; src = "$(src)"; doc = "$(doc)"; inc = "$(inc)"; mgr = "$(mgr)"; cmt = "$(cmt)"; protos = ""; protonames = ""; os9sources = ""; source_files.clear (); buildproto_fragment.reset (); dependencies_fragment.reset (); dependencies_and_triggers_fragment.reset (); make_header_fragment.reset (); library_header_fragment.reset (); application_header_fragment.reset (); document_header_fragment.reset (); java_header_fragment.reset (); jar_header_fragment.reset (); protos_header_fragment.reset (); library_fragment.reset (); library_no_share_fragment.reset (); jar_fragment.reset (); application_fragment.reset (); java_fragment.reset (); cleanup_header_fragment.reset (); cleanup_fragment.reset (); cleanup_library_fragment.reset (); cleanup_application_fragment.reset (); cleanup_java_fragment.reset (); cleanup_objects_fragment.reset (); dsw_header_fragment.reset (); dsw_project_fragment.reset (); dsw_all_project_header_fragment.reset (); dsw_all_project_dependency_fragment.reset (); dsw_all_project_trailer_fragment.reset (); dsw_trailer_fragment.reset (); dsp_all_fragment.reset (); dsp_library_header_fragment.reset (); //dsp_shared_library_header_fragment.reset (); dsp_application_header_fragment.reset (); dsp_windows_header_fragment.reset (); dsp_contents_fragment.reset (); dsp_trailer_fragment.reset (); make_setup_header_fragment.reset (); make_setup_fragment.reset (); constituents_header_fragment.reset (); constituent_fragment.reset (); readme_header_fragment.reset (); readme_fragment.reset (); readme_doc_fragment.reset (); readme_use_fragment.reset (); readme_trailer_fragment.reset (); check_application_fragment.reset (); check_java_fragment.reset (); check_application_header_fragment.reset (); Language::setup_all_fragments (); CmtSystem::cd (Cmt::current_dir); cmt_string branch = CmtSystem::current_branch (); if ((branch == "mgr") || (branch == "cmt")) { if (CmtSystem::test_directory ("../src")) { srcdir = ".."; srcdir += CmtSystem::file_separator (); srcdir += "src"; srcdir += CmtSystem::file_separator (); } else { srcdir = ""; } if (CmtSystem::test_directory ("../doc")) { docdir = ".."; docdir += CmtSystem::file_separator (); docdir += "doc"; docdir += CmtSystem::file_separator (); } else { docdir = ""; } if (CmtSystem::test_directory ("../cmt")) { cmtdir = ".."; cmtdir += CmtSystem::file_separator (); cmtdir += "cmt"; cmtdir += CmtSystem::file_separator (); } else if (CmtSystem::test_directory ("../mgr")) { cmtdir = ".."; cmtdir += CmtSystem::file_separator (); cmtdir += "mgr"; cmtdir += CmtSystem::file_separator (); } else { cmtdir = CmtSystem::pwd (); cmtdir += CmtSystem::file_separator (); } if (CmtSystem::test_directory ("../src")) { incdir = ".."; incdir += CmtSystem::file_separator (); incdir += "src"; incdir += CmtSystem::file_separator (); } else { incdir = ""; } msdevdir = ".."; msdevdir += CmtSystem::file_separator (); msdevdir += "Visual"; if (!CmtSystem::test_directory (msdevdir)) { CmtSystem::mkdir (msdevdir); } msdevdir += CmtSystem::file_separator (); } else { srcdir = "."; srcdir += CmtSystem::file_separator (); docdir = "."; docdir += CmtSystem::file_separator (); cmtdir = CmtSystem::pwd (); cmtdir += CmtSystem::file_separator (); incdir = "."; incdir += CmtSystem::file_separator (); msdevdir = "."; msdevdir += CmtSystem::file_separator (); } } //-------------------------------------------------- void MakefileGenerator::build_application_makefile (const cmt_string& package, const Constituent& constituent) { build_library_makefile (package, constituent); } //-------------------------------------------------- void MakefileGenerator::prepare_proto_file (const cmt_string& file) { static cmt_string name; static cmt_string pp; CmtSystem::name (file, name); if (CmtSystem::test_file (file)) { pp = incdir; pp += name; pp += ".pp"; if (!CmtSystem::test_file (pp)) { //Generator::build_prototype (file); } } protos += " "; protos += inc; protos += name; protos += ".ph"; protonames += " "; protonames += name; protonames += ".ph"; PROTOSTAMPS += " "; PROTOSTAMPS += inc; PROTOSTAMPS += name; PROTOSTAMPS += ".pp"; } //-------------------------------------------------- void MakefileGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent) { static cmt_string suffix; CmtSystem::dirname (file, FILEPATH.value); if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator (); filter_paths (FILEPATH.value); CmtSystem::basename (file, FILENAME.value); CmtSystem::get_dot_suffix (FILENAME, suffix); CmtSystem::basename (FILENAME, suffix, NAME.value); buildproto_fragment.copy (output_file, constituent.variables, 3, &NAME, &FILEPATH, &FILENAME); } //-------------------------------------------------- void MakefileGenerator::module_file_action (SourceFile& file, const Constituent& constituent) { cmt_string name = file.name (); Language& language = file.language (); static cmt_string suffix; static cmt_string prefix; static cmt_string preproc; FULLNAME = name; CmtSystem::get_dot_suffix (name, suffix); CmtSystem::basename (name, suffix, NAME.value); CmtSystem::dirname (name, prefix); CmtSystem::basename (name, FILENAME.value); FragmentHandle* fragment; if (language != Language::null ()) { preproc = language.preprocessor_command; fragment = (is_library) ? &(language.library) : &(language.application); } else { // // What happens when the language is not known??? // // preproc = "-I"; fragment = 0; } if ((prefix == "../src") || (prefix == "..\\src")) { ADDINCLUDE = ""; } else if (prefix != "") { ADDINCLUDE = preproc; ADDINCLUDE += prefix; } if (!CmtSystem::test_file (name)) { cout << "#CMT> Warning : Source file " << name << " not found" << endl; } FILEPATH = prefix; if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator (); filter_paths (FILEPATH.value); LINE = FULLNAME.value; LINE += " "; filter_paths (FULLNAME.value); filter_paths (LINE.value); CmtSystem::get_suffix (name, FILESUFFIX.value); if (fragment != 0) { fragment->copy (output_file, constituent.variables, 10, &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME, &NAME, &LINE, &ADDINCLUDE, &FULLNAME, &FILEPATH, &FILESUFFIX, &PACKAGE); } if (PACKOS9) { os9sources += LINE; os9sources += " "; } } //-------------------------------------------------- void MakefileGenerator::java_file_action (SourceFile& file, const Constituent& constituent) { static cmt_string suffix; FULLNAME = file.name (); OUTPUTNAME = file.output (); CmtSystem::get_dot_suffix (FULLNAME, suffix); CmtSystem::basename (FULLNAME, suffix, NAME.value); CmtSystem::basename (FULLNAME, FILENAME.value); if (CmtSystem::test_file (FULLNAME)) { java_fragment.copy (output_file, constituent.variables, 5, &NAME, &FULLNAME, &OUTPUTNAME, &CONSTITUENT, &CONSTITUENTSUFFIX); } else { cout << "#CMT> Warning : file " << FULLNAME << " not found" << endl; } } //-------------------------------------------------- void MakefileGenerator::fill_outputs () { bool first = true; OBJS = ""; for (int i = 0; i < source_files.size (); i++) { const SourceFile& file = source_files[i]; const cmt_string output = file.output (); if (output != "") { if (first) { first = false; } else { OBJS += " "; } OBJS += output; } if (Cmt::debug) { cout << "MakefileGenerator::fill_outputs> output=" << output << " OBJS=" << OBJS << endl; } } if (Cmt::debug) { cout << "MakefileGenerator::fill_outputs> OBJS=" << OBJS << endl; } } //-------------------------------------------------- void MakefileGenerator::build_library_makefile (const cmt_string& package, const Constituent& constituent) { static cmt_string lib; static cmt_string allsources; static cmt_string file; static cmt_string full_name; static cmt_string compressed_name; static cmt_string suffix; int i; bool need_prototypes; source_files.clear (); need_prototypes = constituent.need_prototypes; cout << TITLE << " " << CONSTITUENT << endl; lib = "$("; lib += CONSTITUENT; lib += "lib)"; // // Prepare the include paths // const CmtSystem::cmt_string_vector& includes = constituent.includes; for (i = 0; i < includes.size (); i++) { const cmt_string& subdir = includes[i]; PACKINCLUDES += " -I"; PACKINCLUDES += subdir; } // // Scan the sources. // const CmtSystem::cmt_string_vector& sources = constituent.modules; for (i = 0; i < sources.size (); i++) { file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { analyze_file (constituent, name); } } } fill_outputs (); prepare_use_context (); DATE = CmtSystem::now (); USER = CmtSystem::user (); make_header_fragment.copy (output_file, constituent.variables, 5, &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX, &USER, &DATE); if (need_prototypes) { need_prototypes = false; for (i = 0; i < source_files.size (); i++) { const SourceFile& file = source_files[i]; Language& language = file.language (); if (language.prototypes) { need_prototypes = true; break; } } } //------------------------------------------- // // Specific targets (application, library or java) // Prepare in case prototype files are needed // //------------------------------------------- PROTOTARGET = ""; //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { PROTOTARGET = CONSTITUENT; PROTOTARGET += "PROTOS"; } if (LINKMACRO == "java") { if (is_library) { jar_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } else { java_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } } else { if (is_library) { library_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &PROTOTARGET); } else { application_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &PROTOTARGET); } } //---------------------------------------------------- // // Preparing prototype files. // //---------------------------------------------------- //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { for (i = 0; i < source_files.size (); i++) { const SourceFile& file = source_files[i]; Language& language = file.language (); if (language.prototypes) { prepare_proto_file (file.name ()); } } if (PROTOSTAMPS != "") { protos_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &PROTOSTAMPS); } if (protonames != "") { for (i = 0; i < source_files.size (); i++) { const SourceFile& file = source_files[i]; Language& language = file.language (); if (language.prototypes) { proto_file_action (file.name (), constituent); } } } } //---------------------------------------------------- // // Preparing the library. // //---------------------------------------------------- if (OBJS != "") { if (LINKMACRO == "java") { if (is_library) { cmt_string classes = OBJS.value; classes.replace_all ("$(javabin)", ""); classes.replace_all (srcdir.c_str (), ""); CLASSES = classes; jar_fragment.copy (output_file, constituent.variables, 4, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS, &CLASSES); } } else { if (is_library) { if (constituent.no_share) { library_no_share_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } else { library_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } } else { application_fragment.copy (output_file, constituent.variables, 4, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS, &LINKMACRO); } } } LINE = ""; for (i = 0; i < sources.size (); i++) { file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); int count = 0; for (int j = 0; j < files.size (); j++) { cmt_string& n = files[j]; if (n != "") count++; } if (count > 0) { LINE += full_name; LINE += " "; } } filter_paths (LINE.value); if (constituent.build_triggers) { dependencies_and_triggers_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE); } else { dependencies_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE); } //---------------------------------------------------- // // Building actual individual targets. // //---------------------------------------------------- for (i = 0; i < source_files.size (); i++) { SourceFile& file = source_files[i]; Language& language = file.language (); if (language == "java") { java_file_action (file, constituent); } else { module_file_action (file, constituent); } } if (PACKOS9) { if (os9sources != "") { // // Generate transfers to the OS9 area. // ALLOS9SOURCES = ""; allsources = ""; } } /* for file in `cmt_sort_line.csh ${os9sources}` ; do if test `echo ${file} | grep '$(src)'` ; then name=`echo ${file} | sed 's#$(src)##'` ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}" allsources="${allsources} ${file}" elif test `echo ${file} | grep '$(inc)'` ; then name=`echo ${file} | sed 's#$(inc)##'` ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}" allsources="${allsources} ${file}" fi done if test ! "${ALLOS9SOURCES}" = "" ; then sed -e "`subs_vars ALLOS9SOURCES`" \ ${os9_header_fragment} \ >>${output} for FULLNAME in ${allsources} ; do NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'` sed -e "`subs_vars NAME FULLNAME`" \ ${os9_fragment} \ >>${output} done fi fi fi */ // // Generate package cleanup operations. // cleanup_header_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { if (protos != "") { FULLNAME = protos; cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME); FULLNAME = PROTOSTAMPS; cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME); } } if (LINKMACRO == "java") { cleanup_java_fragment.copy (output_file, constituent.variables, 1, &OBJS); if (!is_library) { if (constituent.need_check) { check_java_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); } } } else { if (is_library) { cleanup_library_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); } else { cleanup_application_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); if (OBJS != "") { cleanup_objects_fragment.copy (output_file, constituent.variables, 3, &OBJS, &CONSTITUENT, &CONSTITUENTSUFFIX); } if (constituent.need_check) { check_application_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); } } } } //-------------------------------------------------- void MakefileGenerator::build_document_makefile (const cmt_string& package, const Constituent& constituent) { static cmt_string names; static cmt_string output_dir; static cmt_string name; static cmt_string full_name; static cmt_string suffix; static cmt_string output_suffix; static cmt_string fragment_suffix; int i; cout << TITLE << " " << CONSTITUENT << endl; // // Prepare the include paths. // const CmtSystem::cmt_string_vector& includes = constituent.includes; for (i = 0; i < includes.size (); i++) { const cmt_string& subdir = includes[i]; PACKINCLUDES += " -I"; PACKINCLUDES += subdir; } // // Get the fragment associated with the document style // FragmentHandle fragment (GENERATOR); fragment_suffix = fragment.suffix (); output_suffix = "."; if (fragment_suffix == "") { output_suffix += fragment.name (); } else { output_suffix += fragment_suffix; } // // Scan the sources. // const CmtSystem::cmt_string_vector& sources = constituent.modules; for (i = 0; i < sources.size (); i++) { cmt_string& file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { analyze_document_file (name, constituent.name, output_suffix); } } } fill_outputs (); prepare_use_context (); DATE = CmtSystem::now (); USER = CmtSystem::user (); make_header_fragment.copy (output_file, constituent.variables, 5, &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX, &USER, &DATE); const cmt_string& header = fragment.header (); // // If the document type specifies a header, use it . // otherwise, use the default document header fragment. // if (header != "") { FragmentHandle header_fragment (header); header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } else { document_header_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } if (fragment.need_dependencies ()) { LINE = ""; for (i = 0; i < sources.size (); i++) { cmt_string& file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); int count = 0; for (int j = 0; j < files.size (); j++) { cmt_string& n = files[j]; if (n != "") count++; } if (count > 0) { LINE += full_name; LINE += " "; } } filter_paths (LINE.value); dependencies_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE); } else { for (i = 0; i < sources.size (); i++) { cmt_string& file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { static cmt_string s; static cmt_string n; CmtSystem::get_dot_suffix (name, s); CmtSystem::basename (name, s, n); CmtSystem::get_suffix (name, s); fprintf (output_file, "%s_%s_dependencies = %s\n", n.c_str (), s.c_str (), name.c_str ()); } } } } SUFFIX = fragment_suffix; for (i = 0; i < source_files.size (); i++) { SourceFile& file = source_files[i]; const cmt_string& file_name = file.name (); FULLNAME = file_name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, NAME.value); CmtSystem::dirname (file_name, FILEPATH.value); if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator (); filter_paths (FILEPATH.value); CmtSystem::basename (file_name, FILENAME.value); CmtSystem::get_dot_suffix (FILENAME.value, FILESUFFIX.value); if (!CmtSystem::test_file (file_name)) { cout << "#CMT> Warning : Source file " << file_name << " not found" << endl; } filter_paths (FULLNAME.value); fragment.copy (output_file, constituent.variables, 8, &FILEPATH, &SUFFIX, &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME, &NAME, &FULLNAME, &FILESUFFIX); } const cmt_string& trailer = fragment.trailer (); if (trailer != "") { FragmentHandle trailer_fragment (trailer); trailer_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS); } // // Generate package cleanup operations. // cleanup_header_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); } //-------------------------------------------------- void MakefileGenerator::prepare_use_context () { cmt_string path; cmt_string substitution; Use* use = &Use::current (); deps_builder.clear (); if (use->include_path != "none") { if (use->include_path == "") { deps_builder.add (incdir, "$(src)"); } else { substitution = use->include_path; path = substitution; Symbol::expand (path); if (CmtSystem::file_separator () == '/') { path.replace_all ("\\", "/"); path.replace_all ("//", "/"); } else { path.replace_all ("/", "\\"); path.replace_all ("\\\\", "\\"); } } deps_builder.add (path, substitution); } deps_builder.add_includes (*use); Use::UsePtrVector& uses = Use::uses (); if (uses.size () > 0) { int number; for (number = 0; number < uses.size (); number++) { use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { if (use->include_path != "none") { if (use->include_path == "") { path = use->real_path; path += CmtSystem::file_separator (); path += use->package; path += CmtSystem::file_separator (); path += use->version; path += CmtSystem::file_separator (); path += "src"; substitution = "$("; substitution += use->prefix; substitution += "ROOT)"; substitution += CmtSystem::file_separator (); substitution += "src"; substitution += CmtSystem::file_separator (); } else { substitution = use->include_path; path = substitution; Symbol::expand (path); if (CmtSystem::file_separator () == '/') { path.replace_all ("\\", "/"); path.replace_all ("//", "/"); } else { path.replace_all ("/", "\\"); path.replace_all ("\\\\", "\\"); } } deps_builder.add (path, substitution); } deps_builder.add_includes (*use); } } } } //-------------------------------------------------- void MakefileGenerator::set_full_name (cmt_string& full_name, cmt_string& file) { full_name = ""; Symbol::expand (file); if (file == "") return; if (!CmtSystem::absolute_path (file)) { full_name = srcdir; if (full_name != "") full_name += CmtSystem::file_separator (); } full_name += file; char sep = CmtSystem::file_separator (); if (sep == '/') { full_name.replace_all ("\\", sep); full_name.replace_all ("//", "/"); } else { full_name.replace_all ("/", sep); full_name.replace_all ("\\\\", "\\"); } } //-------------------------------------------------- void Generator::commit (const cmt_string& name) { static cmt_string old; static cmt_string backup; old = name; int pos = old.find_last_of ("new"); old.erase (pos); if (CmtSystem::test_file (old)) { backup = old; backup += "sav"; unlink (backup.c_str ()); rename (old.c_str (), backup.c_str ()); } rename (name.c_str (), old.c_str ()); } //-------------------------------------------------- void Generator::check (const cmt_string& name) { static cmt_string old; static cmt_string backup; old = name; int pos = old.find_last_of ("new"); old.erase (pos); if (!CmtSystem::compare_files (old, name)) { backup = old; backup += "sav"; unlink (backup.c_str ()); rename (old.c_str (), backup.c_str ()); rename (name.c_str (), old.c_str ()); } else { unlink (name); } } //-------------------------------------------------- int Generator::build_msdev_workspace (const Constituent::ConstituentVector& constituents) { Context.reset (); const cmt_string& package = Cmt::current_package; cmt_string output = Context.msdevdir + package + ".dswnew"; Context.output_file = fopen (output.c_str (), "wb"); if (Context.output_file != NULL) { PACKAGE = package; dsw_header_fragment.wincopy (Context.output_file, 1, &PACKAGE); int i; dsw_all_project_header_fragment.wincopy (Context.output_file, 1, &PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; if (constituent.type == Library) { CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } else { CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } } dsw_all_project_trailer_fragment.wincopy (Context.output_file, 1, &PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; if (constituent.type == Library) { CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; dsw_project_fragment.wincopy (Context.output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } else { CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; dsw_project_fragment.wincopy (Context.output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } } dsw_trailer_fragment.wincopy (Context.output_file, 1, &PACKAGE); fclose (Context.output_file); //--- Complete the operation -------------- commit (output); } output = Context.msdevdir + "all.dspnew"; Context.output_file = fopen (output.c_str (), "wb"); if (Context.output_file != NULL) { dsp_all_fragment.wincopy (Context.output_file, 1, &PACKAGE); fclose (Context.output_file); //--- Complete the operation -------------- commit (output); } return (0); } //-------------------------------------------------- int Generator::build_msdev (const Constituent& constituent) { Context.reset (); const cmt_string& package = Cmt::current_package; static cmt_string file; static cmt_string full_name; static cmt_string suffix; int i; CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; for (i = 0; i < constituent.includes.size (); i++) { const cmt_string& include = constituent.includes[i]; Context.PACKINCLUDES += " -I" + include; } switch (constituent.type) { case Application: Context.is_application = true; TITLE = "Application"; break; case Library: Context.is_library = true; TITLE = "Library"; break; case Document: Context.is_document = true; Context.GENERATOR = constituent.generator; TITLE = "Document"; break; } Context.PACKOS9 = constituent.need_OS9; const CmtSystem::cmt_string_vector& sources = constituent.modules; //--- Build the constituents fragment ----- cmt_string output; cmt_string output_s; FILE* output_file = NULL; FILE* output_file_s = NULL; output = Context.msdevdir + CONSTITUENT + ".dspnew"; output_file = fopen (output.c_str (), "wb"); if ((output_file == NULL) && (output_file_s == NULL)) return (0); PACKAGE = package; if (Context.is_library) { if (constituent.no_share) { LIBRARYSUFFIX = "lib"; } else { LIBRARYSUFFIX = "arc"; } dsp_library_header_fragment.wincopy (output_file, constituent.variables, 4, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX, &LIBRARYSUFFIX); } else { if (constituent.windows) { dsp_windows_header_fragment.wincopy (output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } else { dsp_application_header_fragment.wincopy (output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); } } for (i = 0; i < sources.size (); i++) { file = sources[i]; Context.set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { FULLNAME = name; if (output_file != NULL) { dsp_contents_fragment.wincopy (output_file, constituent.variables, 2, &PACKAGE, &FULLNAME); } if (output_file_s != NULL) { dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 2, &PACKAGE, &FULLNAME); } } } /* CmtSystem::get_suffix (full_name, suffix); if (file.find ('*') != cmt_string::npos) { static CmtSystem::cmt_string_vector files; CmtSystem::scan_dir (full_name, files); if (Cmt::debug) { cout << "CMT> full_name=" << full_name << " pwd=" << CmtSystem::pwd () << endl; cout << "CMT> files.size=" << files.size () << endl; } for (int j = 0; j < files.size (); j++) { const cmt_string& nnn = files[j]; static cmt_string sss; CmtSystem::get_suffix (nnn, sss); if (sss == suffix) { FULLNAME = nnn; if (output_file != NULL) { dsp_contents_fragment.wincopy (output_file, constituent.variables, 1, &FULLNAME); } if (output_file_s != NULL) { dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 1, &FULLNAME); } } } } else { FULLNAME = full_name; if (output_file != NULL) { dsp_contents_fragment.wincopy (output_file, constituent.variables, 1, &FULLNAME); } if (output_file_s != NULL) { dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 1, &FULLNAME); } } */ } if (output_file != NULL) { dsp_trailer_fragment.wincopy (output_file, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); fclose (output_file); commit (output); } if (output_file_s != NULL) { dsp_trailer_fragment.wincopy (output_file_s, constituent.variables, 3, &PACKAGE, &CONSTITUENT, &CONSTITUENTSUFFIX); fclose (output_file_s); commit (output_s); } return (0); } //-------------------------------------------------- void Generator::build_make_setup (const cmt_string& package) { Context.reset (); PACKAGE = package; FILE* output_file; cmt_string file_name = "setup."; if (Cmt::build_nmake) { file_name += "nmake"; } else { file_name += "make"; } cmt_string new_file_name = file_name; new_file_name += "new"; output_file = fopen (new_file_name, "wb"); if (output_file != NULL) { int number; const Use::UsePtrVector& uses = Use::uses (); const Constituent::ConstituentVector& constituents = Constituent::constituents (); cmt_string temp; make_setup_header_fragment.copy (output_file, 1, &PACKAGE); for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { temp = use->prefix; temp += "ROOT = "; temp += use->real_path; temp += SLASH; temp += use->package; temp += SLASH; temp += use->version; fprintf (output_file, "%s\n", temp.c_str()); } } temp = "use_requirements = "; temp += "requirements "; for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { temp += "$("; temp += use->prefix; temp += "ROOT)"; temp += CmtSystem::file_separator (); switch (use->style) { case cmt_style: temp += "cmt"; break; case mgr_style: temp += "mgr"; break; } temp += CmtSystem::file_separator (); temp += "requirements "; } } fprintf (output_file, "%s\n", temp.c_str()); temp = "constituents = $(constituents)"; Symbol::expand (temp); fprintf (output_file, "%s\n", temp.c_str()); make_setup_fragment.copy (output_file, 1, &PACKAGE); fclose (output_file); //--- Complete the operation -------------- commit (new_file_name); } /* for option in $* do case ${option} in args-tag=*) tag=${option} tag=`echo "${tag}" | sed -e 's/args.tag=//'` ;; -tag=*) tag=args${option} tag=`echo "${tag}" | sed -e 's/args.tag=//'` ;; esac done if test "${tag}" = "" ; then tag=${CMTCONFIG} fi build_shell_setup_files ${tag} now=`date` */ } //-------------------------------------------------- void Generator::build_constituents_makefile (const cmt_string& package) { Context.reset (); cmt_string file_name = "constituents."; //--- Build the constituents fragment ----- if (Cmt::build_nmake) { file_name += "nmake"; } else { file_name += "make"; } cmt_string save_file_name = file_name; save_file_name += "sav"; if (CmtSystem::test_file (file_name)) { rename (file_name, save_file_name); } cmt_string new_file_name = file_name; new_file_name += "new"; FILE* output_file = fopen (new_file_name, "wb"); if (output_file != NULL) { int number; const Constituent::ConstituentVector& constituents = Constituent::constituents (); GROUP = "all"; constituents_header_fragment.copy (output_file, 1, &GROUP); const Group::GroupVector& groups = Group::groups (); for (number = 0; number < groups.size (); number++) { const Group& group = groups[number]; GROUP = group.name (); constituents_header_fragment.copy (output_file, 1, &GROUP); } for (number = 0; number < constituents.size (); number++) { const Constituent& constituent = constituents[number]; CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; LINE = ""; const CmtSystem::cmt_string_vector& sources = constituent.modules; constituent_fragment.copy (output_file, constituent.variables, 3, &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE); if (constituent.need_check) { check_application_header_fragment.copy (output_file, constituent.variables, 2, &CONSTITUENT, &CONSTITUENTSUFFIX); } } fclose (output_file); commit (new_file_name); } } //-------------------------------------------------- int Generator::build_constituent_makefile (const Constituent& constituent) { Context.reset (); const cmt_string& package = Cmt::current_package; int i; PACKAGE = package; CONSTITUENT = constituent.name; CONSTITUENTSUFFIX = constituent.suffix; for (i = 0; i < constituent.includes.size (); i++) { const cmt_string& include = constituent.includes[i]; Context.PACKINCLUDES += " -I" + include; } switch (constituent.type) { case Application: Context.is_library = false; Context.is_application = true; Context.is_document = false; TITLE = "Application"; break; case Library: Context.is_library = true; Context.is_application = false; Context.is_document = false; TITLE = "Library"; break; case Document: Context.is_library = false; Context.is_application = false; Context.is_document = true; Context.GENERATOR = constituent.generator; TITLE = "Document"; break; } Context.PACKOS9 = constituent.need_OS9; cmt_string output = Context.cmtdir + CONSTITUENT + "."; if (Cmt::build_nmake) { output += "nmake"; } else { output += "make"; } output += "new"; Context.output_file = fopen (output.c_str (), "wb"); if (Context.output_file != NULL) { if (Context.is_library) { Context.build_library_makefile (package, constituent); } else if (Context.is_application) { Context.build_application_makefile (package, constituent); } else if (Context.is_document) { Context.build_document_makefile (package, constituent); } fclose (Context.output_file); //--- Complete the operation -------------- commit (output); } return (0); } //-------------------------------------------------- void Generator::build_constituent_makefile (const cmt_string& name) { const Constituent* constituent = Constituent::find (name); if (constituent != 0) build_constituent_makefile (*constituent); } //-------------------------------------------------- void Generator::build_default_makefile () { cmt_string makefile; //--- Build a simple Makefile if none is installed #ifndef WIN32 bool need_makefile = false; makefile = Context.cmtdir + "Makefile"; if (!CmtSystem::test_file (makefile)) { need_makefile = true; } else { static cmt_string s; s.read (makefile); if ((s.find ("METHODSROOT") != cmt_string::npos) || (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos)) { static cmt_string backup = makefile; backup += "_backup"; makefile += ".cmt"; if (!CmtSystem::test_file (makefile)) { FILE* file = fopen (backup.c_str (), "wb"); if (file != NULL) { cout << "# " << endl; cout << "#CMT> Warning !!! " << endl; cout << "# A Makefile already exists " "but it does not provides " << endl; cout << "# the recommended features " "for a full benefit of CMT" << endl; cout << "# " << endl; cout << "# CMT is now building " "a new 'Makefile.cmt' which you can use" << endl; cout << "# to upgrade your current one." << endl; cout << "# " << endl; s.write (file); fclose (file); need_makefile = true; } } } } if (need_makefile) { FILE* file = fopen (makefile.c_str (), "wb"); if (file != NULL) { fprintf (file, "include $(CMTROOT)/src/Makefile.header\n"); fprintf (file, "\n"); fprintf (file, "include $(CMTROOT)/src/constituents.make\n"); fprintf (file, "\n"); fclose (file); } } #endif #ifdef WIN32 makefile = Context.cmtdir + "NMake"; if (!CmtSystem::test_file (makefile)) { FILE* file = fopen (makefile.c_str (), "wb"); if (file != NULL) { fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n"); fprintf (file, "\n"); fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n"); fprintf (file, "\n"); fclose (file); } } #endif } //-------------------------------------------------- cmt_string Generator::build_dependencies (const cmt_string& file_name) { static cmt_string full_name; static cmt_string suffix; static cmt_string name; static cmt_string line; full_name = ""; line = ""; if (!CmtSystem::absolute_path (file_name)) { full_name = Context.srcdir; } full_name += file_name; CmtSystem::get_dot_suffix (full_name, suffix); CmtSystem::basename (full_name, suffix, name); CmtSystem::get_suffix (full_name, suffix); if (name == "requirements") return (line); const CmtSystem::cmt_string_vector& deps = Context.deps_builder.run (full_name); line = name; line += "_"; line += suffix; line += "_dependencies = "; line += full_name; line += " "; for (int j = 0; j < deps.size (); j++) { line += deps[j]; line += " "; } filter_paths (line); return (line); } //-------------------------------------------------- // o text contains lines with a pattern like : // key = xxxxx // // o line follows the same pattern // // This function appends to only if the key found in // is not found in //-------------------------------------------------- static void add_line_to_text (const cmt_string& line, cmt_string& text) { static const cmt_string empty; int pos = line.find (" = "); if (pos != cmt_string::npos) { static cmt_string key; line.substr (0, pos + 3, key); pos = text.find (key); if (pos != cmt_string::npos) { // The key in line exists in text. // Now check if the key is exactly the same. if ((pos == 0) || (text[pos -1] == '\n')) { // The key is either in the first line or // exactly matches '^key = ...' int nl = text.find (pos, "\n"); if (nl != cmt_string::npos) { static cmt_string old; text.substr (pos, nl - pos + 1, old); text.replace (old, empty); } else { text.erase (pos); } } } } if (line != "") { text += line; text += "\n"; } } //-------------------------------------------------- class DependencyFilter : public Awk { public: DependencyFilter () { } void begin () { m_sources = ""; } void filter (const cmt_string& line) { int pos = line.find ("_dependencies = "); if (pos == cmt_string::npos) return; cmt_string s = line; s.erase (pos); m_sources += " "; m_sources += s; m_sources += " "; //pos = s.find_last_of ("_"); //if (pos != cmt_string::npos) s[pos] = "." } void add_source (const cmt_string& file_name) { static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, name); CmtSystem::get_suffix (file_name, suffix); cmt_string s = " "; s += name; s += "_"; s += suffix; s += " "; if (m_sources.find (s) == cmt_string::npos) { m_sources += s; } } bool has_source (const cmt_string& file_name) const { static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, name); CmtSystem::get_suffix (file_name, suffix); cmt_string s = " "; s += name; s += "_"; s += suffix; s += " "; if (m_sources.find (s) == cmt_string::npos) { return (false); } else { return (true); } } cmt_string& get_sources () { return (m_sources); } private: cmt_string m_sources; }; //-------------------------------------------------- void Generator::build_dependencies (const cmt_string& name, int argc, char* argv[]) { Context.reset (); Context.prepare_use_context (); const Constituent* constituent_ptr = Constituent::find (name); if (constituent_ptr == 0) { // Error : wrong constituent name... return; } const Constituent& constituent = *constituent_ptr; cmt_string file_name; cmt_string full_name; cmt_string compressed_name; cmt_string suffix; cmt_string dependencies; static cmt_string output_name; cmt_string branch = CmtSystem::current_branch (); if ((branch == "mgr") || (branch == "cmt")) { Use& current_use = Use::current (); output_name = "../"; if (current_use.package == "CMT") { output_name += CmtSystem::getenv ("CMTBIN"); } else { output_name += "${tag}"; } output_name += "/"; Symbol::expand (output_name); } output_name += name; output_name += "_"; output_name += "dependencies."; if (Cmt::build_nmake) { output_name += "nmake"; } else { output_name += "make"; } static DependencyFilter filter; dependencies.read (output_name); filter.run (dependencies); // // Scan the sources. // // // We have to rebuild the dependencies for : // // o all sources if the parameter -all_sources has been received // o otherwise, // + all source names provided in the argument list (if any) // + all source names missing from the existing dependency file (if any) // const CmtSystem::cmt_string_vector& sources = constituent.modules; bool all_sources = false; int source_number = argc; int i; for (i = argc-1; i >= 0; i--) { file_name = argv[i]; // Get rid of files that may come from the makefile fragment if (file_name.find ("requirements") != cmt_string::npos) source_number--; else if (file_name.find (".make") != cmt_string::npos) source_number--; else if (file_name == "-all_sources") { source_number = sources.size (); all_sources = true; } } if (all_sources) { for (i = 0; i < sources.size (); i++) { file_name = sources[i]; Context.set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { const cmt_string& line = build_dependencies (name); //cout << ">>> name1=" << name << endl; add_line_to_text (line, dependencies); } } } } else { for (i = 0; i < source_number; i++) { file_name = argv[i]; Context.set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; const cmt_string& line = build_dependencies (full_name); //cout << ">>> name2=" << full_name << endl; add_line_to_text (line, dependencies); //cout << ">>from deps : " << filter.get_sources () << endl; filter.add_source (full_name); } //cout << ">>from deps : " << filter.get_sources () << endl; // Now : are there still any missing source file in dependencies?? for (i = 0; i < sources.size (); i++) { file_name = sources[i]; Context.set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { if (!filter.has_source (name)) { const cmt_string& line = build_dependencies (name); //cout << ">>> name3=" << name << endl; add_line_to_text (line, dependencies); } } } } } FILE* f = fopen (output_name.c_str (), "wb"); if (f == 0) { cerr << "Cannot open " << output_name << " for write" << endl; } else { dependencies.write (f); fclose (f); } } //-------------------------------------------------- class Prototyper : public FAwk { public: Prototyper (bool static_functions = false) : m_static_functions(static_functions) { if (m_static_functions) { m_suffix = "_static.phnew"; m_define_suffix = "_static_ph"; } else { m_suffix = ".phnew"; m_define_suffix = "_ph"; } } void begin () { m_running = false; static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (m_file_name, suffix); CmtSystem::basename (m_file_name, suffix, name); m_out_file_name = ""; if (m_dir_name != "") { m_out_file_name = m_dir_name; m_out_file_name += CmtSystem::file_separator (); } m_out_file_name += name; m_out_file_name += m_suffix; CmtSystem::basename (m_file_name, suffix, m_file_name); m_output = fopen (m_out_file_name.c_str (), "wb"); if (m_output != 0) { fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (), m_define_suffix.c_str ()); fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (), m_define_suffix.c_str ()); fprintf (m_output, "\n"); fprintf (m_output, "#ifdef __cplusplus\n"); fprintf (m_output, "extern \"C\" {\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); } else { stop (); } } void filter (const cmt_string& line) { char c = line[0]; if (!m_running) { if ((c == ' ') || (c == '/') || (c == '|') || (c == '\t') || (c == '#')) return; if (line.find ('(') == cmt_string::npos) { m_prev_line = line; return; } m_running = true; m_full_line = line; m_full_line.replace ("(", " ("); static CmtSystem::cmt_string_vector words; CmtSystem::split (m_full_line, " \t", words); const cmt_string& second = words[1]; if (second[0] == '(') { m_full_line = m_prev_line; m_full_line += " "; m_full_line += line; m_prev_line = ""; } } else { m_full_line += line; } if (line.find (')') == cmt_string::npos) return; m_running = false; if (m_full_line.find (';') != cmt_string::npos) return; if (m_full_line.find ("::") != cmt_string::npos) return; if (m_full_line.find ('<') != cmt_string::npos) return; if (m_full_line.find ('>') != cmt_string::npos) return; if (m_full_line.find ('{') != cmt_string::npos) return; if (m_full_line.find ('}') != cmt_string::npos) return; if (m_full_line.find ("typedef") != cmt_string::npos) return; if (m_full_line.find ("yy") != cmt_string::npos) return; if (m_full_line.find ("YY") != cmt_string::npos) return; if (m_static_functions) { if (m_full_line.find ("static") == cmt_string::npos) return; } else { if (m_full_line.find ("static") != cmt_string::npos) return; } m_full_line += ";"; if (m_output != 0) { fprintf (m_output, "%s\n", m_full_line.c_str ()); } } void end () { if (m_output != 0) { fprintf (m_output, "\n"); fprintf (m_output, "#ifdef __cplusplus\n"); fprintf (m_output, "}\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); fclose (m_output); } Generator::check (m_out_file_name); } private: bool m_running; cmt_string m_out_file_name; FILE* m_output; bool m_static_functions; cmt_string m_full_line; cmt_string m_prev_line; cmt_string m_suffix; cmt_string m_define_suffix; }; //-------------------------------------------------- //-------------------------------------------------- void Generator::build_prototype (const cmt_string& file_name) { Prototyper prototyper; prototyper.run (file_name); /* static cmt_string pp; pp = incdir; pp += name; pp += ".pp"; */ } //-------------------------------------------------- void Generator::build_readme (const CmtSystem::cmt_string_vector& arguments) { Context.reset (); PACKAGE = Cmt::current_package; VERSION = Cmt::current_version; DATE = CmtSystem::now (); USER = CmtSystem::user (); cmt_string url; cmt_string doc; for (int i = 0; i < arguments.size (); i++) { cmt_string arg = arguments[i]; if (arg.substr (0, 5) == "-url=") { arg.substr (5, url); } else if (arg.substr (0, 5) == "-doc=") { arg.substr (5, doc); } } cmt_string output = Context.cmtdir + "README.html"; Context.output_file = fopen (output.c_str (), "wb"); if (Context.output_file != NULL) { readme_header_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION); if (doc != "") { DOCPATH = doc; readme_doc_fragment.copy (Context.output_file, 3, &PACKAGE, &VERSION, &DOCPATH); } readme_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION); int number; const Use::UsePtrVector& uses = Use::uses (); for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use->discarded) continue; if ((use != 0) && (use->package != "CMT")) { cmt_string selected_path; if (url == "") { selected_path = use->real_path; if (use->specified_path != "") { int pos = selected_path.find_last_of (use->specified_path); if (pos != cmt_string::npos) { selected_path.erase (pos); } } } else { selected_path = url; if (use->specified_path != "") { selected_path += CmtSystem::file_separator (); } } PACKAGEPATH = selected_path; PACKAGEPREFIX = use->specified_path; PACKAGE = use->package; VERSION = use->version; MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt"; readme_use_fragment.copy (Context.output_file, 5, &PACKAGEPATH, &PACKAGEPREFIX, &PACKAGE, &VERSION, &MGRSTYLE); } } PACKAGE = Cmt::current_package; VERSION = Cmt::current_version; readme_trailer_fragment.copy (Context.output_file, 4, &PACKAGE, &VERSION, &DATE, &USER); } } class WinDefAwk : public PAwk { public : WinDefAwk (const cmt_string& library_name) { m_name = library_name; } void begin () { cout << "LIBRARY " << m_name << endl; cout << "EXPORTS" << endl; } void filter (const cmt_string& line) { if (line.find ("External") == cmt_string::npos) return; if (line.find ("??_") != cmt_string::npos) return; CmtSystem::cmt_string_vector words; CmtSystem::split (line, " \t", words); if (words.size () >= 8) { int pos = 7; cmt_string& fifth_word = words[4]; if (fifth_word == "()") pos = 7; else if (fifth_word == "External") pos = 6; else return; cmt_string& symbol = words[pos]; if (symbol[0] == '_') symbol.erase (0, 1); symbol.replace_all ("\r", ""); symbol.replace_all ("\n", ""); cout << " " << symbol << (pos == 6 ? "\tDATA" : " ") << endl; } } void end () { } private: cmt_string m_name; }; //-------------------------------------------------- void Generator::build_windefs (const cmt_string& library_name) { cmt_string bin; cmt_string name; cmt_string suffix; CmtSystem::dirname (library_name, bin); CmtSystem::get_dot_suffix (library_name, suffix); CmtSystem::basename (library_name, suffix, name); if (!CmtSystem::cd (bin)) return; cmt_string text; cmt_string command; command = "dumpbin /symbols "; command += library_name; WinDefAwk filter (name); filter.run (command, "SECT"); } //-------------------------------------------------- void Packager::begin () { m_package_name = ""; } void Packager::filter (const cmt_string& line) { CmtSystem::cmt_string_vector words; CmtSystem::split (line, " ", words); if (words.size () > 1) { cmt_string& w = words[0]; if (w == "package") { m_package_name = words[1]; int pos = m_package_name.find (";"); if (pos != cmt_string::npos) m_package_name.erase (pos); m_package_name.replace_all (".", CmtSystem::file_separator ()); } } } cmt_string& Packager::package_name () { return (m_package_name); }