pal::string_t resolve_sdk_version(pal::string_t sdk_path) { trace::verbose(_X("--- Resolving SDK version from SDK dir [%s]"), sdk_path.c_str()); pal::string_t retval; std::vector<pal::string_t> versions; pal::readdir(sdk_path, &versions); fx_ver_t max_ver(-1, -1, -1); fx_ver_t max_pre(-1, -1, -1); for (const auto& version : versions) { trace::verbose(_X("Considering version... [%s]"), version.c_str()); fx_ver_t ver(-1, -1, -1); if (fx_ver_t::parse(version, &ver, true)) { max_ver = std::max(ver, max_ver); } if (fx_ver_t::parse(version, &ver, false)) { max_pre = std::max(ver, max_pre); } } // No production, use the max pre-release. if (max_ver == fx_ver_t(-1, -1, -1)) { trace::verbose(_X("No production version found, so using latest prerelease")); max_ver = max_pre; } pal::string_t max_ver_str = max_ver.as_str(); append_path(&sdk_path, max_ver_str.c_str()); trace::verbose(_X("Checking if resolved SDK dir [%s] exists"), sdk_path.c_str()); if (pal::directory_exists(sdk_path)) { retval = sdk_path; } trace::verbose(_X("Resolved SDK dir is [%s]"), retval.c_str()); return retval; }
bool parse_internal(const pal::string_t& ver, fx_ver_t* fx_ver, bool parse_only_production) { size_t maj_start = 0; size_t maj_sep = ver.find(_X('.')); if (maj_sep == pal::string_t::npos) { return false; } unsigned major = 0; if (!try_stou(ver.substr(maj_start, maj_sep), &major)) { return false; } size_t min_start = maj_sep + 1; size_t min_sep = ver.find(_X('.'), min_start); if (min_sep == pal::string_t::npos) { return false; } unsigned minor = 0; if (!try_stou(ver.substr(min_start, min_sep - min_start), &minor)) { return false; } unsigned patch = 0; size_t pat_start = min_sep + 1; size_t pat_sep = ver.find_first_not_of(_X("0123456789"), pat_start); if (pat_sep == pal::string_t::npos) { if (!try_stou(ver.substr(pat_start), &patch)) { return false; } *fx_ver = fx_ver_t(major, minor, patch); return true; } if (parse_only_production) { // This is a prerelease or has build suffix. return false; } if (!try_stou(ver.substr(pat_start, pat_sep - pat_start), &patch)) { return false; } size_t pre_start = pat_sep; size_t pre_sep = ver.find(_X('+'), pre_start); if (pre_sep == pal::string_t::npos) { *fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start)); return true; } else { size_t build_start = pre_sep + 1; *fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start, pre_sep - pre_start), ver.substr(build_start)); return true; } }
void deps_resolver_t::resolve_additional_deps(const arguments_t& args, const deps_json_t::rid_fallback_graph_t& rid_fallback_graph) { if (!m_is_framework_dependent || m_host_mode == host_mode_t::libhost) { // Additional deps.json support is only available for framework-dependent apps due to the following constraints: // // 1) Unlike framework-dependent Apps, self-contained apps do not have details of the SharedFX and Version they target. // 2) Unlike framework-dependent Apps, self-contained apps do not have RID fallback graph that is required for looking up // the correct native assets from nuget packages. // // Additional deps.json support is not available for libhost scenarios. For example, if CoreCLR is instantiated from a // library context (i.e. comhost) the activation of classes are assumed to be performed in an AssemblyLoadContext. This // assumption is made because it is possible an existing CoreCLR was already activated and it may not satisfy the current // needs of the new class. return; } pal::string_t additional_deps_serialized = args.additional_deps_serialized; if (additional_deps_serialized.empty()) { return; } pal::string_t additional_deps_path; pal::stringstream_t ss(additional_deps_serialized); // Process the delimiter separated custom deps files. while (std::getline(ss, additional_deps_path, PATH_SEPARATOR)) { // If it's a single deps file, insert it in 'm_additional_deps_files' if (ends_with(additional_deps_path, _X(".deps.json"), false)) { if (pal::file_exists(additional_deps_path)) { trace::verbose(_X("Using specified additional deps.json: '%s'"), additional_deps_path.c_str()); m_additional_deps_files.push_back(additional_deps_path); } else { trace::warning(_X("Warning: Specified additional deps.json does not exist: '%s'"), additional_deps_path.c_str()); } } else { for (int i = 1; i < m_fx_definitions.size(); ++i) { fx_ver_t most_compatible_deps_folder_version; fx_ver_t framework_found_version; fx_ver_t::parse(m_fx_definitions[i]->get_found_version(), &framework_found_version); // We'll search deps directories in 'base_dir'/shared/fx_name/ for closest compatible patch version pal::string_t additional_deps_path_fx = additional_deps_path; append_path(&additional_deps_path_fx, _X("shared")); append_path(&additional_deps_path_fx, m_fx_definitions[i]->get_name().c_str()); trace::verbose(_X("Searching for most compatible deps directory in [%s]"), additional_deps_path_fx.c_str()); std::vector<pal::string_t> deps_dirs; pal::readdir_onlydirectories(additional_deps_path_fx, &deps_dirs); for (pal::string_t dir : deps_dirs) { fx_ver_t ver; if (fx_ver_t::parse(dir, &ver)) { if (ver > most_compatible_deps_folder_version && ver <= framework_found_version && ver.get_major() == framework_found_version.get_major() && ver.get_minor() == framework_found_version.get_minor()) { most_compatible_deps_folder_version = ver; } } } if (most_compatible_deps_folder_version == fx_ver_t()) { trace::verbose(_X("No additional deps directory less than or equal to [%s] found with same major and minor version."), framework_found_version.as_str().c_str()); } else { trace::verbose(_X("Found additional deps directory [%s]"), most_compatible_deps_folder_version.as_str().c_str()); append_path(&additional_deps_path_fx, most_compatible_deps_folder_version.as_str().c_str()); // The resulting list will be empty if 'additional_deps_path_fx' is not a valid directory path std::vector<pal::string_t> list; pal::readdir(additional_deps_path_fx, _X("*.deps.json"), &list); for (pal::string_t json_file : list) { pal::string_t json_full_path = additional_deps_path_fx; append_path(&json_full_path, json_file.c_str()); m_additional_deps_files.push_back(json_full_path); trace::verbose(_X("Using specified additional deps.json: '%s'"), json_full_path.c_str()); } } } } } for (pal::string_t json_file : m_additional_deps_files) { m_additional_deps.push_back(std::unique_ptr<deps_json_t>( new deps_json_t(true, json_file, rid_fallback_graph))); } }