add DEPENDABLE_HEADER_DIRS

This commit is contained in:
David Rose 2004-09-29 16:45:39 +00:00
parent 35f40e8c2a
commit 8560437033
10 changed files with 227 additions and 19 deletions

View File

@ -154,6 +154,13 @@ $DTOOL/pptempl/System.pp:
Like $[DEPEND_DIRS], this is set by the $[DEPENDS_FILE] script,
and has a different value within each source directory.
$[DEPENDABLE_HEADER_DIRS] - the list of directories outside of the
current source tree in which additional header files ("dependable
headers") may be found. This is used to implement inter-package
dependencies. Any files found in the directories named here are
deemed to be dependable headers, and the $[depdencies] variable
will include these files.
The following functions are built into the ppremake executable. In
general, these operate on one word or a group of words separated by

View File

@ -86,5 +86,5 @@
** Also be sure to change the version number **
** at the beginning of configure.in. **
**************** ****************/
#define VERSION "1.16"
#define VERSION "1.17"
/**************** UPDATE VERSION NUMBER HERE ****************/

View File

@ -5,7 +5,7 @@ dnl **************** UPDATE VERSION NUMBER HERE ****************
dnl ** Also be sure to change the version number **
dnl ** at the end of config_msvc.h. **
dnl **************** ****************
AM_INIT_AUTOMAKE(ppremake, 1.16)
AM_INIT_AUTOMAKE(ppremake, 1.17)
dnl **************** UPDATE VERSION NUMBER HERE ****************
AM_CONFIG_HEADER(config.h)

View File

@ -73,7 +73,7 @@ update_from_cache(const vector<string> &words) {
time_t mtime = strtol(words[1].c_str(), (char **)NULL, 10);
if (mtime == get_mtime()) {
// The modification matches; preserve the cache information.
PPDirectoryTree *tree = _directory->get_tree();
PPDirectoryTree *tree = _directory->get_tree()->get_main_tree();
_dependencies.clear();
vector<string>::const_iterator wi;
@ -173,6 +173,16 @@ get_pathname() const {
return _directory->get_path() + "/" + _filename;
}
////////////////////////////////////////////////////////////////////
// Function: PPDependableFile::get_fullpath
// Access: Public
// Description: Returns the full pathname to this particular filename.
////////////////////////////////////////////////////////////////////
string PPDependableFile::
get_fullpath() const {
return _directory->get_fullpath() + "/" + _filename;
}
////////////////////////////////////////////////////////////////////
// Function: PPDependableFile::get_dirpath
// Access: Public
@ -351,19 +361,19 @@ compute_dependencies(string &circularity) {
if ((_flags & F_from_cache) == 0) {
// Now open the file and scan it for #include statements.
ifstream in(get_pathname().c_str());
ifstream in(get_fullpath().c_str());
if (!in) {
// Can't read the file, or the file doesn't exist. Interesting.
if (exists()) {
cerr << "Warning: dependent file " << get_pathname()
cerr << "Warning: dependent file " << get_fullpath()
<< " exists but cannot be read.\n";
} else {
cerr << "Warning: dependent file " << get_pathname()
cerr << "Warning: dependent file " << get_fullpath()
<< " does not exist.\n";
}
} else {
PPDirectoryTree *tree = _directory->get_tree();
PPDirectoryTree *tree = _directory->get_tree()->get_main_tree();
bool okcircular = false;
string line;
@ -442,7 +452,7 @@ stat_file() {
_flags |= F_statted;
struct stat st;
Filename pathname(get_pathname());
Filename pathname(get_fullpath());
string ospath = pathname.to_os_specific();
if (stat(ospath.c_str(), &st) < 0) {
// The file doesn't exist!

View File

@ -35,6 +35,7 @@ public:
PPDirectory *get_directory() const;
const string &get_filename() const;
string get_pathname() const;
string get_fullpath() const;
string get_dirpath() const;
bool exists();

View File

@ -179,6 +179,20 @@ get_path() const {
return _parent->get_path() + "/" + _dirname;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectory::get_fullpath
// Access: Public
// Description: Returns the full path to this particular directory.
// This does not include a trailing slash.
////////////////////////////////////////////////////////////////////
string PPDirectory::
get_fullpath() const {
if (_parent == (PPDirectory *)NULL) {
return _tree->get_fullpath();
}
return _tree->get_fullpath() + "/" + get_path();
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectory::get_rel_to
// Access: Public
@ -194,6 +208,11 @@ get_rel_to(const PPDirectory *other) const {
return ".";
}
if (a->_tree != b->_tree) {
// If they're in different trees, just return the full path to b.
return b->get_fullpath();
}
string prefix, postfix;
while (a->_depth > b->_depth) {
prefix += "../";
@ -332,14 +351,31 @@ get_dependable_file(const string &filename, bool is_header) {
_dependables.insert(Dependables::value_type(filename, dependable));
if (is_header) {
bool unique = _tree->_dependables.insert
PPDirectoryTree *main_tree = _tree->get_main_tree();
bool unique = main_tree->_dependables.insert
(PPDirectoryTree::Dependables::value_type(filename, dependable)).second;
if (!unique) {
cerr << "Warning: source file " << dependable->get_pathname()
<< " may be confused with "
<< _tree->find_dependable_file(filename)->get_pathname()
<< ".\n";
PPDependableFile *other = main_tree->find_dependable_file(filename);
if (_tree != main_tree) {
// Both files are in external dependable trees.
cerr << "Warning: header file " << dependable->get_fullpath()
<< " may be confused with " << other->get_fullpath()
<< ".\n";
} else if (other->get_directory()->get_tree() != _tree) {
// This file is a source file in this tree, while the other
// one is an external file.
cerr << "Warning: source file " << dependable->get_pathname()
<< " may be confused with " << other->get_fullpath()
<< ".\n";
} else {
// Both files are within the same source tree.
cerr << "Warning: source file " << dependable->get_pathname()
<< " may be confused with " << other->get_pathname()
<< ".\n";
}
}
}
@ -397,7 +433,8 @@ report_reverse_depends() const {
////////////////////////////////////////////////////////////////////
// Function: PPDirectory::r_scan
// Access: Private
// Description: The recursive implementation of scan_source().
// Description: The recursive implementation of
// PPDirectoryTree::scan_source().
////////////////////////////////////////////////////////////////////
bool PPDirectory::
r_scan(const string &prefix) {
@ -406,8 +443,7 @@ r_scan(const string &prefix) {
root_name = prefix.substr(0, prefix.length() - 1);
}
// Collect all the filenames in the directory in this vector first,
// so we can sort them.
// Collect all the filenames in the directory in this vector first.
vector<string> filenames;
if (!root_name.scan_directory(filenames)) {
cerr << "Unable to scan directory " << root_name << "\n";
@ -436,6 +472,38 @@ r_scan(const string &prefix) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectory::scan_extra_depends
// Access: Private
// Description: The recursive implementation of
// PPDirectoryTree::scan_extra_depends(). This simply
// adds each *.h or *.I file in the directory as a
// dependable file. It is assumed to be called for an
// external directory named by DEPENDABLE_HEADER_DIRS.
////////////////////////////////////////////////////////////////////
bool PPDirectory::
scan_extra_depends(const string &cache_filename) {
Filename root_name = get_fullpath();
vector<string> filenames;
if (!root_name.scan_directory(filenames)) {
cerr << "Unable to scan directory " << root_name << "\n";
return false;
}
vector<string>::const_iterator fi;
for (fi = filenames.begin(); fi != filenames.end(); ++fi) {
string filename = (*fi);
if (!filename.empty() && filename[0] != '.' &&
filename != cache_filename) {
get_dependable_file(filename, true);
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectory::read_source_file
// Access: Private
@ -690,7 +758,7 @@ update_file_dependencies(const string &cache_filename) {
} else {
// Open up the dependency cache file in the directory.
Filename cache_pathname(get_path(), cache_filename);
Filename cache_pathname(get_fullpath(), cache_filename);
cache_pathname.set_text();
cache_pathname.unlink();

View File

@ -38,6 +38,7 @@ public:
const string &get_dirname() const;
int get_depends_index() const;
string get_path() const;
string get_fullpath() const;
string get_rel_to(const PPDirectory *other) const;
PPCommandFile *get_source() const;
@ -58,6 +59,7 @@ private:
typedef set<PPDirectory *> Depends;
bool r_scan(const string &prefix);
bool scan_extra_depends(const string &cache_filename);
bool read_source_file(const string &prefix, PPNamedScopes *named_scopes);
bool read_depends_file(PPNamedScopes *named_scopes);
bool resolve_dependencies();

View File

@ -5,6 +5,7 @@
#include "ppDirectoryTree.h"
#include "ppDirectory.h"
#include "tokenize.h"
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::Constructor
@ -12,7 +13,13 @@
// Description:
////////////////////////////////////////////////////////////////////
PPDirectoryTree::
PPDirectoryTree() {
PPDirectoryTree(PPDirectoryTree *main_tree) {
if (main_tree == NULL) {
_main_tree = this;
} else {
_main_tree = main_tree;
}
_root = new PPDirectory(this);
}
@ -24,6 +31,35 @@ PPDirectoryTree() {
PPDirectoryTree::
~PPDirectoryTree() {
delete _root;
RelatedTrees::iterator ri;
for (ri = _related_trees.begin(); ri != _related_trees.end(); ++ri) {
delete (*ri);
}
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::get_main_tree
// Access: Public
// Description: Returns the PPDirectoryTree that represents the
// actual source hierarchy. If the return value is
// something other than this, it indicates that this
// tree is an external dependable tree.
////////////////////////////////////////////////////////////////////
PPDirectoryTree *PPDirectoryTree::
get_main_tree() {
return _main_tree;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::set_fullpath
// Access: Public
// Description: Indicates the full path to the root of this
// particular tree.
////////////////////////////////////////////////////////////////////
void PPDirectoryTree::
set_fullpath(const string &fullpath) {
_fullpath = fullpath;
}
////////////////////////////////////////////////////////////////////
@ -64,6 +100,52 @@ scan_depends(PPNamedScopes *named_scopes) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::scan_extra_depends
// Access: Public
// Description: Accepts the value of DEPENDABLE_HEADER_DIRS, which
// was presumably set by the various Config.pp and/or
// Depends.pp scripts that were read in, and treats each
// named filename there as the name of a directory that
// contains header files in a separate but related tree,
// for which we also need to generate dependency rules
// in this tree.
////////////////////////////////////////////////////////////////////
bool PPDirectoryTree::
scan_extra_depends(const string &dependable_header_dirs,
const string &cache_filename) {
bool okflag = true;
vector<string> dirnames;
tokenize_whitespace(dependable_header_dirs, dirnames);
// Sort dirnames and remove duplicates.
sort(dirnames.begin(), dirnames.end());
dirnames.erase(unique(dirnames.begin(), dirnames.end()), dirnames.end());
vector<string>::const_iterator ni;
for (ni = dirnames.begin(); ni != dirnames.end(); ++ni) {
string dirname = (*ni);
if (dirname[0] != '/') {
// Insist that the external dirname be a full pathname.
dirname = _fullpath + "/" + dirname;
}
// Now we need to make up a different tree for each external
// dirname.
PPDirectoryTree *tree = new PPDirectoryTree(this);
tree->set_fullpath(dirname);
_related_trees.push_back(tree);
if (!tree->get_root()->scan_extra_depends(cache_filename)) {
okflag = false;
}
}
return okflag;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::count_source_files
// Access: Public
@ -85,6 +167,16 @@ get_root() const {
return _root;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::get_fullpath
// Access: Public
// Description: Returns the full path to the root of the tree.
////////////////////////////////////////////////////////////////////
const string &PPDirectoryTree::
get_fullpath() const {
return _fullpath;
}
////////////////////////////////////////////////////////////////////
// Function: PPDirectoryTree::get_complete_tree
// Access: Public
@ -197,5 +289,10 @@ read_file_dependencies(const string &cache_filename) {
void PPDirectoryTree::
update_file_dependencies(const string &cache_filename) {
_root->update_file_dependencies(cache_filename);
RelatedTrees::iterator ri;
for (ri = _related_trees.begin(); ri != _related_trees.end(); ++ri) {
(*ri)->update_file_dependencies(cache_filename);
}
}

View File

@ -9,6 +9,7 @@
#include "ppremake.h"
#include <map>
#include <vector>
class PPNamedScopes;
class PPDirectory;
@ -23,14 +24,20 @@ class PPDependableFile;
////////////////////////////////////////////////////////////////////
class PPDirectoryTree {
public:
PPDirectoryTree();
PPDirectoryTree(PPDirectoryTree *main_tree = NULL);
~PPDirectoryTree();
PPDirectoryTree *get_main_tree();
void set_fullpath(const string &fullpath);
bool scan_source(PPNamedScopes *named_scopes);
bool scan_depends(PPNamedScopes *named_scopes);
bool scan_extra_depends(const string &dependable_header_dirs,
const string &cache_filename);
int count_source_files() const;
PPDirectory *get_root() const;
const string &get_fullpath() const;
string get_complete_tree() const;
@ -44,7 +51,9 @@ public:
void update_file_dependencies(const string &cache_filename);
private:
PPDirectoryTree *_main_tree;
PPDirectory *_root;
string _fullpath;
typedef map<string, PPDirectory *> Dirnames;
Dirnames _dirnames;
@ -52,6 +61,9 @@ private:
typedef map<string, PPDependableFile *> Dependables;
Dependables _dependables;
typedef vector<PPDirectoryTree *> RelatedTrees;
RelatedTrees _related_trees;
friend class PPDirectory;
};

View File

@ -116,11 +116,13 @@ read_source(const string &root) {
}
_root = get_cwd();
_tree.set_fullpath(_root);
cerr << "Root is " << _root << "\n";
_def_scope = new PPScope(&_named_scopes);
_def_scope->define_variable("PACKAGEFILE", package_file);
_def_scope->define_variable("TOPDIR", _root);
_def_scope->define_variable("DEPENDABLE_HEADER_DIRS", "");
_defs = new PPCommandFile(_def_scope);
if (!_defs->read_file(PACKAGE_FILENAME)) {
@ -165,6 +167,15 @@ read_source(const string &root) {
return false;
}
string dependable_header_dirs =
_def_scope->expand_variable("DEPENDABLE_HEADER_DIRS");
string cache_filename =
_def_scope->expand_variable("DEPENDENCY_CACHE_FILENAME");
if (!_tree.scan_extra_depends(dependable_header_dirs, cache_filename)) {
return false;
}
return true;
}