add DEPENDABLE_HEADER_DIRS
This commit is contained in:
parent
35f40e8c2a
commit
8560437033
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ****************/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue