123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399(******************************************************************************)(* OASIS: architecture for building OCaml libraries and applications *)(* *)(* Copyright (C) 2011-2016, Sylvain Le Gall *)(* Copyright (C) 2008-2011, OCamlCore SARL *)(* *)(* This library is free software; you can redistribute it and/or modify it *)(* under the terms of the GNU Lesser General Public License as published by *)(* the Free Software Foundation; either version 2.1 of the License, or (at *)(* your option) any later version, with the OCaml static compilation *)(* exception. *)(* *)(* This library is distributed in the hope that it will be useful, but *)(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)(* details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this library; if not, write to the Free Software Foundation, *)(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)(******************************************************************************)openOASISTypesopenOASISUtilsopenOASISGettextopenOASISVersionmoduleMapPlugin=Map.Make(structtypet=plugin_kind*nameletcompare=Pervasives.compareend)moduleData=structtypet={oasis_version:OASISVersion.t;plugin_versions:OASISVersion.toptionMapPlugin.t;alpha_features:stringlist;beta_features:stringlist;}letcreateoasis_versionalpha_featuresbeta_features={oasis_version=oasis_version;plugin_versions=MapPlugin.empty;alpha_features=alpha_features;beta_features=beta_features}letof_packagepkg=createpkg.OASISTypes.oasis_versionpkg.OASISTypes.alpha_featurespkg.OASISTypes.beta_featuresletadd_plugin(plugin_kind,plugin_name,plugin_version)t={twithplugin_versions=MapPlugin.add(plugin_kind,plugin_name)plugin_versiont.plugin_versions}letplugin_versionplugin_kindplugin_namet=MapPlugin.find(plugin_kind,plugin_name)t.plugin_versionsletto_stringt=Printf.sprintf"oasis_version: %s; alpha_features: %s; beta_features: %s; \
plugins_version: %s"(OASISVersion.string_of_version(t:t).oasis_version)(String.concat", "t.alpha_features)(String.concat", "t.beta_features)(String.concat", "(MapPlugin.fold(fun(_,plg)ver_optacc->(plg^(matchver_optwith|Somev->" "^(OASISVersion.string_of_versionv)|None->""))::acc)t.plugin_versions[]))endtypeorigin=|Fieldofstring*string|Sectionofstring|NoOrigintypestage=Alpha|Betaletstring_of_stage=function|Alpha->"alpha"|Beta->"beta"letfield_of_stage=function|Alpha->"AlphaFeatures"|Beta->"BetaFeatures"typepublication=InDevofstage|SinceVersionofOASISVersion.ttypet={name:string;plugin:all_pluginoption;publication:publication;description:unit->string;}(* TODO: mutex protect this. *)letall_features=Hashtbl.create13letsince_versionver_str=SinceVersion(version_of_stringver_str)letalpha=InDevAlphaletbeta=InDevBetaletto_stringt=Printf.sprintf"feature: %s; plugin: %s; publication: %s"(t:t).name(matcht.pluginwith|None->"<none>"|Some(_,nm,_)->nm)(matcht.publicationwith|InDevstage->string_of_stagestage|SinceVersionver->">= "^(OASISVersion.string_of_versionver))letdata_checktdataorigin=letno_message="no message"inletcheck_featurefeaturesstage=lethas_feature=List.mem(t:t).namefeaturesinifnothas_featurethenmatch(origin:origin)with|Field(fld,where)->Some(Printf.sprintf(f_"Field %s in %s is only available when feature %s \
is in field %s.")fldwheret.name(field_of_stagestage))|Sectionsct->Some(Printf.sprintf(f_"Section %s is only available when features %s \
is in field %s.")sctt.name(field_of_stagestage))|NoOrigin->Someno_messageelseNoneinletversion_is_good~min_versionversionfmt=letversion_is_good=OASISVersion.comparator_applyversion(OASISVersion.VGreaterEqualmin_version)inPrintf.ksprintf(funstr->ifversion_is_goodthenNoneelseSomestr)fmtinmatchorigin,t.plugin,t.publicationwith|_,_,InDevAlpha->check_featuredata.Data.alpha_featuresAlpha|_,_,InDevBeta->check_featuredata.Data.beta_featuresBeta|Field(fld,where),None,SinceVersionmin_version->version_is_good~min_versiondata.Data.oasis_version(f_"Field %s in %s is only valid since OASIS v%s, update \
OASISFormat field from '%s' to '%s' after checking \
OASIS changelog.")fldwhere(string_of_versionmin_version)(string_of_versiondata.Data.oasis_version)(string_of_versionmin_version)|Field(fld,where),Some(plugin_knd,plugin_name,_),SinceVersionmin_version->begintryletplugin_version_current=trymatchData.plugin_versionplugin_kndplugin_namedatawith|Somever->ver|None->failwithf(f_"Field %s in %s is only valid for the OASIS \
plugin %s since v%s, but no plugin version is \
defined in the _oasis file, change '%s' to \
'%s (%s)' in your _oasis file.")fldwhereplugin_name(string_of_versionmin_version)plugin_nameplugin_name(string_of_versionmin_version)withNot_found->failwithf(f_"Field %s in %s is only valid when the OASIS plugin %s \
is defined.")fldwhereplugin_nameinversion_is_good~min_versionplugin_version_current(f_"Field %s in %s is only valid for the OASIS plugin %s \
since v%s, update your plugin from '%s (%s)' to \
'%s (%s)' after checking the plugin's changelog.")fldwhereplugin_name(string_of_versionmin_version)plugin_name(string_of_versionplugin_version_current)plugin_name(string_of_versionmin_version)withFailuremsg->Somemsgend|Sectionsct,None,SinceVersionmin_version->version_is_good~min_versiondata.Data.oasis_version(f_"Section %s is only valid for since OASIS v%s, update \
OASISFormat field from '%s' to '%s' after checking OASIS \
changelog.")sct(string_of_versionmin_version)(string_of_versiondata.Data.oasis_version)(string_of_versionmin_version)|Sectionsct,Some(plugin_knd,plugin_name,_),SinceVersionmin_version->begintryletplugin_version_current=trymatchData.plugin_versionplugin_kndplugin_namedatawith|Somever->ver|None->failwithf(f_"Section %s is only valid for the OASIS \
plugin %s since v%s, but no plugin version is \
defined in the _oasis file, change '%s' to \
'%s (%s)' in your _oasis file.")sctplugin_name(string_of_versionmin_version)plugin_nameplugin_name(string_of_versionmin_version)withNot_found->failwithf(f_"Section %s is only valid when the OASIS plugin %s \
is defined.")sctplugin_nameinversion_is_good~min_versionplugin_version_current(f_"Section %s is only valid for the OASIS plugin %s \
since v%s, update your plugin from '%s (%s)' to \
'%s (%s)' after checking the plugin's changelog.")sctplugin_name(string_of_versionmin_version)plugin_name(string_of_versionplugin_version_current)plugin_name(string_of_versionmin_version)withFailuremsg->Somemsgend|NoOrigin,None,SinceVersionmin_version->version_is_good~min_versiondata.Data.oasis_version"%s"no_message|NoOrigin,Some(plugin_knd,plugin_name,_),SinceVersionmin_version->begintryletplugin_version_current=matchData.plugin_versionplugin_kndplugin_namedatawith|Somever->ver|None->raiseNot_foundinversion_is_good~min_versionplugin_version_current"%s"no_messagewithNot_found->Someno_messageendletdata_asserttdataorigin=matchdata_checktdataoriginwith|None->()|Somestr->failwithstrletdata_testtdata=matchdata_checktdataNoOriginwith|None->true|Some_->falseletpackage_testtpkg=data_testt(Data.of_packagepkg)letcreate?pluginnamepublicationdescription=let()=ifHashtbl.memall_featuresnamethenfailwithf"Feature '%s' is already declared."nameinlett={name=name;plugin=plugin;publication=publication;description=description;}inHashtbl.addall_featuresnamet;tletget_stagename=try(Hashtbl.findall_featuresname).publicationwithNot_found->failwithf(f_"Feature %s doesn't exist.")nameletlist()=Hashtbl.fold(fun_vacc->v::acc)all_features[](*
* Real flags.
*)letfeatures=create"features_fields"(since_version"0.4")(fun()->s_"Enable to experiment not yet official features.")letflag_docs=create"flag_docs"(since_version"0.3")(fun()->s_"Make building docs require '-docs' flag at configure.")letflag_tests=create"flag_tests"(since_version"0.3")(fun()->s_"Make running tests require '-tests' flag at configure.")letpack=create"pack"(since_version"0.3")(fun()->s_"Allow to create packed library.")letsection_object=create"section_object"beta(fun()->s_"Implement an object section.")letdynrun_for_release=create"dynrun_for_release"alpha(fun()->s_"Make '-setup-update dynamic' suitable for releasing project.")letcompiled_setup_ml=create"compiled_setup_ml"alpha(fun()->s_"Compile the setup.ml and speed-up actions done with it.")letdisable_oasis_section=create"disable_oasis_section"alpha(fun()->s_"Allow the OASIS section comments and digests to be omitted in \
generated files.")letno_automatic_syntax=create"no_automatic_syntax"alpha(fun()->s_"Disable the automatic inclusion of -syntax camlp4o for packages \
that matches the internal heuristic (if a dependency ends with \
a .syntax or is a well known syntax).")letfindlib_directory=create"findlib_directory"beta(fun()->s_"Allow to install findlib libraries in sub-directories of the target \
findlib directory.")letfindlib_extra_files=create"findlib_extra_files"beta(fun()->s_"Allow to install extra files for findlib libraries.")letsource_patterns=create"source_patterns"alpha(fun()->s_"Customize mapping between module name and source file.")