From c3cbb22d066e9ac9af1c6d497be85afeb598b2b8 Mon Sep 17 00:00:00 2001 From: Laurent Aphecetche Date: Tue, 9 Feb 2021 16:18:42 +0100 Subject: [PATCH] :alien: Changes to allow usage of either v2 or v3 of Microsoft GSL. Version 3.0.0 of Microsoft's implementation of the C++ Core Guidelines Support Library (GSL) (https://github.com/microsoft/GSL/releases/tag/v3.0.0) introduces a few breaking changes that affect our code. At the same time it's more future proof than v2 by being closer to the C++20 version of span, and has the very immediate benefit of compiling fine on Apple Silicon (while v2 does not). So, in order to prepare for the migration to v3, we introduce a compile definition and use to switch between syntaxes in the few places where the breaking changes impact us. Next step will be to update the alidist recipe to build v3(v3.1 really) instead of v2(.1). As a side note, v3(.1) also adds proper CMake config file that should eventually replace our custom Findms_gsl.cmake module (once we switch to v3 only). --- .../DataFormatsTPC/ClusterNativeHelper.h | 4 ++ .../Detectors/TPC/src/CompressedClusters.cxx | 4 ++ .../ConstMCTruthContainer.h | 12 ++++- .../SimulationDataFormat/MCTruthContainer.h | 3 +- .../FIT/FT0/reconstruction/src/ReadRaw.cxx | 4 +- .../FIT/FV0/simulation/src/Digitizer.cxx | 1 + .../include/GlobalTracking/MatchTOF.h | 20 ++++---- .../MUON/MCH/Simulation/src/Digitizer.cxx | 9 ++-- .../MID/Simulation/test/testSimulation.cxx | 14 ++++-- .../workflow/src/TRDGlobalTrackingSpec.cxx | 4 ++ .../Detectors/src/DataInterpreterITS.cxx | 3 ++ .../include/Framework/TMessageSerializer.h | 13 +++++ .../TestWorkflows/src/o2DummyWorkflow.cxx | 8 ++++ .../Interface/GPUO2InterfaceConfiguration.h | 9 +++- .../O2Device/include/O2Device/Utilities.h | 14 ++++-- dependencies/Findms_gsl.cmake | 48 ++++++++++++------- 16 files changed, 130 insertions(+), 40 deletions(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNativeHelper.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNativeHelper.h index c7fc95592d6e9..4563636ea5bd6 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNativeHelper.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNativeHelper.h @@ -382,7 +382,11 @@ int ClusterNativeHelper::Reader::fillIndex(ClusterNativeAccess& clusterIndex, continue; } o2::dataformats::ConstMCTruthContainerView const* labelsptr = nullptr; +#ifdef MS_GSL_V3 + std::size_t extent = 0; +#else int extent = 0; +#endif if (index < mcinputs.size()) { labelsptr = &mcinputs[index]; extent = 1; diff --git a/DataFormats/Detectors/TPC/src/CompressedClusters.cxx b/DataFormats/Detectors/TPC/src/CompressedClusters.cxx index c78a0b193848f..4fb31317117e4 100644 --- a/DataFormats/Detectors/TPC/src/CompressedClusters.cxx +++ b/DataFormats/Detectors/TPC/src/CompressedClusters.cxx @@ -60,7 +60,11 @@ void CompressedClustersROOT::Streamer(TBuffer& R__b) // the custom streamer for CompressedClustersROOT if (R__b.IsReading()) { R__b.ReadClassBuffer(CompressedClustersROOT::Class(), this); +#ifdef MS_GSL_V3 + gsl::span flatdata{this->flatdata, static_cast(this->flatdataSize)}; +#else gsl::span flatdata{this->flatdata, this->flatdataSize}; +#endif CompressedClustersHelpers::restoreFrom(flatdata, *this); } else { std::vector flatdata; diff --git a/DataFormats/simulation/include/SimulationDataFormat/ConstMCTruthContainer.h b/DataFormats/simulation/include/SimulationDataFormat/ConstMCTruthContainer.h index f287dd56803b7..2213ad1bb8d9d 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/ConstMCTruthContainer.h +++ b/DataFormats/simulation/include/SimulationDataFormat/ConstMCTruthContainer.h @@ -131,7 +131,17 @@ class ConstMCTruthContainerView public: ConstMCTruthContainerView(gsl::span const bufferview) : mStorage(bufferview){}; ConstMCTruthContainerView(ConstMCTruthContainer const& cont) : mStorage(gsl::span(cont)){}; - ConstMCTruthContainerView() : mStorage(nullptr, (gsl::span::index_type)0) { (void)0; } // be explicit that we want nullptr / 0 for an uninitialized container +#ifdef MS_GSL_V3 + // be explicit that we want nullptr / 0 for an uninitialized container + ConstMCTruthContainerView() : mStorage{nullptr, static_cast::size_type>(0)} + { + } +#else + // be explicit that we want nullptr / 0 for an uninitialized container + ConstMCTruthContainerView() : mStorage{nullptr, static_cast::index_type>(0)} + { + } +#endif ConstMCTruthContainerView(const ConstMCTruthContainerView&) = default; // const data access diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCTruthContainer.h b/DataFormats/simulation/include/SimulationDataFormat/MCTruthContainer.h index 506f24b56897a..9c08084da1cad 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCTruthContainer.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCTruthContainer.h @@ -19,11 +19,12 @@ #include // uint8_t etc #include #include -#include // for guideline support library; array_view +#include // for guideline support library span #include #include // memmove, memcpy #include #include + // type traits are needed for the compile time consistency check // maybe to be moved out of Framework first //#include "Framework/TypeTraits.h" diff --git a/Detectors/FIT/FT0/reconstruction/src/ReadRaw.cxx b/Detectors/FIT/FT0/reconstruction/src/ReadRaw.cxx index 451d211690ec6..485416db39007 100644 --- a/Detectors/FIT/FT0/reconstruction/src/ReadRaw.cxx +++ b/Detectors/FIT/FT0/reconstruction/src/ReadRaw.cxx @@ -60,7 +60,9 @@ Continueous mode : for only bunches with data at least in 1 channel. #include "TBranch.h" #include "CommonConstants/LHCConstants.h" #include "DetectorsRaw/RDHUtils.h" - +#ifdef MS_GSL_V3 +#include +#endif using namespace o2::ft0; using RDHUtils = o2::raw::RDHUtils; diff --git a/Detectors/FIT/FV0/simulation/src/Digitizer.cxx b/Detectors/FIT/FV0/simulation/src/Digitizer.cxx index c8cd42e29145d..aa3559e461ad3 100644 --- a/Detectors/FIT/FV0/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FV0/simulation/src/Digitizer.cxx @@ -14,6 +14,7 @@ #include #include +#include ClassImp(o2::fv0::Digitizer); diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchTOF.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchTOF.h index e628058aeca51..751ba920cdcf3 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchTOF.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchTOF.h @@ -183,8 +183,12 @@ class MatchTOF void setFITRecPoints(const std::vector* recpoints) { if (recpoints) { +#ifdef MS_GSL_V3 + mFITRecPoints = {recpoints->data(), recpoints->size()}; +#else // need explicit cast because the gsl index_type is signed mFITRecPoints = {recpoints->data(), static_cast(recpoints->size())}; +#endif } } void setFITRecPoints(gsl::span recpoints) @@ -340,14 +344,14 @@ class MatchTOF int mNumOfClusters; // number of clusters to be matched int* mMatchedClustersIndex = nullptr; //[mNumOfClusters] - std::string mTracksBranchName = "TPCITS"; ///< name of branch containing input matched tracks - std::string mTPCTracksBranchName = "TPCTracks"; ///< name of branch containing actual TPC tracks - std::string mTPCMCTruthBranchName = "MatchMCTruth"; ///< name of branch containing TPC labels - std::string mTOFMCTruthBranchName = "TOFClusterMCTruth"; ///< name of branch containing TOF clusters labels - std::string mTOFClusterBranchName = "TOFCluster"; ///< name of branch containing input ITS clusters - std::string mOutTracksBranchName = "TOFMatchInfo"; ///< name of branch containing output matched tracks - std::string mOutCalibBranchName = "TOFCalibInfo"; ///< name of branch containing output calibration infos - std::string mOutTOFMCTruthBranchName = "MatchTOFMCTruth"; ///< name of branch containing TOF labels for output matched tracks + std::string mTracksBranchName = "TPCITS"; ///< name of branch containing input matched tracks + std::string mTPCTracksBranchName = "TPCTracks"; ///< name of branch containing actual TPC tracks + std::string mTPCMCTruthBranchName = "MatchMCTruth"; ///< name of branch containing TPC labels + std::string mTOFMCTruthBranchName = "TOFClusterMCTruth"; ///< name of branch containing TOF clusters labels + std::string mTOFClusterBranchName = "TOFCluster"; ///< name of branch containing input ITS clusters + std::string mOutTracksBranchName = "TOFMatchInfo"; ///< name of branch containing output matched tracks + std::string mOutCalibBranchName = "TOFCalibInfo"; ///< name of branch containing output calibration infos + std::string mOutTOFMCTruthBranchName = "MatchTOFMCTruth"; ///< name of branch containing TOF labels for output matched tracks std::string mOutTPCTrackMCTruthBranchName = "TPCTracksMCTruth"; ///< name of branch containing TPC labels for input TPC tracks std::unique_ptr mDBGOut; diff --git a/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx b/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx index 8ea0b4514f99b..74782b46b9e4a 100644 --- a/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx +++ b/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx @@ -10,9 +10,9 @@ #include "MCHSimulation/Digitizer.h" -#include "MCHMappingInterface/Segmentation.h" #include "MCHGeometryCreator/Geometry.h" #include "MCHGeometryTransformer/Transformations.h" +#include "MCHMappingInterface/Segmentation.h" #include "MCHSimulation/Response.h" #include "TGeoManager.h" #include "TMath.h" @@ -20,8 +20,9 @@ #include #include #include - #include +#include + using namespace std; using namespace o2::mch; @@ -187,7 +188,7 @@ int Digitizer::processHit(const Hit& hit, int detID, int event_time) void Digitizer::generateNoiseDigits() { - o2::mch::mapping::forEachDetectionElement([& digits = this->mDigits, &normProbNoise = this->mNormProbNoise, + o2::mch::mapping::forEachDetectionElement([&digits = this->mDigits, &normProbNoise = this->mNormProbNoise, &eventTime = this->mEventTime, &eventID = this->mEventID, &srcID = this->mSrcID, &mcTruthOutputContainer = this->mMCTruthOutputContainer](int detID) { auto& seg = segmentation(detID); @@ -213,7 +214,7 @@ void Digitizer::mergeDigits() { std::vector indices(mDigits.size()); std::iota(begin(indices), end(indices), 0); - std::sort(indices.begin(), indices.end(), [& digits = this->mDigits, this](int a, int b) { + std::sort(indices.begin(), indices.end(), [&digits = this->mDigits, this](int a, int b) { return (getGlobalDigit(digits[a].getDetID(), digits[a].getPadID()) < getGlobalDigit(digits[b].getDetID(), digits[b].getPadID())); }); diff --git a/Detectors/MUON/MID/Simulation/test/testSimulation.cxx b/Detectors/MUON/MID/Simulation/test/testSimulation.cxx index 47c92c41cf7c6..11443a4c6080b 100644 --- a/Detectors/MUON/MID/Simulation/test/testSimulation.cxx +++ b/Detectors/MUON/MID/Simulation/test/testSimulation.cxx @@ -42,6 +42,14 @@ namespace o2 namespace mid { +std::vector getColumnDataNonMC(const o2::mid::DigitsMerger& dm) +{ + std::vector v; + auto ref = dm.getColumnData(); + v.insert(v.begin(), ref.begin(), ref.end()); + return v; +} + Digitizer createDigitizerNoClusterSize() { /// Returns the default chamber response @@ -395,7 +403,7 @@ BOOST_DATA_TEST_CASE(MID_SingleCluster, boost::unit_test::data::make(getDEList() rofRecords.clear(); rofRecords.emplace_back(o2::constants::lhc::LHCBunchSpacingNS * ievent, EventType::Standard, 0, digitStoreMC.size()); simDigitizer.digitsMerger.process(digitStoreMC, digitLabelsMC, rofRecords); - simClustering.preClusterizer.process(simDigitizer.digitsMerger.getColumnData(), simDigitizer.digitsMerger.getROFRecords()); + simClustering.preClusterizer.process(getColumnDataNonMC(simDigitizer.digitsMerger), simDigitizer.digitsMerger.getROFRecords()); simClustering.clusterizer.process(simClustering.preClusterizer.getPreClusters(), simClustering.preClusterizer.getROFRecords()); nRecoClusters = simClustering.clusterizer.getClusters().size(); ss << "nRecoClusters: " << nRecoClusters << " nGenClusters: " << nGenClusters << "\n"; @@ -438,7 +446,7 @@ BOOST_DATA_TEST_CASE(MID_SimClusters, boost::unit_test::data::make(getDEList()), digitLabelsAccum.mergeAtBack(digitLabelsMC); } simDigitizer.digitsMerger.process(digitsAccum, digitLabelsAccum, digitsROF); - simClustering.preClusterizer.process(simDigitizer.digitsMerger.getColumnData(), simDigitizer.digitsMerger.getROFRecords()); + simClustering.preClusterizer.process(getColumnDataNonMC(simDigitizer.digitsMerger), simDigitizer.digitsMerger.getROFRecords()); simClustering.correlation.clear(); simClustering.clusterizer.process(simClustering.preClusterizer.getPreClusters(), simClustering.preClusterizer.getROFRecords()); simClustering.preClusterLabeler.process(simClustering.preClusterizer.getPreClusters(), simDigitizer.digitsMerger.getMCContainer(), simClustering.preClusterizer.getROFRecords(), simDigitizer.digitsMerger.getROFRecords()); @@ -532,7 +540,7 @@ BOOST_DATA_TEST_CASE(MID_SimTracks, boost::unit_test::data::make({1, 2, 3, 4, 5, } simDigitizer.digitsMerger.process(digitsAccum, digitLabelsAccum, digitsROF); - simClustering.preClusterizer.process(simDigitizer.digitsMerger.getColumnData(), simDigitizer.digitsMerger.getROFRecords()); + simClustering.preClusterizer.process(getColumnDataNonMC(simDigitizer.digitsMerger), simDigitizer.digitsMerger.getROFRecords()); simClustering.correlation.clear(); simClustering.clusterizer.process(simClustering.preClusterizer.getPreClusters(), simClustering.preClusterizer.getROFRecords()); simClustering.preClusterLabeler.process(simClustering.preClusterizer.getPreClusters(), simDigitizer.digitsMerger.getMCContainer(), simClustering.preClusterizer.getROFRecords(), simDigitizer.digitsMerger.getROFRecords()); diff --git a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx index 37c02358ccf3a..c926821475244 100644 --- a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx @@ -94,7 +94,11 @@ void TRDGlobalTracking::run(ProcessingContext& pc) std::vector trdTriggerIndices; for (int iEv = 0; iEv < nCollisions; ++iEv) { +#ifdef MS_GSL_V3 + const auto& trg = triggerRecords[iEv]; +#else const auto& trg = triggerRecords.at(iEv); +#endif int nTrackletsCurrent = trg.getNumberOfObjects(); int iFirstTracklet = trg.getFirstEntry(); int64_t evTime = trg.getBCData().toLong() * o2::constants::lhc::LHCBunchSpacingNS; // event time in ns diff --git a/EventVisualisation/Detectors/src/DataInterpreterITS.cxx b/EventVisualisation/Detectors/src/DataInterpreterITS.cxx index ef2269ac5666f..10a77310610f6 100644 --- a/EventVisualisation/Detectors/src/DataInterpreterITS.cxx +++ b/EventVisualisation/Detectors/src/DataInterpreterITS.cxx @@ -31,6 +31,9 @@ #include #include +#ifdef MS_GSL_V3 +#include +#endif using namespace std; diff --git a/Framework/Core/include/Framework/TMessageSerializer.h b/Framework/Core/include/Framework/TMessageSerializer.h index b041125800396..be2a9a347a378 100644 --- a/Framework/Core/include/Framework/TMessageSerializer.h +++ b/Framework/Core/include/Framework/TMessageSerializer.h @@ -160,7 +160,11 @@ inline std::unique_ptr TMessageSerializer::deserialize(gsl::span bu template inline std::unique_ptr TMessageSerializer::deserialize(byte* buffer, size_t size) { +#ifdef MS_GSL_V3 + return deserialize(gsl::span(buffer, gsl::narrow::size_type>(size))); +#else return deserialize(gsl::span(buffer, gsl::narrow::index_type>(size))); +#endif } inline void FairTMessage::free(void* /*data*/, void* hint) @@ -213,13 +217,22 @@ inline TMessageSerializer::StreamerList TMessageSerializer::getStreamers() // we would probably be fine with e.g. gsl::narrow_cast (or just a static_cast) inline gsl::span as_span(const FairMQMessage& msg) { +#ifdef MS_GSL_V3 + return gsl::span{static_cast(msg.GetData()), gsl::narrow::size_type>(msg.GetSize())}; +#else return gsl::span{static_cast(msg.GetData()), gsl::narrow::index_type>(msg.GetSize())}; +#endif } inline gsl::span as_span(const FairTMessage& msg) { +#ifdef MS_GSL_V3 + return gsl::span{reinterpret_cast(msg.Buffer()), + gsl::narrow::size_type>(msg.BufferSize())}; +#else return gsl::span{reinterpret_cast(msg.Buffer()), gsl::narrow::index_type>(msg.BufferSize())}; +#endif } } // namespace framework diff --git a/Framework/TestWorkflows/src/o2DummyWorkflow.cxx b/Framework/TestWorkflows/src/o2DummyWorkflow.cxx index ae4c86ade35f2..8a7ad02cd0e39 100644 --- a/Framework/TestWorkflows/src/o2DummyWorkflow.cxx +++ b/Framework/TestWorkflows/src/o2DummyWorkflow.cxx @@ -78,7 +78,11 @@ std::vector defineDataProcessing(ConfigContext const&) {OutputSpec{{"summary"}, "TPC", "SUMMARY"}}, AlgorithmSpec{[](ProcessingContext& ctx) { auto& tpcSummary = ctx.outputs().make(OutputRef{"summary"}, 1); +#ifdef MS_GSL_V3 + tpcSummary[0].inputCount = ctx.inputs().size(); +#else tpcSummary.at(0).inputCount = ctx.inputs().size(); +#endif }}, {ConfigParamSpec{"some-cut", VariantType::Float, 1.0f, {"some cut"}}}, }; @@ -91,7 +95,11 @@ std::vector defineDataProcessing(ConfigContext const&) }, AlgorithmSpec{[](ProcessingContext& ctx) { auto& itsSummary = ctx.outputs().make(OutputRef{"summary"}, 1); +#ifdef MS_GSL_V3 + itsSummary[0].inputCount = ctx.inputs().size(); +#else itsSummary.at(0).inputCount = ctx.inputs().size(); +#endif }}, {ConfigParamSpec{"some-cut", VariantType::Float, 1.0f, {"some cut"}}}, }; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h index d706d2f98ecd1..8e2200d5d04b3 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h @@ -45,7 +45,7 @@ namespace tpc { class TrackTPC; class Digit; -} +} // namespace tpc namespace gpu { class TPCFastTransform; @@ -114,10 +114,15 @@ struct GPUO2InterfaceIOPtrs { const o2::gpu::GPUTrackingInOutZS* tpcZS = nullptr; // Input / Output for Merged TPC tracks, two ptrs, for the tracks themselves, and for the MC labels. +#ifdef MS_GSL_V3 + gsl::span outputTracks = {nullptr, (gsl::span::size_type)0}; + gsl::span outputClusRefs = {nullptr, (gsl::span::size_type)0}; + gsl::span outputTracksMCTruth = {nullptr, (gsl::span::size_type)0}; +#else gsl::span outputTracks = {nullptr, (gsl::span::index_type)0}; gsl::span outputClusRefs = {nullptr, (gsl::span::index_type)0}; gsl::span outputTracksMCTruth = {nullptr, (gsl::span::index_type)0}; - +#endif // Output for entropy-reduced clusters of TPC compression const o2::tpc::CompressedClustersFlat* compressedClusters = nullptr; }; diff --git a/Utilities/O2Device/include/O2Device/Utilities.h b/Utilities/O2Device/include/O2Device/Utilities.h index 398086cc009b0..2adbe6e12ffc5 100644 --- a/Utilities/O2Device/include/O2Device/Utilities.h +++ b/Utilities/O2Device/include/O2Device/Utilities.h @@ -85,21 +85,27 @@ namespace internal template auto forEach(I begin, I end, F&& function) { + using span = gsl::span; +#ifdef MS_GSL_V3 + using SPAN_SIZE_TYPE = span::size_type; +#else + using SPAN_SIZE_TYPE = span::index_type; +#endif using gsl::narrow_cast; for (auto it = begin; it != end; ++it) { o2::byte* headerBuffer{nullptr}; - span::index_type headerBufferSize{0}; + SPAN_SIZE_TYPE headerBufferSize{0}; if (*it != nullptr) { headerBuffer = reinterpret_cast((*it)->GetData()); - headerBufferSize = narrow_cast((*it)->GetSize()); + headerBufferSize = narrow_cast((*it)->GetSize()); } ++it; o2::byte* dataBuffer{nullptr}; - span::index_type dataBufferSize{0}; + SPAN_SIZE_TYPE dataBufferSize{0}; if (*it != nullptr) { dataBuffer = reinterpret_cast((*it)->GetData()); - dataBufferSize = narrow_cast((*it)->GetSize()); + dataBufferSize = narrow_cast((*it)->GetSize()); } // call the user provided function diff --git a/dependencies/Findms_gsl.cmake b/dependencies/Findms_gsl.cmake index 64ae38d326701..eb053dbe25c2b 100644 --- a/dependencies/Findms_gsl.cmake +++ b/dependencies/Findms_gsl.cmake @@ -8,22 +8,38 @@ # granted to it by virtue of its status as an Intergovernmental Organization or # submit itself to any jurisdiction. -find_path(MS_GSL_INCLUDE_DIR gsl/gsl PATH_SUFFIXES ms_gsl/include include - HINTS $ENV{MS_GSL_ROOT}) - -if(NOT MS_GSL_INCLUDE_DIR) - set(MS_GSL_FOUND FALSE) - message(WARNING "MS_GSL not found") - return() -endif() +# The library provides a Config file for CMake, once installed it can be found via +# +# find_package(Microsoft.GSL CONFIG) +# Which, when successful, will add library target called Microsoft.GSL::GSL which you can use via the usual target_link_libraries mechanism. -set(MS_GSL_FOUND TRUE) +find_package(Microsoft.GSL CONFIG) -if(NOT TARGET ms_gsl::ms_gsl) - add_library(ms_gsl::ms_gsl INTERFACE IMPORTED) - set_target_properties(ms_gsl::ms_gsl - PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - ${MS_GSL_INCLUDE_DIR}) +if(TARGET Microsoft.GSL::GSL) + # version >= 3.1 now has a proper Config.cmake file + # so we use that + add_library(ms_gsl::ms_gsl ALIAS Microsoft.GSL::GSL) + set(MS_GSL_FOUND TRUE) + target_compile_definitions(Microsoft.GSL::GSL INTERFACE MS_GSL_V3) +else() + + find_path(MS_GSL_INCLUDE_DIR gsl/gsl PATH_SUFFIXES ms_gsl/include include + HINTS $ENV{MS_GSL_ROOT}) + + if(NOT MS_GSL_INCLUDE_DIR) + set(MS_GSL_FOUND FALSE) + message(WARNING "MS_GSL not found") + return() + endif() + + set(MS_GSL_FOUND TRUE) + + if(NOT TARGET ms_gsl::ms_gsl) + add_library(ms_gsl::ms_gsl INTERFACE IMPORTED) + set_target_properties(ms_gsl::ms_gsl + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + ${MS_GSL_INCLUDE_DIR}) + endif() + + mark_as_advanced(MS_GSL_INCLUDE_DIR) endif() - -mark_as_advanced(MS_GSL_INCLUDE_DIR)