]> git.tdb.fi Git - builder.git/commitdiff
Support manually written export definition files on Windows
authorMikko Rasa <tdb@tdb.fi>
Fri, 15 Sep 2023 19:51:43 +0000 (22:51 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 15 Sep 2023 19:51:43 +0000 (22:51 +0300)
They are required to compile some third-party libraries with Builder.

plugins/gnu/gnuarchiver.cpp
plugins/gnu/gnulinker.cpp
plugins/gnu/gnulinker.h
plugins/msvc/msvcarchiver.cpp
plugins/msvc/msvclinker.cpp
plugins/msvc/msvclinker.h
source/lib/exportdefinitions.cpp
source/lib/exportdefinitions.h

index 4f216749e2c85f121ce369a861da5ba380654327..448cf429f3ad4c9d13b69099f021a97e02da309f 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdexcept>
 #include <msp/builder/builder.h>
 #include <msp/builder/component.h>
+#include <msp/builder/exportdefinitions.h>
 #include <msp/builder/objectfile.h>
 #include <msp/builder/sourcepackage.h>
 #include <msp/builder/staticlibrary.h>
@@ -23,7 +24,11 @@ GnuArchiver::GnuArchiver(Builder &b, const Architecture &a):
 Target *GnuArchiver::create_target(const vector<Target *> &sources, const string &)
 {
        vector<ObjectFile *> objs;
-       extract_sources(sources, required(objs));
+       ExportDefinitions *exp = 0;  // Unused, for compatibility with LINK
+       if(architecture->get_system()=="windows")
+               extract_sources(sources, required(objs), exp);
+       else
+               extract_sources(sources, required(objs));
 
        const Component &comp = *objs.front()->get_component();
        StaticLibrary *lib = new StaticLibrary(builder, comp, objs);
index 95e74fdc0aa314087c953f8be5aaac0db429a84a..3e61bcd95624bf16e3e4e5aaf64f1029bdeba0ef 100644 (file)
@@ -26,6 +26,8 @@ GnuLinker::GnuLinker(Builder &b, const Architecture &a):
 {
        input_suffixes.push_back(".o");
        input_suffixes.push_back(".a");
+       if(architecture->get_system()=="windows")
+               input_suffixes.push_back(".def");
 
        processing_unit = COMPONENT;
 
@@ -33,6 +35,14 @@ GnuLinker::GnuLinker(Builder &b, const Architecture &a):
        set_run_external(_run);
 }
 
+Target *GnuLinker::create_source(const Component &comp, const FS::Path &path) const
+{
+       if(FS::extpart(FS::basename(path))==".def")
+               return new ExportDefinitions(builder, comp, path);
+       else
+               return 0;
+}
+
 Target *GnuLinker::create_target(const vector<Target *> &sources, const string &arg)
 {
        if(arg=="import")
@@ -48,12 +58,20 @@ Target *GnuLinker::create_target(const vector<Target *> &sources, const string &
        }
 
        vector<ObjectFile *> objs;
-       extract_sources(sources, required(objs));
+       ExportDefinitions *exp = 0;
+       if(architecture->get_system()=="windows")
+               extract_sources(sources, required(objs), exp);
+       else
+               extract_sources(sources, required(objs));
 
        const Component &comp = *objs.front()->get_component();
        Binary *bin = 0;
        if(arg=="shared")
+       {
                bin = new SharedLibrary(builder, comp, objs);
+               if(exp)
+                       bin->add_dependency(*exp);
+       }
        else
                bin = new Executable(builder, comp, objs);
        bin->set_tool(*this);
index a669bc7be0767ea60a297ab32794a703360682b8..0089d1a42b6971b0fb25dbe3037b2156b86d5bb5 100644 (file)
@@ -15,6 +15,7 @@ class GnuLinker: public Tool
 public:
        GnuLinker(Builder &, const Architecture &);
 
+       Target *create_source(const Component &, const Msp::FS::Path &) const override;
        Target *create_target(const std::vector<Target *> &, const std::string &) override;
        Target *create_install(Target &) const override;
        std::string create_build_signature(const BuildInfo &) const override;
index b8d3d1916d5382f83337be4f9ad61300c71a5b7c..1968457d56d8e8c2cba4cf325966aa27d98d5587 100644 (file)
@@ -1,4 +1,5 @@
 #include <msp/builder/component.h>
+#include <msp/builder/exportdefinitions.h>
 #include <msp/builder/objectfile.h>
 #include <msp/builder/sourcepackage.h>
 #include <msp/builder/staticlibrary.h>
@@ -22,7 +23,8 @@ MsvcArchiver::MsvcArchiver(Builder &b, const Architecture &a, const MicrosoftToo
 Target *MsvcArchiver::create_target(const vector<Target *> &sources, const string &)
 {
        vector<ObjectFile *> objs;
-       extract_sources(sources, required(objs));
+       ExportDefinitions *exp = 0;  // Unused, for compatibility with LINK
+       extract_sources(sources, required(objs), exp);
 
        const Component &comp = *objs.front()->get_component();
        StaticLibrary *lib = new StaticLibrary(builder, comp, objs);
index a9ada9958802d36c13ba76fde7797272a2afa3bd..bd23ea315047d3441867b9d195a3ada3862e2998 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/builder/builder.h>
 #include <msp/builder/component.h>
 #include <msp/builder/executable.h>
+#include <msp/builder/exportdefinitions.h>
 #include <msp/builder/importlibrary.h>
 #include <msp/builder/installedfile.h>
 #include <msp/builder/objectfile.h>
@@ -22,6 +23,7 @@ MsvcLinker::MsvcLinker(Builder &b, const Architecture &a, const MicrosoftTools &
 {
        input_suffixes.push_back(".obj");
        input_suffixes.push_back(".lib");
+       input_suffixes.push_back(".def");
 
        processing_unit = COMPONENT;
 
@@ -29,6 +31,14 @@ MsvcLinker::MsvcLinker(Builder &b, const Architecture &a, const MicrosoftTools &
        set_run_external(_run);
 }
 
+Target *MsvcLinker::create_source(const Component &comp, const FS::Path &path) const
+{
+       if(FS::extpart(FS::basename(path))==".def")
+               return new ExportDefinitions(builder, comp, path);
+       else
+               return 0;
+}
+
 Target *MsvcLinker::create_target(const vector<Target *> &sources, const string &arg)
 {
        if(arg=="import")
@@ -45,12 +55,17 @@ Target *MsvcLinker::create_target(const vector<Target *> &sources, const string
        }
 
        vector<ObjectFile *> objs;
-       extract_sources(sources, required(objs));
+       ExportDefinitions *exp = 0;
+       extract_sources(sources, required(objs), exp);
 
        const Component &comp = *objs.front()->get_component();
        Binary *bin = 0;
        if(arg=="shared")
+       {
                bin = new SharedLibrary(builder, comp, objs);
+               if(exp)
+                       bin->add_dependency(*exp);
+       }
        else
                bin = new Executable(builder, comp, objs);
        bin->set_tool(*this);
@@ -141,6 +156,8 @@ ExternalTask::Arguments MsvcLinker::_run(const Binary &bin, FS::Path &work_dir)
 
                if(ObjectFile *obj = dynamic_cast<ObjectFile *>(tgt))
                        argv.push_back(relative(obj->get_path(), work_dir).str());
+               else if(ExportDefinitions *exp = dynamic_cast<ExportDefinitions *>(tgt))
+                       argv.push_back("/DEF:"+relative(exp->get_path(), work_dir).str());
                else if(StaticLibrary *stlib = dynamic_cast<StaticLibrary *>(tgt))
                        argv.push_back((file?file:stlib)->get_path().str());
                else if(ImportLibrary *imp = dynamic_cast<ImportLibrary *>(tgt))
index fe98c7d8501460f77d3ccb2aaa43c88d733369d8..9949695e297a2dd4c35e037f3c00af64f1d230a9 100644 (file)
@@ -14,6 +14,7 @@ private:
 public:
        MsvcLinker(Builder &, const Architecture &, const MicrosoftTools &);
 
+       Target *create_source(const Component &, const Msp::FS::Path &) const override;
        Target *create_target(const std::vector<Target *> &, const std::string &) override;
        std::string create_build_signature(const BuildInfo &) const override;
 
index 7edf7596288a9996d31a1c744e6a9abab26573aa..3b8d2a5377e3deccc8a8a76368fa7a7343bdbb0d 100644 (file)
@@ -6,10 +6,15 @@
 using namespace std;
 using namespace Msp;
 
-ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, const vector<ObjectFile *> &objs):
-       FileTarget(b, c.get_package(), generate_target_path(c))
+ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, const FS::Path &p):
+       FileTarget(b, c.get_package(), p)
 {
        component = &c;
+}
+
+ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, const vector<ObjectFile *> &objs):
+       ExportDefinitions(b, c, generate_target_path(c))
+{
        for(ObjectFile *o: objs)
                add_dependency(*o);
 }
index 0535d6359415e63e2152c3e9791b9fdf79a7b373..97630c786460210ebd41a8426e8d924e7d7e60c5 100644 (file)
@@ -12,6 +12,7 @@ An export definition file for a shared library.  Only used on Windows.
 class LIBBUILDER_API ExportDefinitions: public FileTarget
 {
 public:
+       ExportDefinitions(Builder &, const Component &, const Msp::FS::Path &);
        ExportDefinitions(Builder &, const Component &, const std::vector<ObjectFile *> &);
 private:
        static Msp::FS::Path generate_target_path(const Component &);