From f19959de304afaff2b3d539c9bef1f493ede5fbd Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 22 Nov 2022 06:27:33 +0200 Subject: Add support for Objective-C/C++ compilation in cc module --- libbuild2/cxx/init.cxx | 47 +++++++++++++++++++++++++++++++++++++++++++++++ libbuild2/cxx/init.hxx | 2 ++ libbuild2/cxx/target.cxx | 18 ++++++++++++++---- libbuild2/cxx/target.hxx | 16 ++++++++++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) (limited to 'libbuild2/cxx') diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx index 5396056..fd6d04c 100644 --- a/libbuild2/cxx/init.cxx +++ b/libbuild2/cxx/init.cxx @@ -479,8 +479,10 @@ namespace build2 "cxx", "c++", + "obj-c++", BUILD2_DEFAULT_CXX, ".ii", + ".mii", hinters, @@ -790,6 +792,8 @@ namespace build2 &mxx::static_type, &cxx::static_type, &c::static_type, + &mm::static_type, + &m::static_type, nullptr }; @@ -877,6 +881,48 @@ namespace build2 return true; } + bool + objcxx_init (scope& rs, + scope& bs, + const location& loc, + bool, + bool, + module_init_extra&) + { + tracer trace ("cxx::objcxx_init"); + l5 ([&]{trace << "for " << bs;}); + + // We only support root loading (which means there can only be one). + // + if (rs != bs) + fail (loc) << "cxx.objcxx module must be loaded in project root"; + + module* mod (rs.find_module ("cxx")); + + if (mod == nullptr) + fail (loc) << "cxx.objcxx module must be loaded after cxx module"; + + // Register the target type and "enable" it in the module. + // + // Note that we must register the target type regardless of whether the + // C++ compiler is capable of compiling Objective-C++. But we enable + // only if it is. + // + // Note: see similar code in the c module. + // + rs.insert_target_type (); + + // Note that while Objective-C++ is supported by MinGW GCC, it's + // unlikely Clang supports it when targeting MSVC or Emscripten. But + // let's keep the check simple for now. + // + if (mod->ctype == compiler_type::gcc || + mod->ctype == compiler_type::clang) + mod->x_obj = &mm::static_type; + + return true; + } + static const module_functions mod_functions[] = { // NOTE: don't forget to also update the documentation in init.hxx if @@ -885,6 +931,7 @@ namespace build2 {"cxx.guess", nullptr, guess_init}, {"cxx.config", nullptr, config_init}, {"cxx", nullptr, init}, + {"cxx.objcxx", nullptr, objcxx_init}, {nullptr, nullptr, nullptr} }; diff --git a/libbuild2/cxx/init.hxx b/libbuild2/cxx/init.hxx index 094fea4..0e42cbe 100644 --- a/libbuild2/cxx/init.hxx +++ b/libbuild2/cxx/init.hxx @@ -22,6 +22,8 @@ namespace build2 // `cxx.guess` -- registers and sets some variables. // `cxx.config` -- loads cxx.guess and sets more variables. // `cxx` -- loads cxx.config and registers target types and rules. + // `cxx.objcxx` -- registers mm{} target type and enables Objective-C++ + // compilation. // extern "C" LIBBUILD2_CXX_SYMEXPORT const module_functions* build2_cxx_load (); diff --git a/libbuild2/cxx/target.cxx b/libbuild2/cxx/target.cxx index fc50f67..5ead620 100644 --- a/libbuild2/cxx/target.cxx +++ b/libbuild2/cxx/target.cxx @@ -3,10 +3,6 @@ #include -#include - -using namespace std; - namespace build2 { namespace cxx @@ -80,5 +76,19 @@ namespace build2 &file_search, target_type::flag::none }; + + extern const char mm_ext_def[] = "mm"; + const target_type mm::static_type + { + "mm", + &cc::static_type, + &target_factory, + nullptr, /* fixed_extension */ + &target_extension_var, + &target_pattern_var, + nullptr, + &file_search, + target_type::flag::none + }; } } diff --git a/libbuild2/cxx/target.hxx b/libbuild2/cxx/target.hxx index b20bf00..fc85f75 100644 --- a/libbuild2/cxx/target.hxx +++ b/libbuild2/cxx/target.hxx @@ -18,6 +18,7 @@ namespace build2 { using cc::h; using cc::c; + using cc::m; class LIBBUILD2_CXX_SYMEXPORT hxx: public cc::cc { @@ -88,6 +89,21 @@ namespace build2 public: static const target_type static_type; }; + + // Objective-C++ source file. + // + class LIBBUILD2_CXX_SYMEXPORT mm: public cc::cc + { + public: + mm (context& c, dir_path d, dir_path o, string n) + : cc (c, move (d), move (o), move (n)) + { + dynamic_type = &static_type; + } + + public: + static const target_type static_type; + }; } } -- cgit v1.1