From 2e33e7882d1c389f6386b69ecbaa3993abd9e9ec Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 15 Sep 2023 22:51:43 +0300 Subject: [PATCH] Support manually written export definition files on Windows They are required to compile some third-party libraries with Builder. --- plugins/gnu/gnuarchiver.cpp | 7 ++++++- plugins/gnu/gnulinker.cpp | 20 +++++++++++++++++++- plugins/gnu/gnulinker.h | 1 + plugins/msvc/msvcarchiver.cpp | 4 +++- plugins/msvc/msvclinker.cpp | 19 ++++++++++++++++++- plugins/msvc/msvclinker.h | 1 + source/lib/exportdefinitions.cpp | 9 +++++++-- source/lib/exportdefinitions.h | 1 + 8 files changed, 56 insertions(+), 6 deletions(-) diff --git a/plugins/gnu/gnuarchiver.cpp b/plugins/gnu/gnuarchiver.cpp index 4f21674..448cf42 100644 --- a/plugins/gnu/gnuarchiver.cpp +++ b/plugins/gnu/gnuarchiver.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,11 @@ GnuArchiver::GnuArchiver(Builder &b, const Architecture &a): Target *GnuArchiver::create_target(const vector &sources, const string &) { vector 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); diff --git a/plugins/gnu/gnulinker.cpp b/plugins/gnu/gnulinker.cpp index 95e74fd..3e61bcd 100644 --- a/plugins/gnu/gnulinker.cpp +++ b/plugins/gnu/gnulinker.cpp @@ -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 &sources, const string &arg) { if(arg=="import") @@ -48,12 +58,20 @@ Target *GnuLinker::create_target(const vector &sources, const string & } vector 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); diff --git a/plugins/gnu/gnulinker.h b/plugins/gnu/gnulinker.h index a669bc7..0089d1a 100644 --- a/plugins/gnu/gnulinker.h +++ b/plugins/gnu/gnulinker.h @@ -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 &, const std::string &) override; Target *create_install(Target &) const override; std::string create_build_signature(const BuildInfo &) const override; diff --git a/plugins/msvc/msvcarchiver.cpp b/plugins/msvc/msvcarchiver.cpp index b8d3d19..1968457 100644 --- a/plugins/msvc/msvcarchiver.cpp +++ b/plugins/msvc/msvcarchiver.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -22,7 +23,8 @@ MsvcArchiver::MsvcArchiver(Builder &b, const Architecture &a, const MicrosoftToo Target *MsvcArchiver::create_target(const vector &sources, const string &) { vector 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); diff --git a/plugins/msvc/msvclinker.cpp b/plugins/msvc/msvclinker.cpp index a9ada99..bd23ea3 100644 --- a/plugins/msvc/msvclinker.cpp +++ b/plugins/msvc/msvclinker.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -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 &sources, const string &arg) { if(arg=="import") @@ -45,12 +55,17 @@ Target *MsvcLinker::create_target(const vector &sources, const string } vector 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(tgt)) argv.push_back(relative(obj->get_path(), work_dir).str()); + else if(ExportDefinitions *exp = dynamic_cast(tgt)) + argv.push_back("/DEF:"+relative(exp->get_path(), work_dir).str()); else if(StaticLibrary *stlib = dynamic_cast(tgt)) argv.push_back((file?file:stlib)->get_path().str()); else if(ImportLibrary *imp = dynamic_cast(tgt)) diff --git a/plugins/msvc/msvclinker.h b/plugins/msvc/msvclinker.h index fe98c7d..9949695 100644 --- a/plugins/msvc/msvclinker.h +++ b/plugins/msvc/msvclinker.h @@ -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 &, const std::string &) override; std::string create_build_signature(const BuildInfo &) const override; diff --git a/source/lib/exportdefinitions.cpp b/source/lib/exportdefinitions.cpp index 7edf759..3b8d2a5 100644 --- a/source/lib/exportdefinitions.cpp +++ b/source/lib/exportdefinitions.cpp @@ -6,10 +6,15 @@ using namespace std; using namespace Msp; -ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, const vector &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 &objs): + ExportDefinitions(b, c, generate_target_path(c)) +{ for(ObjectFile *o: objs) add_dependency(*o); } diff --git a/source/lib/exportdefinitions.h b/source/lib/exportdefinitions.h index 0535d63..97630c7 100644 --- a/source/lib/exportdefinitions.h +++ b/source/lib/exportdefinitions.h @@ -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 &); private: static Msp::FS::Path generate_target_path(const Component &); -- 2.45.2