// // aegis - project change supervisor // Copyright (C) 2008-2014 Peter Miller // // 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 3 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, see . // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static nstring first_line_only(const nstring &s) { unsigned max = 47; const char *start = s.c_str(); const char *end = start + s.size(); if (s.size() > max) end = start + max; const char *cp = start; while (cp < end) { unsigned char c = *cp; // tabs are OK, newlines are not if (c == '\t' || isprint(c)) ++cp; else break; } return nstring(start, cp - start); } static void wrap_and_print(const output::pointer &op, const nstring &caption, const nstring_list &items) { if (items.empty()) return; op->fputs(caption); size_t column = caption.size(); op->fputc(':'); ++column; for (size_t j = 0; j < items.size(); ++j) { if (j) { op->fputc(','); ++column; } nstring s = items[j]; if (column + 1 + s.size() >= 80) { op->fputc('\n'); column = 0; } op->fputc(' '); ++column; op->fputs(s); column += s.size(); } op->fputc('\n'); } static void check_against_list(const nstring &name, const char **list, size_t list_size) { for (const char **p = list; p < list + list_size; ++p) { if (name == *p) return; } nstring best; double best_weight = 0.6; for (const char **f = list; f < list + list_size; ++f) { nstring candidate(*f); double weight = fstrcmp(name.c_str(), candidate.c_str()); if (best_weight < weight) { best_weight = weight; best = candidate; } } if (best.empty()) { sub_context_ty sc; sc.var_set_string("Name", name); fatal_intl(&sc, i18n("the name \"$name\" is undefined")); // NOTREACHED } else { sub_context_ty sc; sc.var_set_string("Name", name); sc.var_set_string("Guess", best); fatal_intl(&sc, i18n("no \"$name\", guessing \"$guess\"")); // NOTREACHED } } static void check_section(const nstring &name) { // Debian Policy Manual, version 2.8.2.0, section 2.4 nstring_list parts; parts.split(name, "/"); while (parts.size() < 2) parts.push_front("main"); struct table_t { const char *name; const char *version; }; static const table_t table[] = { { "admin", "3.5.6" }, // { "base", "3.5.6" }, // obsolete { "cli-mono", "3.8.2" }, { "comm", "3.5.6" }, // { "contrib", "3.5.6" }, // obsolete { "database", "3.8.2" }, { "debug", "3.8.2" }, { "devel", "3.5.6" }, { "doc", "3.5.6" }, { "editors", "3.5.6" }, { "electronics", "3.5.6" }, { "embedded", "3.6.1" }, { "fonts", "3.8.2" }, { "games", "3.5.6" }, { "gnome", "3.6.1" }, { "gnu-r", "3.8.2" }, { "gnustep", "3.8.2" }, { "graphics", "3.5.6" }, { "hamradio", "3.5.6" }, { "haskell", "3.8.2" }, { "httpd", "3.8.2" }, { "interpreters", "3.5.6" }, { "java", "3.8.2" }, { "kde", "3.6.1" }, { "kernel", "3.8.2" }, { "libdevel", "3.6.1" }, { "libs", "3.5.6" }, { "lisp", "3.8.2" }, { "localization", "3.8.2" }, { "mail", "3.5.6" }, { "math", "3.5.6" }, { "misc", "3.5.6" }, { "net", "3.5.6" }, { "news", "3.5.6" }, // { "non-free", "3.5.6" }, // obsolete // { "non-US", "3.5.6" }, // obsolete { "ocaml", "3.8.2" }, { "oldlibs", "3.5.6" }, { "otherosfs", "3.5.6" }, { "perl", "3.6.1" }, { "php", "3.8.2" }, { "python", "3.6.1" }, { "ruby", "3.8.2" }, { "science", "3.5.6" }, { "shells", "3.5.6" }, { "sound", "3.5.6" }, { "tex", "3.5.6" }, { "text", "3.5.6" }, { "utils", "3.5.6" }, { "vcs", "3.8.2" }, { "video", "3.8.2" }, { "web", "3.5.6" }, { "x11", "3.5.6" }, { "xfce", "3.8.2" }, { "zope", "3.8.2" }, }; const table_t *best = 0; double best_weight = 0.6; for (const table_t *tp = table; tp < ENDOF(table); ++tp) { if (0 == strcmp(name.c_str(), tp->name)) { return; } double weight = fstrcmp(name.c_str(), tp->name); if (weight > best_weight) { best = tp; best_weight = weight; } } if (!best) { sub_context_ty sc; sc.var_set_string("Name", name); fatal_intl(&sc, i18n("the name \"$name\" is undefined")); // NOTREACHED } else { sub_context_ty sc; sc.var_set_string("Name", name); sc.var_set_charstar("Guess", best->name); fatal_intl(&sc, i18n("no \"$name\", guessing \"$guess\"")); // NOTREACHED } } static nstring doc_base_section_from_debian_section(const nstring &name) { struct table_t { const char *deb_name; const char *doc_base_name; }; static const table_t table[] = { { "admin", "System/Administration" }, { "cli-mono", "Programming" }, { "comm", "Network" }, { "database", "Data Management" }, { "debug", "Programming", }, { "devel", "Programming" }, { "doc", "Debian" }, { "editors", "Editors" }, { "electronics", "Science/Electronics" }, { "embedded", "Programming" }, { "fonts", "Office" }, { "games", "Games" }, { "gnome", "Graphics" }, { "gnu-r", "Programming" }, { "gnustep", "Programming" }, { "graphics", "Graphics" }, { "hamradio", "Amateur Radio" }, { "haskell", "Programming" }, { "httpd", "Network" }, { "interpreters", "Emulators" }, { "java", "Programming/Java" }, { "kde", "Graphics" }, { "kernel", "System" }, { "libdevel", "Programming" }, { "libs", "Programming" }, { "lisp", "Programming/Lisp" }, { "localization", "Programming" }, { "mail", "Network/Communication" }, { "math", "Science/Mathematics" }, { "misc", "Programming" }, { "net", "Network" }, { "news", "Network" }, { "ocaml", "Programming/Ocaml" }, { "oldlibs", "Programming" }, { "otherosfs", "Programming" }, { "perl", "Programming/Perl" }, { "php", "Programming/Php" }, { "python", "Programming/Python" }, { "ruby", "Programming/Ruby" }, { "science", "Science" }, { "shells", "Shells" }, { "sound", "Sound" }, { "tex", "Typesetting" }, { "text", "Text" }, { "utils", "Programming" }, { "vcs", "Programming" }, { "video", "Video" }, { "web", "Network" }, { "x11", "Graphics" }, { "xfce", "Graphics" }, { "zope", "Network" }, }; for (const table_t *tp = table; tp < ENDOF(table); ++tp) { if (name == tp->deb_name) return tp->doc_base_name; } return "Programming"; } static void check_priority(const nstring &name) { // Debian Policy Manual 2.5 static const char *ok[] = { "required", "important", "standard", "optional", "extra" }; check_against_list(name, ok, SIZEOF(ok)); } void target_debian::maybe_field(const output::pointer &fp, const nstring &field_name, const nstring &root_name) { nstring name = "aemakegen:debian:" + field_name; if (!root_name.empty()) name += ":" + root_name; nstring value = get_cp()->pconf_attributes_find(name); if (!value.empty()) { fp->fprintf("%s: %s\n", field_name.capitalize().c_str(), value.c_str()); } } static nstring_list filter_man15678(const nstring_list &src) { nstring_list result; for (size_t j = 0; j < src.size(); ++j) { nstring fn = src[j]; nstring section = fn.field('/', 1); if (section == "man1" || (section >= "man5" && section <= "man8")) result.push_back(fn); } return result; } static nstring_list filter_man234(const nstring_list &src) { nstring_list result; for (size_t j = 0; j < src.size(); ++j) { nstring fn = src[j]; nstring section = fn.field('/', 1); if (section >= "man2" && section <= "man4") result.push_back(fn); } return result; } static nstring_list filter_runtime(const nstring_list &src) { nstring_list result; for (size_t j = 0; j < src.size(); ++j) { nstring fn = src[j]; if (fn.ends_with(".la") || fn.ends_with(".a")) { nstring stem = fn.trim_extension(); result.push_back_unique(stem + ".so.*"); } } return result; } static nstring_list filter_bin(const nstring_list &src) { nstring_list result; for (size_t j = 0; j < src.size(); ++j) { nstring fn = src[j]; if (!fn.ends_with(".la") && !fn.ends_with(".a") && !fn.ends_with(".pc")) { result.push_back(fn); } } return result; } nstring_list target_debian::filter_dev(const nstring_list &src) const { nstring_list result; for (size_t j = 0; j < src.size(); ++j) { nstring fn = src[j]; if (fn.ends_with(".la") || fn.ends_with(".a")) { nstring stem = fn.trim_extension(); result.push_back_unique(stem + ".a"); result.push_back_unique(stem + ".so"); if (data.use_lib_la_files()) { // The debian folk take exception to the "almost // always useless" *.la files installed by libtool. result.push_back_unique(stem + ".la"); } } else if (fn.ends_with(".pc")) { result.push_back_unique(fn); } } return result; } nstring target_debian::expand_make_macro(const nstring &text) { struct table_t { const char *from; const char *to; }; static const table_t table[] = { { "$(bindir)", "usr/bin" }, { "$(datadir)", "usr/share" }, { "$(datarootdir)", "usr/share" }, { "$(exec_prefix)", "usr" }, { "$(EXEEXT)", "" }, { "$(includedir)", "usr/include" }, { "$(libdir)", "usr/lib" }, { "$(localedir)", "usr/share/locale" }, { "$(mandir)", "usr/share/man" }, { "$(NLSDIR)", "usr/share/locale" }, { "$(prefix)", "usr" }, { "$(sysconfdir)", "etc" }, }; for (const table_t *tp = table; tp < ENDOF(table); ++tp) { const char *cp = strstr(text.c_str(), tp->from); if (cp) { size_t s1 = cp - text.c_str(); size_t s2 = strlen(tp->from); size_t s3 = text.size() - (s1 + s2); // There are two choices here. #if 1 // This choice does not permit recursive substitutions // and is thus slightly faster than the next choice. return ( text.substr(0, s1) + tp->to + expand_make_macro(text.substr(s1 + s2, s3)) ); #else // This choice permits recursive substitutions (potential // for infinite recursion, though not this specific case). return ( text.substr(0, s1) + translate_make_macro(tp->to + text.substr(s1 + s2, s3)) ); #endif } } const char *cp = strchr(text.c_str(), '$'); if (cp) { const char *cp2 = strchr(cp, '/'); if (!cp2) cp2 = cp + strlen(cp); error_raw ( "make macro %s not understood", nstring(cp, cp2 - cp).quote_c().c_str() ); this_is_a_bug(); // NOTREACHED } return text; } void target_debian::fill_instance_variables(void) { source_package_name = get_project_name(); // binary_package_files are for executable programs // and libdir and datadir and i18n required to support them binary_package_name = ( source_package_name.starts_with("lib") ? source_package_name.substr(3, source_package_name.size() - 3) : source_package_name ); binary_package_files.push_back(data.get_install_bin()); if (data.use_libtool()) { binary_package_files.push_back ( filter_man15678(data.get_install_mandir()) ); } else binary_package_files.push_back(data.get_install_mandir()); binary_package_files.push_back(filter_bin(data.get_install_libdir())); binary_package_files.push_back(data.get_install_datadir()); // Put the i18n files in the binary package, if there is no runtime package. if (!data.use_libtool()) binary_package_files.push_back(data.get_install_i18n()); // doc files are for the "*-doc" package documentation_package_name = source_package_name + "-doc"; documentation_package_files.push_back(data.get_install_doc()); nstring lib_root_name = "lib" + binary_package_name; // runtime files are for shared libraries runtime_package_name = lib_root_name + data.get_version_info_major(); runtime_package_files.push_back(filter_runtime(data.get_install_libdir())); // Put the i18n files in the runtime package, if there is one. if (data.use_libtool()) runtime_package_files.push_back(data.get_install_i18n()); debug_package_name = runtime_package_name + "-dbg"; // developer files are for static libraries and include files developer_package_name = lib_root_name + "-dev"; developer_package_files.push_back(data.get_install_include()); if (data.use_libtool()) { developer_package_files.push_back ( filter_man234(data.get_install_mandir()) ); developer_package_files.push_back ( filter_dev(data.get_install_libdir()) ); } } void target_debian::gen_control(void) { nstring source_description = nstring(project_brief_description_get(get_pp()->trunk_get())); source_description = first_line_only(source_description).trim(); nstring source_extended_description = get_cp()->pconf_attributes_find ( "aemakegen:debian:extended-description:" + source_package_name ); if (source_extended_description.empty()) { source_extended_description = get_cp()->pconf_attributes_find ( "aemakegen:debian:extended-description" ); } nstring runtime_extended_description = get_cp()->pconf_attributes_find ( "aemakegen:debian:description:" + runtime_package_name ); if (runtime_extended_description.empty()) { runtime_extended_description = get_cp()->pconf_attributes_find ( "aemakegen:debian:description:lib" + binary_package_name ); } if (runtime_extended_description.empty()) runtime_extended_description = source_extended_description; nstring devel_extended_description = get_cp()->pconf_attributes_find ( "aemakegen:debian:extended-description:" + developer_package_name ); if (devel_extended_description.empty()) devel_extended_description = source_extended_description; // write debian/control os_become_orig(); output::pointer fp = output_file::open("debian/control"); os_become_undo(); // ---------- source package ----------------------------------------- fp->fprintf("Source: %s\n", source_package_name.c_str()); nstring section = get_cp()->pconf_attributes_find("aemakegen:debian:section"); if (section.empty()) section = "utils"; check_section(section); fp->fprintf("Section: %s\n", section.c_str()); nstring priority = get_cp()->pconf_attributes_find("aemakegen:debian:priority"); if (priority.empty()) priority = "optional"; check_priority(priority); fp->fprintf("Priority: %s\n", priority.c_str()); nstring maintainer = get_cp()->pconf_attributes_find("aemakegen:debian:maintainer"); if (maintainer.empty()) get_up()->get_email_address(); fp->fprintf("Maintainer: %s\n", maintainer.c_str()); nstring homepage = get_cp()->pconf_attributes_find("aemakegen:debian:homepage"); if (!homepage.empty()) { fp->fprintf("Homepage: %s\n", homepage.c_str()); } if ( get_cp()->pconf_attributes_get_boolean ( "aemakegen:debian:dm-upload-allowed" ) ) { fp->fprintf("DM-Upload-Allowed: yes\n"); } // // The Build-Depends: list may need a few more things, and we sort it. // nstring_list build_depends_list; nstring build_depends = get_cp()->pconf_attributes_find("aemakegen:debian:build-depends"); if (!build_depends.empty()) { build_depends_list.split(build_depends, ",", true); build_depends_list.remove(""); // common infelicity } build_depends_list.push_back_unique("debhelper (>= 5)"); build_depends_list.push_back_unique("dh-autoreconf"); build_depends_list.push_back_unique("autotools-dev"); if (data.use_libtool()) build_depends_list.push_back_unique("libtool"); if (data.need_groff()) build_depends_list.push_back_unique("groff"); if (data.need_yacc()) build_depends_list.push_back_unique("bison"); if (data.need_lex()) build_depends_list.push_back_unique("flex"); if (data.need_ghostscript()) build_depends_list.push_back_unique("ghostscript"); build_depends_list.sort(); wrap_and_print(fp, "Build-Depends", build_depends_list); if (!runtime_package_files.empty()) { check_section("libs"); check_section("debug"); } if (!developer_package_files.empty()) check_section("libdevel"); // Lintian would be a whole lot more useful if it actually checked // packages against the claimed standards version, instead of // blindly demanding that the standards version is always up-to-date. fp->fputs("Standards-Version: 3.9.3\n"); // ---------- binary package ----------------------------------------- // // This is the binary package, it contains the executables. // if (!binary_package_files.empty()) { binary_package_files.sort(); fp->fprintf("\n"); fp->fprintf("Package: %s\n", binary_package_name.c_str()); fp->fprintf("Architecture: any\n"); nstring description = get_cp()->pconf_attributes_find ( "aemakegen:debian:description:" + binary_package_name ); if (description.empty()) { description = source_description; if (binary_package_name != source_package_name) description += " - programs"; } fp->fprintf("Description: %s\n", description.c_str()); // wrap the extended description, if one has been provided // in the project-specific attributes. { nstring aname = "aemakegen:debian:extended-description:" + binary_package_name; nstring binary_extended_description = get_cp()->pconf_attributes_find(aname); if (binary_extended_description.empty()) binary_extended_description = source_extended_description; if (!binary_extended_description.empty()) { output::pointer op2 = output_wrap_open ( output_filter_dot_blank_lines::create ( output_filter_prefix::create(fp, " ") ), 79 ); op2->fputs(binary_extended_description); op2->end_of_line(); } } nstring_list depends_list; nstring depends = get_cp()->pconf_attributes_find("aemakegen:debian:depends"); if (!depends.empty()) depends_list.split(depends, ",", true); depends_list.push_back("${shlibs:Depends}"); depends_list.push_back("${misc:Depends}"); if (!runtime_package_files.empty()) depends_list.push_back(runtime_package_name); depends_list.remove(""); depends_list.sort(); wrap_and_print(fp, "Depends", depends_list); maybe_field(fp, "breaks", binary_package_name); maybe_field(fp, "conflicts", binary_package_name); maybe_field(fp, "provides", binary_package_name); maybe_field(fp, "recommends", binary_package_name); maybe_field(fp, "replaces", binary_package_name); maybe_field(fp, "suggests", binary_package_name); } // ---------- documentation package ---------------------------------- if (!documentation_package_files.empty()) { // // The doc binary package for the user documentation, // other than man pages. // // Package: -doc // documentation_package_files.sort(); fp->fprintf("\n"); fp->fprintf("Package: %s\n", documentation_package_name.c_str()); fp->fprintf("Architecture: all\n"); fp->fprintf("Section: doc\n"); nstring description = get_cp()->pconf_attributes_find ( "aemakegen:debian:description:" + documentation_package_name ); if (description.empty()) { description = source_description; if ( runtime_package_name != source_package_name + data.get_version_info_major() ) description += " - documentation"; } fp->fprintf("Description: %s\n", description.c_str()); // Wrap the extended description, if one has been provided // in the project-specific attributes. nstring aname = "aemakegen:debian:extended-description:" + documentation_package_name; nstring doc_extended_description = get_cp()->pconf_attributes_find(aname); if (doc_extended_description.empty()) doc_extended_description = devel_extended_description; if (!doc_extended_description.empty()) { output::pointer op2 = output_wrap_open ( output_filter_dot_blank_lines::create ( output_filter_prefix::create(fp, " ") ), 79 ); op2->fputs(doc_extended_description); op2->end_of_line(); } { nstring depname = "aemakegen:debian:depends:" + documentation_package_name; nstring depends = get_cp()->pconf_attributes_find(depname); nstring_list depends_list; depends_list.split(depends, ",", true); depends_list.remove(""); // common infelicity depends_list.push_back("${misc:Depends}"); // for debhelper depends_list.sort(); wrap_and_print(fp, "Depends", depends_list); } maybe_field(fp, "breaks", documentation_package_name); maybe_field(fp, "conflicts", documentation_package_name); maybe_field(fp, "provides", documentation_package_name); maybe_field(fp, "recommends", documentation_package_name); maybe_field(fp, "replaces", documentation_package_name); maybe_field(fp, "suggests", documentation_package_name); // // Generate the debian/-doc.doc-base file. // // We will do it as a single document, it simplifies everything // except doc-base. I wonder if anyone actually uses this // facility? // // According to dh_installdocs(1), // // debian/.doc-base.* // "If your package needs to register more than one // document, you need multiple doc-base files, and can // name them like this." // // Which is a whole lot of work for not much gain. // nstring fn2 = "debian/" + documentation_package_name + ".doc-base"; os_become_orig(); output::pointer op2 = output_file::open(fn2); os_become_undo(); nstring uc_source_package_name = source_package_name.capitalize(); op2->fputs("Document: "); op2->fputs(source_package_name); op2->fputs("\nTitle: "); op2->fputs(uc_source_package_name); op2->fputs(" Manuals\nAuthor: "); op2->fputs(get_cp()->pconf_copyright_owner_get()); op2->fputs("\nAbstract: "); op2->fputs(uc_source_package_name); op2->fputs(" Manuals\nSection: "); op2->fputs(doc_base_section_from_debian_section(section)); op2->fputs("\n\nFormat: PDF\nFiles:"); for (size_t j = 0; j < documentation_package_files.size(); ++j) { op2->fputs(" /"); op2->fputs(expand_make_macro(documentation_package_files[j])); // we need the wildcard, because they may or may not be // compressed by the time we see this. op2->fputs("*\n"); } } if (data.use_libtool()) { // The libtool program is only used when a shared library is // going to be installed. Use this to decide whether or not to // add the binary packages for shared libraries. if (!runtime_package_files.empty()) { // ---------- runtime package -------------------------------- // // The runtime binary package for the shared library. Using a // shared library (as opposed to a static library) reduces the // size of executable of all clients, but increases the amount // of work to be done by a program before main() is called. // // Package: lib. // runtime_package_files.sort(); fp->fprintf("\n"); fp->fprintf("Package: %s\n", runtime_package_name.c_str()); if (section != "libs") { // lintian(1) does not like redundant Section lines fp->fprintf("Section: libs\n"); } fp->fprintf("Architecture: any\n"); nstring description = get_cp()->pconf_attributes_find ( "aemakegen:debian:description:" + runtime_package_name ); if (description.empty()) { description = source_description; if ( runtime_package_name != source_package_name + data.get_version_info_major() ) description += " - runtime library"; } fp->fprintf("Description: %s\n", description.c_str()); // wrap the extended description, if one has been provided // in the project-specific attributes. if (!runtime_extended_description.empty()) { output::pointer op2 = output_wrap_open ( output_filter_dot_blank_lines::create ( output_filter_prefix::create(fp, " ") ), 79 ); op2->fputs(runtime_extended_description); op2->end_of_line(); } nstring_list depends_list; nstring depends = get_cp()->pconf_attributes_find("aemakegen:debian:depends"); if (!depends.empty()) depends_list.split(depends, ",", true); depends_list.push_back("${shlibs:Depends}"); depends_list.push_back("${misc:Depends}"); depends_list.sort(); wrap_and_print(fp, "Depends", depends_list); // ---------- debug package ---------------------------------- // // The debug binary package, used to hold the debug symbls // for the runtime package. This simplifies start-up // linking for client programs, and reduces the time before // main() is called. // // package: lib.-dbg // fp->fprintf("\n"); fp->fprintf("Package: %s\n", debug_package_name.c_str()); if (section != "debug") { // lintian(1) does n't like redundant Section lines fp->fprintf("Section: debug\n"); } if (priority != "extra") { // lintian(1) does n't like redundant Priority lines fp->fprintf("Priority: extra\n"); } fp->fprintf("Architecture: any\n"); nstring aname = "aemakegen:debian:description:" + debug_package_name; description = get_cp()->pconf_attributes_find(aname); if (description.empty()) description = source_description; description += " - debugging symbols"; fp->fprintf("Description: %s\n", description.c_str()); aname = "aemakegen:debian:extended-description:" + debug_package_name; nstring debug_extended_description = get_cp()->pconf_attributes_find(aname); if (debug_extended_description.empty()) debug_extended_description = runtime_extended_description; if (debug_extended_description.empty()) debug_extended_description = source_extended_description; if (!debug_extended_description.empty()) { output::pointer op2 = output_wrap_open ( output_filter_dot_blank_lines::create ( output_filter_prefix::create(fp, " ") ), 79 ); op2->fputs(debug_extended_description); op2->end_of_line(); } depends_list.push_back ( runtime_package_name + " (= ${binary:Version})" ); wrap_and_print(fp, "Depends", depends_list); maybe_field(fp, "breaks", runtime_package_name); maybe_field(fp, "conflicts", runtime_package_name); maybe_field(fp, "provides", runtime_package_name); maybe_field(fp, "recommends", runtime_package_name); maybe_field(fp, "replaces", runtime_package_name); maybe_field(fp, "suggests", runtime_package_name); } if (!developer_package_files.empty()) { // ---------- developer package ------------------------------ // // The dev package, for linking programs to the library, and // header files required to build the library. // // Package: lib-dev // developer_package_files.sort(); fp->fprintf("\n"); fp->fprintf("Package: %s\n", developer_package_name.c_str()); if (section != "libdevel") { // lintian(1) does not like redundant Section lines fp->fprintf("Section: libdevel\n"); } fp->fprintf("Architecture: any\n"); nstring aname = "aemakegen:debian:description:" + developer_package_name; nstring description = get_cp()->pconf_attributes_find(aname); if (description.empty()) description = source_description; description += " - development files"; fp->fprintf("Description: %s\n", description.c_str()); if (!devel_extended_description.empty()) { output::pointer op2 = output_wrap_open ( output_filter_dot_blank_lines::create ( output_filter_prefix::create(fp, " ") ), 79 ); op2->fputs(devel_extended_description); op2->end_of_line(); } nstring_list depends_list; nstring depends = get_cp()->pconf_attributes_find("aemakegen:debian:depends"); if (!depends.empty()) depends_list.split(depends, ",", true); depends_list.push_back("${shlibs:Depends}"); depends_list.push_back("${misc:Depends}"); depends_list.push_back ( runtime_package_name + " (= ${binary:Version})" ); depends_list.sort(); wrap_and_print(fp, "Depends", depends_list); maybe_field(fp, "breaks", developer_package_name); maybe_field(fp, "conflicts", developer_package_name); maybe_field(fp, "provides", developer_package_name); maybe_field(fp, "recommends", developer_package_name); maybe_field(fp, "replaces", developer_package_name); maybe_field(fp, "suggests", developer_package_name); } } fp.reset(); // ---------- binary package ------------------------------------------ // // The binary package (executables, man pages) // if (!binary_package_files.empty()) { nstring_list tmp; for (size_t j = 0; j < binary_package_files.size(); ++j) { nstring fn = binary_package_files[j]; if (!redundant_license_file(fn)) { // // Debian don't like you installing redundant license files. // // Note: you must remove these files here, and you will also // have to do it in aemakegen/target/debian/rules.cc as well. // tmp.push_back(expand_make_macro(fn)); } } tmp.sort(); nstring fn = "debian/" + binary_package_name + ".install"; os_become_orig(); fp = output_file::open(fn); for (size_t j = 0; j < tmp.size(); ++j) { fp->fputs(tmp[j]); fp->fputc('\n'); } fp.reset(); os_become_undo(); } // ---------- documentation package ----------------------------------- // // The documentation package. // if (!documentation_package_files.empty()) { nstring_list tmp; for (size_t j = 0; j < documentation_package_files.size(); ++j) { nstring fn = documentation_package_files[j]; if (!redundant_license_file(fn)) tmp.push_back(expand_make_macro(fn)); } tmp.sort(); nstring fn = "debian/" + documentation_package_name + ".install"; os_become_orig(); fp = output_file::open(fn); for (size_t j = 0; j < tmp.size(); ++j) { fp->fputs(tmp[j]); fp->fputc('\n'); } fp.reset(); os_become_undo(); } if (data.use_libtool()) { // ---------- runtime package ------------------------------------- // // The runtime package, for shared libraries // if (!runtime_package_files.empty()) { nstring_list tmp; for (size_t j = 0; j < runtime_package_files.size(); ++j) { nstring fn = runtime_package_files[j]; tmp.push_back(expand_make_macro(fn)); } tmp.sort(); nstring fn = "debian/" + runtime_package_name + ".install"; os_become_orig(); fp = output_file::open(fn); for (size_t j = 0; j < tmp.size(); ++j) { fp->fputs(tmp[j]); fp->fputc('\n'); } fp.reset(); os_become_undo(); } // ---------- developer package ----------------------------------- // // The developer package, for .a files, and include files, // and section 2 or 3 man pages. // if (!developer_package_files.empty()) { nstring_list tmp; for (size_t j = 0; j < developer_package_files.size(); ++j) { nstring fn = developer_package_files[j]; assert(!fn.ends_with(".la") || data.use_lib_la_files()); if (!redundant_license_file(fn)) tmp.push_back(expand_make_macro(fn)); } tmp.sort(); nstring fn = "debian/" + developer_package_name + ".install"; os_become_orig(); fp = output_file::open(fn); for (size_t j = 0; j < tmp.size(); ++j) { fp->fputs(tmp[j]); fp->fputc('\n'); } fp.reset(); os_become_undo(); } } } // vim: set ts=8 sw=4 et :