]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Make tools capable of reporting a system-wide path used to locate input files
[builder.git] / source / builder.cpp
index bd1ee1aa82b523c450faeb6c72357e9d6651fc8d..e8f8927d580ea0e2739aadf1bd32b055f420e1a5 100644 (file)
 #include "binarypackage.h"
 #include "builder.h"
 #include "copy.h"
+#include "externaltask.h"
 #include "gnuarchiver.h"
 #include "gnuccompiler.h"
 #include "gnucxxcompiler.h"
 #include "gnulinker.h"
-#include "header.h"
-#include "install.h"
-#include "misc.h"
+#include "installedfile.h"
 #include "package.h"
-#include "pkgconfig.h"
+#include "pkgconfigfile.h"
 #include "pkgconfiggenerator.h"
 #include "sharedlibrary.h"
 #include "sourcepackage.h"
-#include "systemlibrary.h"
 #include "tar.h"
 #include "task.h"
 #include "virtualtarget.h"
@@ -127,14 +125,6 @@ Builder::Builder(int argc, char **argv):
 
        cwd = FS::getcwd();
 
-       toolchain.add_tool(new GnuCCompiler(*this));
-       toolchain.add_tool(new GnuCxxCompiler(*this));
-       toolchain.add_tool(new GnuLinker(*this));
-       toolchain.add_tool(new GnuArchiver(*this));
-       toolchain.add_tool(new Copy(*this));
-       toolchain.add_tool(new Tar(*this));
-       toolchain.add_tool(new PkgConfigGenerator(*this));
-
        load_build_file((FS::get_sys_data_dir(argv[0], "builder")/"builderrc").str());
        load_build_file((FS::get_user_data_dir("builder")/"rc").str());
 
@@ -153,6 +143,14 @@ Builder::Builder(int argc, char **argv):
                        }
        }
 
+       toolchain.add_tool(new GnuCCompiler(*this));
+       toolchain.add_tool(new GnuCxxCompiler(*this));
+       toolchain.add_tool(new GnuLinker(*this));
+       toolchain.add_tool(new GnuArchiver(*this));
+       toolchain.add_tool(new Copy(*this));
+       toolchain.add_tool(new Tar(*this));
+       toolchain.add_tool(new PkgConfigGenerator(*this));
+
        if(prfx.empty())
        {
                if(current_arch->is_native())
@@ -270,7 +268,7 @@ int Builder::main()
                                if(j->second->get_package()==i->second)
                                {
                                        ++count;
-                                       if(j->second->get_rebuild())
+                                       if(j->second->needs_rebuild())
                                                ++to_be_built;
                                }
                        if(count)
@@ -307,7 +305,7 @@ int Builder::main()
 
 string Builder::run_pkgconfig(const string &pkg, const string &what)
 {
-       list<string> argv;
+       ExternalTask::Arguments argv;
        argv.push_back("pkg-config");
        if(what=="cflags" || what=="libs")
                argv.push_back("--"+what);
@@ -323,12 +321,17 @@ string Builder::run_pkgconfig(const string &pkg, const string &what)
        if(verbose>=4)
                IO::print("Running %s\n", join(argv.begin(), argv.end()));
 
-       int status;
-       string res = run_command(argv, &status);
-       if(status)
+       ExternalTask task(argv);
+       task.set_stdout(ExternalTask::CAPTURE);
+       task.set_stderr(ExternalTask::IGNORE);
+       task.start();
+       Task::Status status;
+       while((status=task.check())==Task::RUNNING)
+               Time::sleep(10*Time::msec);
+       if(status==Task::ERROR)
                throw runtime_error(format("pkg-config for package %s failed", pkg));
 
-       return res;
+       return task.get_output();
 }
 
 Package *Builder::get_package(const string &name)
@@ -506,22 +509,13 @@ int Builder::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));
+                       PkgConfigFile *pc = new PkgConfigFile(*this, *spkg);
+                       install->add_depend(toolchain.get_tool("CP").create_target(*pc));
                }
        }
 
-       // 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
+       // XXX This does not currently work with targets found during dependency discovery
        for(StringList::iterator i=what_if.begin(); i!=what_if.end(); ++i)
        {
                FileTarget *tgt = vfs.get_target(cwd/ *i);
@@ -566,7 +560,7 @@ int Builder::do_build()
 
        unsigned total = 0;
        for(map<string, Target *>::const_iterator i=targets.begin(); i!=targets.end(); ++i)
-               if(i->second->is_buildable() && i->second->get_rebuild())
+               if(i->second->is_buildable() && i->second->needs_rebuild())
                        ++total;
 
        if(!total)
@@ -592,10 +586,23 @@ int Builder::do_build()
                        if(tgt)
                        {
                                if(tgt->get_tool())
-                                       IO::print("[%-10s] [%-4s] %s\n", tgt->get_package()->get_name(), tgt->get_tool()->get_tag(), tgt->get_name());
+                                       IO::print("%-4s  %s\n", tgt->get_tool()->get_tag(), tgt->get_name());
                                Task *task = tgt->build();
                                if(task)
-                                       tasks.push_back(task);
+                               {
+                                       if(verbose>=2)
+                                               IO::print("%s\n", task->get_command());
+                                       if(dry_run)
+                                       {
+                                               task->signal_finished.emit(true);
+                                               delete task;
+                                       }
+                                       else
+                                       {
+                                               task->start();
+                                               tasks.push_back(task);
+                                       }
+                               }
 
                                if(show_progress)
                                        IO::print("%d of %d target%s built\033[1G", count, total, (total!=1 ? "s" : ""));
@@ -640,7 +647,7 @@ int Builder::do_clean()
        // Cleaning doesn't care about ordering, so a simpler method can be used
 
        set<Target *> clean_tgts;
-       TargetList queue;
+       list<Target *> queue;
        queue.push_back(get_target("cmdline"));
 
        while(!queue.empty())
@@ -651,15 +658,16 @@ int Builder::do_clean()
                if(tgt->is_buildable() && (tgt->get_package()==main_pkg || clean>=2))
                        clean_tgts.insert(tgt);
 
-               const TargetList &deps = tgt->get_depends();
-               for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
+               const Target::Dependencies &deps = tgt->get_depends();
+               for(list<Target *>::const_iterator i=deps.begin(); i!=deps.end(); ++i)
                        if(!clean_tgts.count(*i))
                                queue.push_back(*i);
        }
 
        for(set<Target *>::iterator i=clean_tgts.begin(); i!=clean_tgts.end(); ++i)
                if(FileTarget *ft = dynamic_cast<FileTarget *>(*i))
-                       unlink(ft->get_path());
+                       if(ft->get_mtime())
+                               FS::unlink(ft->get_path());
 
        return 0;
 }