// file : build2/cc/common -*- C++ -*- // copyright : Copyright (c) 2014-2017 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BUILD2_CC_COMMON #define BUILD2_CC_COMMON #include #include #include #include #include namespace build2 { namespace cc { // Data entries that define a concrete c-family module (e.g., c or cxx). // These classes are used as a virtual bases by the rules as well as the // modules. This way the member variables can be referenced as is, without // any extra decorations (in other words, it is a bunch of data members // that can be shared between several classes/instances). // struct config_data { lang x_lang; const char* x; // Module name ("c", "cxx"). const char* x_name; // Compiler name ("c", "c++"). const char* x_default; // Compiler default ("gcc", "g++"). const variable& config_x; const variable& config_x_poptions; const variable& config_x_coptions; const variable& config_x_loptions; const variable& config_x_libs; const variable& x_path; // Compiler process path. const variable& x_sys_lib_dirs; // System library search directories. const variable& x_sys_inc_dirs; // Extra header search directories. const variable& x_poptions; const variable& x_coptions; const variable& x_loptions; const variable& x_libs; const variable& c_poptions; // cc.* const variable& c_coptions; const variable& c_loptions; const variable& c_libs; const variable& x_export_poptions; const variable& x_export_coptions; const variable& x_export_loptions; const variable& x_export_libs; const variable& c_export_poptions; // cc.export.* const variable& c_export_coptions; const variable& c_export_loptions; const variable& c_export_libs; const variable& c_type; // cc.type const variable& c_system; // cc.system const variable& x_std; const variable& x_id; const variable& x_id_type; const variable& x_id_variant; const variable& x_version; const variable& x_version_major; const variable& x_version_minor; const variable& x_version_patch; const variable& x_version_build; const variable& x_signature; const variable& x_checksum; const variable& x_target; const variable& x_target_cpu; const variable& x_target_vendor; const variable& x_target_system; const variable& x_target_version; const variable& x_target_class; }; struct data: config_data { const char* x_compile; // Rule names. const char* x_link; const char* x_install; const char* x_uninstall; // Cached values for some commonly-used variables/values. // const string& cid; // x.id const target_triplet& ctg; // x.target const string& tsys; // x.target.system const string& tclass; // x.target.class const string& tstd; // Translated x_std value (can be empty). const process_path* pkgconfig; // pkgconfig.path (can be NULL). const dir_paths& sys_lib_dirs; // x.sys_lib_dirs const dir_paths& sys_inc_dirs; // x.sys_inc_dirs const target_type& x_src; // Source target type (c{}, cxx{}). // Array of target types that are considered headers. Keep them in the // most likely to appear order and terminate with NULL. // const target_type* const* x_hdr; template bool x_header (const T& t) const { for (const target_type* const* ht (x_hdr); *ht != nullptr; ++ht) if (t.is_a (**ht)) return true; return false; } // Array of target types that can be #include'd. Used to reverse-lookup // extensions to target types. Keep them in the most likely to appear // order and terminate with NULL. // const target_type* const* x_inc; // Aggregate-like constructor with from-base support. // data (const config_data& cd, const char* compile, const char* link, const char* install, const char* uninstall, const string& id, const target_triplet& tg, const string& std, const process_path* pkgc, const dir_paths& sld, const dir_paths& sid, const target_type& src, const target_type* const* hdr, const target_type* const* inc) : config_data (cd), x_compile (compile), x_link (link), x_install (install), x_uninstall (uninstall), cid (id), ctg (tg), tsys (ctg.system), tclass (ctg.class_), tstd (std), pkgconfig (pkgc), sys_lib_dirs (sld), sys_inc_dirs (sid), x_src (src), x_hdr (hdr), x_inc (inc) {} }; class common: protected data { public: common (data&& d): data (move (d)) {} // Language standard (x.std) mapping. // void append_std (cstrings& args) const { if (!tstd.empty ()) args.push_back (tstd.c_str ()); } void hash_std (sha256& cs) const { if (!tstd.empty ()) cs.append (tstd); } // Library handling. // public: void process_libraries ( const scope&, lorder, const dir_paths&, const file&, bool, const function&, const function&, const function&, bool = false) const; target* search_library (const dir_paths& sysd, optional& usrd, prerequisite& p) const { if (p.target == nullptr) // First check the cache. p.target = search_library (sysd, usrd, p.key ()); return p.target; } private: const file& resolve_library (const scope&, name, lorder, const dir_paths&, optional&) const; target* search_library (const dir_paths&, optional&, const prerequisite_key&, bool existing = false) const; const target* search_library_existing (const dir_paths& sysd, optional& usrd, const prerequisite_key& pk) const { return search_library (sysd, usrd, pk, true); } dir_paths extract_library_dirs (const scope&) const; bool pkgconfig_extract (const scope&, bin::lib&, bin::liba*, bin::libs*, const optional&, const string&, const dir_path&, const dir_paths&) const; // pkgconfig.cxx // Alternative search logic for VC (msvc.cxx). // bin::liba* msvc_search_static (const process_path&, const dir_path&, const prerequisite_key&, bool existing) const; bin::libs* msvc_search_shared (const process_path&, const dir_path&, const prerequisite_key&, bool existing) const; }; } } #endif // BUILD2_CC_COMMON