From 30fd234f1e33de2c02a26f53133ba78414955861 Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Wed, 19 Jul 2017 08:18:24 -0700 Subject: [PATCH 1/7] Add extra linkages --- scoring_framework/CMakeLists.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scoring_framework/CMakeLists.txt b/scoring_framework/CMakeLists.txt index fa5202e..f8ff551 100644 --- a/scoring_framework/CMakeLists.txt +++ b/scoring_framework/CMakeLists.txt @@ -83,6 +83,7 @@ target_link_libraries( score_core vul vgl data_terms + scoring_aries_interface PRIVATE track_oracle_tokenizers vibrant_descriptors vital_logger @@ -119,6 +120,11 @@ target_link_libraries( score_tracks_loader PUBLIC score_core vul PRIVATE track_oracle_file_formats + track_kwxml + track_vpd + track_comms_xml + track_oracle_format_base + vital_logger ) ######################################## @@ -170,21 +176,25 @@ if (fletch_ENABLED_libjson) kwiver_add_executable( score_tracks score_tracks.cxx) target_link_libraries( score_tracks - score_tracks_loader + PRIVATE score_tracks_loader score_tracks_hadwav track_oracle track_oracle_file_formats timestamp_utilities + vital_logger ${json_lib} ) endif() kwiver_add_executable( score_events score_events.cxx ) target_link_libraries( score_events - logging_map + PRIVATE logging_map data_terms score_tracks_loader timestamp_utilities track_oracle - track_oracle_file_formats vul + track_kst track_kwxml + track_oracle_file_formats + track_oracle_format_base + vital_logger vul ${Boost_SYSTEM_LIBRARY} ) ######################################## From a3766b22772c6f39717b23b34c7e7d194cd77f1e Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Wed, 11 Oct 2017 13:07:01 -0400 Subject: [PATCH 2/7] Add flag required for latest kwiver --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e4ffb..bd5d616 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,8 @@ include_directories( ${kwant_SOURCE_DIR} ) include_directories( ${kwant_BINARY_DIR} ) include( kwant-depends ) + +include( kwiver-cmake-future ) include( kwiver-utils ) include( kwiver-flags ) # use same compile flags as kwiver From 27e5d9fd4f9968c74b48b0f6eb43c8a40c583a19 Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Tue, 3 Jul 2018 21:46:09 -0400 Subject: [PATCH 3/7] Update for VXL API change --- scoring_framework/quickfilter_box.cxx | 4 ++-- scoring_framework/score_events.cxx | 4 ++-- scoring_framework/score_frames_aipr.cxx | 4 ++-- scoring_framework/score_phase1.cxx | 6 +++--- scoring_framework/score_tracks.cxx | 2 +- scoring_framework/score_tracks_loader.cxx | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scoring_framework/quickfilter_box.cxx b/scoring_framework/quickfilter_box.cxx index c8c5d12..2479ab3 100644 --- a/scoring_framework/quickfilter_box.cxx +++ b/scoring_framework/quickfilter_box.cxx @@ -386,7 +386,7 @@ ::mgrs_box_intersect( const track_handle_type& t1, vgl_box_2d overlap = vgl_intersection( t1_box, t2_box ); if (dbg) LOG_DEBUG( main_logger, "mgrs_box_intersect: boxes:\n" << t1_box << "\n" << t2_box << "\n" << overlap ); - return (overlap.is_empty()) ? 0.0 : overlap.area(); + return (overlap.is_empty()) ? 0.0 : overlap.volume(); } // if we get this far, we found no overlapping zones; the caller will @@ -428,7 +428,7 @@ ::img_box_intersect( const track_handle_type& t1, return -1.0; } - return vgl_intersection( box_1, box_2 ).area(); + return vgl_intersection( box_1, box_2 ).volume(); } double diff --git a/scoring_framework/score_events.cxx b/scoring_framework/score_events.cxx index 3d47d22..10024ba 100644 --- a/scoring_framework/score_events.cxx +++ b/scoring_framework/score_events.cxx @@ -779,14 +779,14 @@ compute_normalization_factors( const track_handle_list_type& truth_tracks, vgl_box_2d ne_box; // northing / easting box; assume the zones all match add_tracks_to_box( truth_tracks, ne_box ); add_tracks_to_box( computed_tracks, ne_box ); - LOG_INFO( main_logger, "Normalization: MGRS all-tracks AOI is " << ne_box.area() << " m^2" ); + LOG_INFO( main_logger, "Normalization: MGRS all-tracks AOI is " << ne_box.volume() << " m^2" ); timestamp_utilities::track_timestamp_stats_type tst_t( truth_tracks ), tst_c( computed_tracks ); tst_t.combine_with_other( tst_c ); double time_window_secs = (tst_t.minmax_ts.second - tst_t.minmax_ts.first) / 1.0e6; LOG_INFO( main_logger, "Normalization: all-tracks time window is " << time_window_secs << " seconds" ); - double kmsq_in_box = ne_box.area() / 1.0e6; + double kmsq_in_box = ne_box.volume() / 1.0e6; // e.g. if area == 3 and time_window_secs = 120, then to get to FA / (km^2 per s), // divide FA count by (3 * 120) diff --git a/scoring_framework/score_frames_aipr.cxx b/scoring_framework/score_frames_aipr.cxx index 161123a..d52f5be 100644 --- a/scoring_framework/score_frames_aipr.cxx +++ b/scoring_framework/score_frames_aipr.cxx @@ -96,9 +96,9 @@ void compute_frame_based_metrics(vector& fbm, vgl_box_2d intersection = vgl_intersection(gt->history()[0]->amhi_bbox_,comp->history()[0]->amhi_bbox_); double overlap_score = 0; - if(intersection.area() != 0) + if(intersection.volume() != 0) { - overlap_score = (gt->history()[0]->amhi_bbox_.area()+comp->history()[0]->amhi_bbox_.area()-intersection.area())/intersection.area(); + overlap_score = (gt->history()[0]->amhi_bbox_.volume()+comp->history()[0]->amhi_bbox_.volume()-intersection.volume())/intersection.volume(); } if(!intersection.is_empty() && overlap_score >= min_overlap_ratio) diff --git a/scoring_framework/score_phase1.cxx b/scoring_framework/score_phase1.cxx index 907c91b..47c5762 100644 --- a/scoring_framework/score_phase1.cxx +++ b/scoring_framework/score_phase1.cxx @@ -642,9 +642,9 @@ ::compute_spatial_overlap( frame_handle_type t1, frame_handle_type t2, phase1_pa { // it's pretty annoying but some of the code (e.g. score_phase2_aipr.cxx:60) // seems to rely on these being set ONLY if there is overlap - ret.truth_area = b1.area(); - ret.computed_area = b2.area(); - ret.overlap_area = bi.area(); + ret.truth_area = b1.volume(); + ret.computed_area = b2.volume(); + ret.overlap_area = bi.volume(); double dx = b1.centroid_x() - b2.centroid_x(); double d_center_y = b1.centroid_y() - b2.centroid_y(); diff --git a/scoring_framework/score_tracks.cxx b/scoring_framework/score_tracks.cxx index 8fc4070..3191813 100644 --- a/scoring_framework/score_tracks.cxx +++ b/scoring_framework/score_tracks.cxx @@ -447,7 +447,7 @@ compute_normalization_factor( const phase1_parameters& p1_params, if (compute_norm) { double g = normalization_args.gsd(); // meters-per-pixel - double data_spatial_footprint = p1_params.b_aoi.area() * g * g; // m^2 + double data_spatial_footprint = p1_params.b_aoi.volume() * g * g; // m^2 norm = data_spatial_footprint * normalization_args.norm_data_time(); // (m^2)*s } } diff --git a/scoring_framework/score_tracks_loader.cxx b/scoring_framework/score_tracks_loader.cxx index 47915dd..1ae04cd 100644 --- a/scoring_framework/score_tracks_loader.cxx +++ b/scoring_framework/score_tracks_loader.cxx @@ -723,7 +723,7 @@ check_for_zero_area_boxes( const vector< track_record_type >& records ) frame_handle_list_type frames = track_oracle_core::get_frames( r_tracks[j] ); for (size_t k=0; k Date: Mon, 10 Dec 2018 21:49:05 -0500 Subject: [PATCH 4/7] Allow users to specify formats for computed and truth files. Adds the --truth-format and --computed-format options, which override file format autodetection. Use 'help' to list the formats track_oracle knows about. --- scoring_framework/score_events.cxx | 5 ++ scoring_framework/score_tracks_loader.cxx | 82 +++++++++++++++++++---- scoring_framework/score_tracks_loader.h | 10 +++ 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/scoring_framework/score_events.cxx b/scoring_framework/score_events.cxx index 424f9d3..64dd0c4 100644 --- a/scoring_framework/score_events.cxx +++ b/scoring_framework/score_events.cxx @@ -2292,6 +2292,11 @@ int main( int argc, char *argv[] ) return EXIT_SUCCESS; } + if (! input_args.sanity_check() ) + { + return EXIT_SUCCESS; + } + activity_selector_type what_act = scoring_args.deduce_activity(); LOG_INFO( main_logger, "Activity deduction: " << what_act ); diff --git a/scoring_framework/score_tracks_loader.cxx b/scoring_framework/score_tracks_loader.cxx index 0296048..e48349c 100644 --- a/scoring_framework/score_tracks_loader.cxx +++ b/scoring_framework/score_tracks_loader.cxx @@ -75,6 +75,10 @@ using kwiver::track_oracle::track_handle_type; using kwiver::track_oracle::track_oracle_core; using kwiver::track_oracle::file_format_schema_type; using kwiver::track_oracle::file_format_manager; +using kwiver::track_oracle::file_format_enum; +using kwiver::track_oracle::file_format_base; +using kwiver::track_oracle::file_format_type; +using kwiver::track_oracle::format_map_type; using kwiver::track_oracle::track_vpd_track_type; using kwiver::track_oracle::track_vpd_event_type; using kwiver::track_oracle::track_comms_xml_type; @@ -124,6 +128,8 @@ class track_record_type // ground-truth and computed tracks. If timestamp_generator_map is // empty, then the source time already had timestamps (e.g. kw18). // +// If the tf_type is not invalid, only load that type of file or fail. +// // When the input file is a VIRAT scenario, also return a map of // query_id -> activity_list. When the other input is a comms_xml // from the test harness, which only has query_ids, we can use this @@ -132,11 +138,16 @@ class track_record_type struct input_source_type { - input_source_type( const string& arg, vul_arg< string >& path_override, double fps, size_t min_track_length_param ); + input_source_type( const string& arg, + vul_arg< string >& path_override, + double fps, + size_t min_track_length_param, + file_format_enum tft ); vector< string > fn_list; timestamp_generator_map_type timestamp_generator_map; map< string, vector< size_t > > qid2activity_map; size_t min_track_length; + file_format_enum tf_type; }; /// @@ -343,8 +354,9 @@ input_source_type ::input_source_type( const string& arg, vul_arg< string >& path_override, double fps, - size_t min_track_length_param ) - : min_track_length( min_track_length_param ) + size_t min_track_length_param, + file_format_enum tft ) + : min_track_length( min_track_length_param ), tf_type( tft ) { // Either arg starts with "@", in which case it's a list, // or it can be loaded as a scenario file, @@ -846,13 +858,28 @@ load_tracks_from_file( const input_source_type& src ) { track_record_type r; r.set_src_fn( src.fn_list[i] ); - LOG_INFO( main_logger, "About to load file " << i+1 << " of " << src.fn_list.size() << " : " << r.src_fn() << "..."); track_handle_list_type input_tracks; - if ( ! file_format_manager::read( r.src_fn(), input_tracks )) + if (src.tf_type != kwiver::track_oracle::TF_INVALID_TYPE ) { - LOG_ERROR( main_logger, "Couldn't load tracks from '" << r.src_fn() << "'"); - ret.clear(); - return ret; + file_format_base* b = file_format_manager::get_format( src.tf_type ); + LOG_INFO( main_logger, "About to load file '" << i+1 << " of " << src.fn_list.size() << + " (forced format " << file_format_type::to_string( src.tf_type ) << ") : " << r.src_fn() << " ..."); + if (! b->read( r.src_fn(), input_tracks )) + { + LOG_ERROR( main_logger, "Couldn't load tracks from '" << r.src_fn() << "'"); + ret.clear(); + return ret; + } + } + else + { + LOG_INFO( main_logger, "About to load file " << i+1 << " of " << src.fn_list.size() << " : " << r.src_fn() << "..."); + if ( ! file_format_manager::read( r.src_fn(), input_tracks )) + { + LOG_ERROR( main_logger, "Couldn't load tracks from '" << r.src_fn() << "'"); + ret.clear(); + return ret; + } } LOG_INFO( main_logger, "read " << input_tracks.size() << " tracks"); // only keep tracks longer than the requested number of states @@ -1061,12 +1088,24 @@ decompose_track_into_frames( const track_handle_type& t ) return ret; } - - bool input_args_type -::process( track_handle_list_type& computed_tracks, track_handle_list_type& truth_tracks ) +::sanity_check() { + if ((this->computed_format() == "help") || (this->truth_format() == "help")) + { + LOG_INFO( main_logger, "Valid file format names: " ); + for (const auto f: file_format_manager::get_format_map() ) + { + if (f.first != track_oracle::TF_INVALID_TYPE) + { + LOG_INFO( main_logger, file_format_type::to_string( f.first ) << " : " << f.second->format_description() ); + } + } + return false; + } + + if (this->time_window() == "help") { LOG_INFO( main_logger, string( "\n" ) << @@ -1089,6 +1128,14 @@ ::process( track_handle_list_type& computed_tracks, track_handle_list_type& trut << "', but this directory does not exist" ); return false; } + return true; +} + + +bool +input_args_type +::process( track_handle_list_type& computed_tracks, track_handle_list_type& truth_tracks ) +{ // Even though we don't use the time window filter for a while, create it here // to find parsing errors quickly. We can catch parsing errors of explicit @@ -1133,8 +1180,17 @@ ::process( track_handle_list_type& computed_tracks, track_handle_list_type& trut // Create input sources from computed and truth tracks args // - input_source_type computed_src( this->computed_tracks_fn(), this->computed_path, this->computed_fps(), min_computed_length ); - input_source_type truth_src( this->truth_tracks_fn(), this->truth_path, this->truth_fps(), min_truth_length ); + file_format_enum forced_computed_type = + this->computed_format.set() + ? file_format_type::from_string( this->computed_format() ) + : track_oracle::TF_INVALID_TYPE; + input_source_type computed_src( this->computed_tracks_fn(), this->computed_path, this->computed_fps(), min_computed_length, forced_computed_type ); + + file_format_enum forced_truth_type = + this->truth_format.set() + ? file_format_type::from_string( this->truth_format() ) + : track_oracle::TF_INVALID_TYPE; + input_source_type truth_src( this->truth_tracks_fn(), this->truth_path, this->truth_fps(), min_truth_length, forced_truth_type ); // verify we have plausible data in the input sources if (computed_src.fn_list.empty()) diff --git a/scoring_framework/score_tracks_loader.h b/scoring_framework/score_tracks_loader.h index f2a480f..34cf1f4 100644 --- a/scoring_framework/score_tracks_loader.h +++ b/scoring_framework/score_tracks_loader.h @@ -43,6 +43,12 @@ struct SCORE_TRACKS_LOADER_EXPORT input_args_type vul_arg< std::string > computed_tracks_fn; vul_arg< std::string > truth_tracks_fn; + // if set, will override autodetection of file formats + // 'help' to list valid formats + + vul_arg< std::string > computed_format; + vul_arg< std::string > truth_format; + // if set, will override path components in file when loading // Example: if --truth-path=/data/foo/bar, then: // @@ -129,6 +135,8 @@ struct SCORE_TRACKS_LOADER_EXPORT input_args_type input_args_type() : computed_tracks_fn( "--computed-tracks", "Computed tracks file, or @filelist reads list of files" ), truth_tracks_fn( "--truth-tracks", "Truth tracks files, scenario, or @filelist reads list of files" ), + computed_format( "--computed-format", "Disable computed format auto-detection; force to be this format; 'help' to list" ), + truth_format( "--truth-format", "Disable truth format auto-detection; force to be this format; 'help' to list" ), computed_path( "--computed-path", "All computed files will be loaded from this directory, overriding other paths", "" ), truth_path( "--truth-path", "All truth files will be loaded from this directory, overriding other paths", "" ), computed_fps( "--computed-fps", "Computed tracks frames-per-second", 29.97 / 3 ), @@ -150,6 +158,8 @@ struct SCORE_TRACKS_LOADER_EXPORT input_args_type {} + bool sanity_check(); + bool process( kwiver::track_oracle::track_handle_list_type& computed_tracks, kwiver::track_oracle::track_handle_list_type& truth_tracks ); From 6c65a8a8f051703c6679b26daacabd50b9767d74 Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Wed, 30 Nov 2022 18:08:14 -0500 Subject: [PATCH 5/7] Drop JSON code --- scoring_framework/CMakeLists.txt | 26 ++++++------- scoring_framework/score_tracks.cxx | 60 ------------------------------ 2 files changed, 12 insertions(+), 74 deletions(-) diff --git a/scoring_framework/CMakeLists.txt b/scoring_framework/CMakeLists.txt index 4ff0334..f558806 100644 --- a/scoring_framework/CMakeLists.txt +++ b/scoring_framework/CMakeLists.txt @@ -173,20 +173,18 @@ target_link_libraries(score_tracks_hadwav # Scoring ######################################## -if (fletch_ENABLED_libjson) - set(scoring_json_src) - set(json_lib ${LIBJSON_LIBRARY}) - - kwiver_add_executable( score_tracks score_tracks.cxx) - target_link_libraries( score_tracks - PRIVATE score_tracks_loader - score_tracks_hadwav - track_oracle - track_oracle_file_formats - timestamp_utilities - vital_logger - ${json_lib} ) -endif() +set(scoring_json_src) +set(json_lib ${LIBJSON_LIBRARY}) + +add_definitions( -DJSON_NO_EXCEPTIONS ) +kwiver_add_executable( score_tracks score_tracks.cxx) +target_link_libraries( score_tracks + PRIVATE score_tracks_loader + score_tracks_hadwav + track_oracle + track_oracle_file_formats + timestamp_utilities + vital_logger ) kwiver_add_executable( score_events score_events.cxx ) target_link_libraries( score_events diff --git a/scoring_framework/score_tracks.cxx b/scoring_framework/score_tracks.cxx index 3191813..424ddc0 100644 --- a/scoring_framework/score_tracks.cxx +++ b/scoring_framework/score_tracks.cxx @@ -31,7 +31,6 @@ #include #include -#include #include static kwiver::vital::logger_handle_t main_logger( kwiver::vital::get_logger( __FILE__ ) ); @@ -64,14 +63,12 @@ struct output_args_type { vul_arg< string > track_stats_fn; vul_arg< string > target_stats_fn; - vul_arg< string > json_dump_fn; vul_arg< string > matches_dump_fn; vul_arg< string > frame_level_matches_fn; output_args_type() : track_stats_fn( "--track-stats", "write track purity / continuity to file" ), target_stats_fn( "--target-stats", "write target purity / continuity to file" ), - json_dump_fn( "--j", "write results in json format to file" ), matches_dump_fn( "--matches", "write track match info to file" ), frame_level_matches_fn( "--frame-level-match","writes out gt to cp frame level match information") {} @@ -668,8 +665,6 @@ int main( int argc, char *argv[] ) write_activity_overlay( os, aoi_filtered_truth_tracks, aoi_filtered_computed_tracks, p1 ); } - JSONNode json_root(JSON_NODE); // for json output option - if(score_hadwav_flag()) { track2track_phase2_hadwav p2( verbose_flag() ); @@ -755,61 +750,6 @@ int main( int argc, char *argv[] ) cout << " Avg target (continuity, purity ): " << p3.avg_target_continuity << ", " << p3.avg_target_purity << endl; cout << " Track-frame-precision: " << p2.trackFramePrecision << endl; - - if ( output_args.json_dump_fn.set() ) - { - // Add json objects - JSONNode hadwav_node(JSON_NODE); - hadwav_node.set_name("hadwav-results"); - - hadwav_node.push_back(JSONNode("detection-pd", p2.detectionPD)); - hadwav_node.push_back(JSONNode("detection-false-alarms", p2.detectionFalseAlarms)); - hadwav_node.push_back(JSONNode("detection-probability-false-alarms", p2.detectionPFalseAlarm)); - hadwav_node.push_back(JSONNode("track-pd", p3.trackPd)); - hadwav_node.push_back(JSONNode("track-fa", p3.trackFA)); - hadwav_node.push_back(JSONNode("track-fp", p2.trackFramePrecision)); - if (norm.first) - { - hadwav_node.push_back(JSONNode("frame-nfar", p2.frameFA/norm.second)); - hadwav_node.push_back(JSONNode("track-nfar", p3.trackFA/norm.second)); - } - else - { - hadwav_node.push_back(JSONNode("frame-nfar", "not computed")); - hadwav_node.push_back(JSONNode("track-nfar", "not computed")); - } - hadwav_node.push_back(JSONNode("avg-track-continuity", p3.avg_track_continuity)); - hadwav_node.push_back(JSONNode("avg-track-purity", p3.avg_track_purity)); - hadwav_node.push_back(JSONNode("avg-target-continuity", p3.avg_target_continuity)); - hadwav_node.push_back(JSONNode("avg-target-purity", p3.avg_target_purity)); - - json_root.push_back(hadwav_node); - } - } - - if ( output_args.json_dump_fn.set() ) - { - // Add json objects - JSONNode version_node(JSON_NODE); - version_node.set_name("vidtk-meta"); - // version_node.push_back(JSONNode("version", VIDTK_GIT_VERSION)); - version_node.push_back(JSONNode("version", "not-available" )); - json_root.push_back(version_node); - } - - if ( output_args.json_dump_fn.set() ) - { - ofstream os( output_args.json_dump_fn().c_str() ); - if ( ! os ) - { - LOG_ERROR( main_logger, "Couldn't dump results to '" << output_args.json_dump_fn() << "'?"); - } - else - { - string json_output = json_root.write_formatted(); - os << json_output; - os.close(); - } } if ( track_dump_fn_arg.set() ) From d818f238a8cb99cb0a11d47c88cdbcbf5babfe11 Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Mon, 8 Dec 2025 05:39:29 -0500 Subject: [PATCH 6/7] Updates for latest KWIVER --- CMake/kwant-depends-kwiver.cmake | 1 - CMakeLists.txt | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMake/kwant-depends-kwiver.cmake b/CMake/kwant-depends-kwiver.cmake index 9e4d760..3afcaf1 100644 --- a/CMake/kwant-depends-kwiver.cmake +++ b/CMake/kwant-depends-kwiver.cmake @@ -9,4 +9,3 @@ link_directories("${KWIVER_LIBRARY_DIRS}") include(kwiver-cmake-future) include(kwiver-utils) include(kwiver-flags) -include(kwiver-configcheck) diff --git a/CMakeLists.txt b/CMakeLists.txt index cceb87f..476b00d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,10 @@ set(KWANT_VERSION_MINOR 1) set(KWANT_VERSION_PATCH 0) set(KWANT_VERSION "${KWANT_VERSION_MAJOR}.${KWANT_VERSION_MINOR}.${KWANT_VERSION_PATCH}") +# C++17 is required for latest KWIVER +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + ### # Ask for kwiver build directory # From 618920b12b2339dfbef8e3742b3a55fe07934d0f Mon Sep 17 00:00:00 2001 From: Matt Dawkins Date: Thu, 22 Jan 2026 14:46:07 -0500 Subject: [PATCH 7/7] Update cmake version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 476b00d..f0154c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.5) project( KWANT )