Attached is a little C++ program to extract global dependency info from the .deps database.
Compile with the equivalent of: $ SRCTREE=../devel; BUILDTREE=../devel/build; $ g++ -I${SRCTREE}/boost -I${SRCTREE}/src -o collect_deps collect_deps.C -L${BUILDTREE}/src/support/.libs -lsupport -L${BUILDTREE}/boost/libs/regex/src/.libs -lboostregex Run like: $ ./collect_deps `find ${BUILDTREE}/src/ -name "*.o"` | sort -n -r | less Gives the output below. I think it is fair to say that 88 object files really _shouldn't_ depend on Bullets.h... 625 dependencies on support/std_string.h 535 dependencies on config.h 277 dependencies on LColor.h 274 dependencies on support/std_ostream.h 253 dependencies on support/DebugStream.h 253 dependencies on debug.h 248 dependencies on lyxlength.h 229 dependencies on gettext.h 217 dependencies on insets/insetbase.h 215 dependencies on dimension.h 214 dependencies on lyxfont.h 154 dependencies on support/lstrings.h 151 dependencies on ParagraphList_fwd.h 150 dependencies on insets/inset.h 140 dependencies on support/types.h 131 dependencies on layout.h 130 dependencies on frontends/qt2/qt_helpers.h 129 dependencies on frontends/controllers/Kernel.h 128 dependencies on frontends/controllers/Dialog.h 119 dependencies on paper.h 111 dependencies on graphics/GraphicsTypes.h 109 dependencies on lyxlayout_ptr_fwd.h 106 dependencies on lfuns.h 105 dependencies on frontends/xforms/forms_fwd.h 104 dependencies on lyxgluelength.h 104 dependencies on frontends/mouse_state.h 101 dependencies on vspace.h 97 dependencies on frontends/controllers/ButtonPolicies.h 92 dependencies on Spacing.h 92 dependencies on frontends/controllers/BCView.tmpl 92 dependencies on frontends/controllers/BCView.h 89 dependencies on lyxlayout.h 89 dependencies on InsetList.h 88 dependencies on Bullet.h 87 dependencies on metricsinfo.h 87 dependencies on lyxtextclass.h 87 dependencies on frontends/xforms/fdesign_base.h 87 dependencies on BranchList.h 86 dependencies on support/filetools.h 85 dependencies on support/LAssert.h 85 dependencies on author.h 84 dependencies on insets/insetquotes.h 84 dependencies on bufferparams.h 81 dependencies on RowList_fwd.h 77 dependencies on texrow.h 74 dependencies on support/limited_stack.h 74 dependencies on mathed/math_inset.h 73 dependencies on lyxvc.h 73 dependencies on buffer.h 72 dependencies on lyxcursor.h 72 dependencies on funcrequest.h 71 dependencies on bufferview_funcs.h 71 dependencies on box.h -- Angus--nextPart6146248.53BEXn27C3 Content-Type: text/x-csrc; name="collect_deps.C" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="collect_deps.C" #include "lyx_main.h" #include "support/FileInfo.h" #include "support/filetools.h" #include "support/lstrings.h" #include <boost/tuple/tuple.hpp> #include <cassert> #include <exception> #include <fstream> #include <iostream> #include <map> #include <string> #include <utility> #include <vector> std::ostream & lyxerr = std::cerr; using std::make_pair; using std::map; using std::pair; using std::string; using std::vector; namespace support = lyx::support; int usage(char const * name); pair<string, string> const get_dependency_file(string const & obj_file); vector<string> const extract_dependencies(string const & dep_file, string const & obj_file); typedef map<string, int> DepMap; void build_local_dependency_map(vector<string> const & data, DepMap & dep_map); int main(int argc, char * argv[]) { if (argc < 2) return usage(argv[0]); typedef char const * const * const_charstring_iterator; const_charstring_iterator obj_files_begin = &argv[1]; const_charstring_iterator obj_files_end = &argv[0] + argc; DepMap dep_map; for (const_charstring_iterator it = obj_files_begin; it != obj_files_end; ++it) { string dep_file; string obj_file; boost::tie(dep_file, obj_file) = get_dependency_file(*it); if (dep_file.empty()) continue; vector<string> const data = extract_dependencies(dep_file, obj_file); if (data.empty()) continue; build_local_dependency_map(data, dep_map); } DepMap::const_iterator dit = dep_map.begin(); DepMap::const_iterator dend = dep_map.end(); for (; dit != dend; ++dit) { std::cout << dit->second << " dependencies on " << dit->first << '\n'; } std::flush(std::cout); return 0; } int usage(char const * name) { std::cerr << "Usage: " << name << " <list of object files>\n"; return 1; } pair<string, string> const get_dependency_file(string const & obj_file) { pair<string, string> const empty; if (!support::IsFileReadable(obj_file)) { std::cerr << "Cannot find \"" << obj_file << "\".\n"; return empty; } string const ext = support::GetExtension(obj_file); string const filename = support::OnlyFilename(obj_file); if (ext != "o") { std::cerr << "Expecting .o files, not " << filename << ".\n"; return empty; } string const dir = support::OnlyPath(obj_file); if (!support::FileInfo(dir).isDir()) { std::cerr << '"' << dir << "\" is not a directory.\n"; return empty; } string const deps_dir = support::AddPath(dir, ".deps"); if (!support::FileInfo(deps_dir).isDir()) { std::cerr << '"' << deps_dir << "\" is not a directory.\n"; return empty; } string const filebase = support::ChangeExtension(obj_file, string()); string const lo_file = filebase + ".lo"; string obj_file_out; string dep_file; if (support::IsFileReadable(lo_file)) { obj_file_out = support::OnlyFilename(lo_file); dep_file = support::ChangeExtension(filename, ".Plo"); } else { obj_file_out = filename; dep_file = support::ChangeExtension(filename, ".Po"); } dep_file = support::AddName(deps_dir, dep_file); return make_pair(dep_file, obj_file_out); } vector<string> const extract_dependencies(string const & dep_file, string const & obj_file) { using std::getline; using support::ltrim; using support::prefixIs; using support::split; vector<string> data; std::ifstream ifs(dep_file.c_str()); if (!ifs.good()) { std::cerr << "Unable to open \"" << dep_file << "\".\n"; return data; } bool found_start = false; bool the_end = false; while (ifs.good()) { string line; std::getline(ifs, line); ltrim(line); if (prefixIs(line, obj_file)) { found_start = true; line = ltrim(split(line, ':')); } if (found_start) { while (1) { string entry; line = ltrim(split(line, entry, ' ')); if (!entry.empty() && entry != "\\") data.push_back(entry); if (line.empty()) { if (entry != "\\") the_end = true; break; } } } if (the_end) break; } return data; } void build_local_dependency_map(vector<string> const & data, DepMap & dep_map) { using support::contains; using support::prefixIs; vector<string>::const_iterator it = data.begin(); vector<string>::const_iterator end = data.end(); for (; it != end; ++it) { if (!prefixIs(*it, ".")) continue; if (contains(*it, "boost/")) continue; string::size_type const pos = it->find("src/"); string const entry = pos == string::npos ? *it : it->substr(pos+4); DepMap::iterator mit = dep_map.find(entry); if (mit == dep_map.end()) dep_map[entry] = 1; else mit->second += 1; } } namespace boost { void throw_exception(std::exception const & e) { std::cerr << "Exception caught:\n" << e.what() << std::endl; assert(false); } } string const _(string const & str) { return str; } void LyX::emergencyCleanup() {}