- Target *install=new VirtualTarget(*this, "install");
- world->add_depend(install);
-
- Target *tarballs=new VirtualTarget(*this, "tarballs");
- world->add_depend(tarballs);
-
- PackageList all_reqs=main_pkg->collect_requires();
- for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
- {
- SourcePackage *spkg=dynamic_cast<SourcePackage *>(*i);
- if(!spkg)
- continue;
-
- const ComponentList &components=spkg->get_components();
- for(ComponentList::const_iterator j=components.begin(); j!=components.end(); ++j)
- j->create_targets();
-
- if(spkg->get_install_flags()&(SourcePackage::LIB|SourcePackage::INCLUDE))
- {
- PkgConfig *pc=new PkgConfig(*this, *spkg);
- install->add_depend(new Install(*this, *spkg, *pc));
- }
-
- tarballs->add_depend(new TarBall(*this, *spkg));
- }
-
- // Find dependencies until no new targets are created
- while(!new_tgts.empty())
- {
- Target *tgt=new_tgts.front();
- new_tgts.erase(new_tgts.begin());
- tgt->find_depends();
- if(!tgt->get_depends_ready())
- new_tgts.push_back(tgt);
- }
-
- // Apply what-ifs
- for(StringList::iterator i=what_if.begin(); i!=what_if.end(); ++i)
- {
- Target *tgt=get_target((cwd/ *i).str());
- if(!tgt)
- {
- cerr<<"Unknown what-if target "<<*i<<'\n';
- return -1;
- }
- tgt->touch();
- }
-
- // Make the cmdline target depend on all targets mentioned on the command line
- Target *cmdline=new VirtualTarget(*this, "cmdline");
- bool build_world=false;
- for(list<string>::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ++i)
- {
- Target *tgt=get_target(*i);
- if(!tgt)
- tgt=get_target((cwd/ *i).str());
- if(!tgt)
- {
- cerr<<"I don't know anything about "<<*i<<'\n';
- return -1;
- }
- if(tgt==world)
- build_world=true;
- cmdline->add_depend(tgt);
- }
-
- /* If world is to be built, prepare cmdline. If not, add cmdline to world
- and prepare world. I don't really like this, but it keeps the graph
- acyclic. */
- if(build_world)
- cmdline->prepare();
- else
- {
- world->add_depend(cmdline);
- world->prepare();
- }
-
- for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
- if(SourcePackage *spkg=dynamic_cast<SourcePackage *>(i->second))
- spkg->get_deps_cache().save();
-
- return 0;
-}
-
-/**
-Check if a header exists, either as a target or a file. Either an existing
-target or a new SystemHeader target will be returned.
-*/
-Target *Builder::get_header(const Msp::Path::Path &fn)
-{
- Target *tgt=get_target(fn.str());
- if(tgt) return tgt;
-
- if(Path::exists(fn))
- {
- tgt=new SystemHeader(*this, fn.str());
- return tgt;
- }
- return 0;
-}
-
-Target *Builder::get_library(const string &lib, const string &arch, const Path::Path &path, LibMode mode)
-{
- // Populate a list of candidate filenames
- StringList candidates;
-
- if(mode!=ALL_STATIC)
- {
- if(arch=="win32")
- candidates.push_back("lib"+lib+".dll");
- else
- candidates.push_back("lib"+lib+".so");
- }
-
- /* Static libraries are always considered, since sometimes shared versions
- may not be available */
- candidates.push_back("lib"+lib+".a");
- if(arch=="win32")
- candidates.push_back("lib"+lib+".dll.a");
-
- for(StringList::iterator i=candidates.begin(); i!=candidates.end(); ++i)
- {
- string full=(path/ *i).str();
- Target *tgt=get_target(full);
-
- if(tgt)
- {
- Target *real_tgt=tgt;
- if(dynamic_cast<Install *>(tgt))
- real_tgt=real_tgt->get_depends().front();
-
- /* Ignore dynamic libraries from local packages unless library mode is
- DYNAMIC */
- if(dynamic_cast<SharedLibrary *>(real_tgt) && mode!=DYNAMIC)
- continue;
- else if(tgt)
- return tgt;
- }
- else if(Path::exists(full))
- {
- tgt=new SystemLibrary(*this, full);
- return tgt;
- }
- }
-
- return 0;
-}
-
-/**
-Updates a hash with a string. This is used from get_header and get_library.
-*/
-void Builder::update_hash(string &hash, const string &value)
-{
- for(unsigned i=0; i<value.size(); ++i)
- hash[i%hash.size()]^=value[i];
-}
-
-/**
-This function supervises the build process, starting new actions when slots
-become available.
-*/
-int Builder::do_build()
-{
- Target *cmdline=get_target("cmdline");
-
- unsigned total=cmdline->count_rebuild();