Merge pull request #1243 from schellap/dotnethome
Remove DOTNET_HOME from the CoreCLR probe path
This commit is contained in:
commit
328e806069
9 changed files with 155 additions and 77 deletions
|
@ -24,7 +24,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
public static readonly string DynamicLibSuffix = CurrentPlatform == Platform.Windows ? ".dll" :
|
||||
CurrentPlatform == Platform.Darwin ? ".dylib" : ".so";
|
||||
|
||||
public static readonly string LibCoreClrName = (CurrentPlatform == Platform.Windows ? "coreclr" : "libcoreclr") + DynamicLibSuffix;
|
||||
public static readonly string LibCoreClrFileName = (CurrentPlatform == Platform.Windows ? "coreclr" : "libcoreclr");
|
||||
public static readonly string LibCoreClrName = LibCoreClrFileName + DynamicLibSuffix;
|
||||
|
||||
public static readonly string RuntimeIdentifier = CurrentPlatform == Platform.Windows ? "win7-x64" :
|
||||
CurrentPlatform == Platform.Darwin ? "osx.10.10-x64" : "ubuntu.14.04-x64";
|
||||
|
|
|
@ -123,7 +123,7 @@ void add_mscorlib_to_tpa(const pal::string_t& clr_dir, std::set<pal::string_t>*
|
|||
pal::string_t mscorlib_path = clr_dir + DIR_SEPARATOR + _X("mscorlib.dll");
|
||||
if (pal::file_exists(mscorlib_path))
|
||||
{
|
||||
add_tpa_asset(_X("mscorlib"), mscorlib_ni_path, items, output);
|
||||
add_tpa_asset(_X("mscorlib"), mscorlib_path, items, output);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -346,6 +346,20 @@ bool deps_resolver_t::load()
|
|||
replace_char(&entry.relative_path, _X('\\'), _X('/'));
|
||||
|
||||
m_deps_entries.push_back(entry);
|
||||
|
||||
trace::verbose(_X("Added deps entry [%d] [%s, %s, %s]"), m_deps_entries.size() - 1, entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str());
|
||||
|
||||
static_assert(std::is_same<std::vector<deps_entry_t>, decltype(m_deps_entries)>::value, "decltype(m_deps_entries) not a vector, took index based on size.");
|
||||
if (entry.asset_type == _X("native") &&
|
||||
entry.asset_name == LIBCORECLR_FILENAME)
|
||||
{
|
||||
m_coreclr_index = m_deps_entries.size() - 1;
|
||||
trace::verbose(_X("Found coreclr from deps entry [%d] [%s, %s, %s]"),
|
||||
m_coreclr_index,
|
||||
entry.library_name.c_str(),
|
||||
entry.library_version.c_str(),
|
||||
entry.relative_path.c_str());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -379,9 +393,9 @@ void deps_resolver_t::get_local_assemblies(const pal::string_t& dir)
|
|||
std::vector<pal::string_t> files;
|
||||
pal::readdir(dir, &files);
|
||||
|
||||
for (const auto& file : files)
|
||||
for (const auto& ext : managed_ext)
|
||||
{
|
||||
for (const auto& ext : managed_ext)
|
||||
for (const auto& file : files)
|
||||
{
|
||||
// Nothing to do if file length is smaller than expected ext.
|
||||
if (file.length() <= ext.length())
|
||||
|
@ -414,6 +428,67 @@ void deps_resolver_t::get_local_assemblies(const pal::string_t& dir)
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Resolve coreclr directory from the deps file.
|
||||
//
|
||||
// Description:
|
||||
// Look for CoreCLR from the dependency list in the package cache and then
|
||||
// the packages directory.
|
||||
//
|
||||
pal::string_t deps_resolver_t::resolve_coreclr_dir(
|
||||
const pal::string_t& app_dir,
|
||||
const pal::string_t& package_dir,
|
||||
const pal::string_t& package_cache_dir)
|
||||
{
|
||||
// Runtime servicing
|
||||
trace::verbose(_X("Probing for CoreCLR in servicing dir=[%s]"), m_runtime_svc.c_str());
|
||||
if (!m_runtime_svc.empty())
|
||||
{
|
||||
pal::string_t svc_clr = m_runtime_svc;
|
||||
append_path(&svc_clr, _X("runtime"));
|
||||
append_path(&svc_clr, _X("coreclr"));
|
||||
|
||||
if (coreclr_exists_in_dir(svc_clr))
|
||||
{
|
||||
return svc_clr;
|
||||
}
|
||||
}
|
||||
|
||||
// Package cache.
|
||||
trace::verbose(_X("Probing for CoreCLR in package cache=[%s] deps index: [%d]"), package_cache_dir.c_str(), m_coreclr_index);
|
||||
pal::string_t coreclr_cache;
|
||||
if (m_coreclr_index >= 0 && !package_cache_dir.empty() &&
|
||||
m_deps_entries[m_coreclr_index].to_hash_matched_path(package_cache_dir, &coreclr_cache))
|
||||
{
|
||||
return get_directory(coreclr_cache);
|
||||
}
|
||||
|
||||
// App dir.
|
||||
trace::verbose(_X("Probing for CoreCLR in app directory=[%s]"), app_dir.c_str());
|
||||
if (coreclr_exists_in_dir(app_dir))
|
||||
{
|
||||
return app_dir;
|
||||
}
|
||||
|
||||
// Packages dir
|
||||
trace::verbose(_X("Probing for CoreCLR in packages=[%s] deps index: [%d]"), package_dir.c_str(), m_coreclr_index);
|
||||
pal::string_t coreclr_package;
|
||||
if (m_coreclr_index >= 0 && !package_dir.empty() &&
|
||||
m_deps_entries[m_coreclr_index].to_full_path(package_dir, &coreclr_package))
|
||||
{
|
||||
return get_directory(coreclr_package);
|
||||
}
|
||||
|
||||
// Use platform-specific search algorithm
|
||||
pal::string_t install_dir;
|
||||
if (pal::find_coreclr(&install_dir))
|
||||
{
|
||||
return install_dir;
|
||||
}
|
||||
|
||||
return pal::string_t();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Resolve the TPA list order.
|
||||
//
|
||||
|
@ -549,11 +624,14 @@ void deps_resolver_t::resolve_probe_dirs(
|
|||
pal::string_t candidate;
|
||||
|
||||
// Take care of the secondary cache path
|
||||
for (const deps_entry_t& entry : m_deps_entries)
|
||||
if (!package_cache_dir.empty())
|
||||
{
|
||||
if (entry.asset_type == asset_type && entry.to_hash_matched_path(package_cache_dir, &candidate))
|
||||
for (const deps_entry_t& entry : m_deps_entries)
|
||||
{
|
||||
add_unique_path(asset_type, action(candidate), &items, output);
|
||||
if (entry.asset_type == asset_type && entry.to_hash_matched_path(package_cache_dir, &candidate))
|
||||
{
|
||||
add_unique_path(asset_type, action(candidate), &items, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,11 +639,14 @@ void deps_resolver_t::resolve_probe_dirs(
|
|||
add_unique_path(asset_type, app_dir, &items, output);
|
||||
|
||||
// Take care of the package restore path
|
||||
for (const deps_entry_t& entry : m_deps_entries)
|
||||
if (!package_dir.empty())
|
||||
{
|
||||
if (entry.asset_type == asset_type && entry.to_full_path(package_dir, &candidate))
|
||||
for (const deps_entry_t& entry : m_deps_entries)
|
||||
{
|
||||
add_unique_path(asset_type, action(candidate), &items, output);
|
||||
if (entry.asset_type == asset_type && entry.to_full_path(package_dir, &candidate))
|
||||
{
|
||||
add_unique_path(asset_type, action(candidate), &items, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ class deps_resolver_t
|
|||
public:
|
||||
deps_resolver_t(const arguments_t& args)
|
||||
: m_svc(args.dotnet_servicing)
|
||||
, m_runtime_svc(args.dotnet_runtime_servicing)
|
||||
, m_coreclr_index(-1)
|
||||
{
|
||||
m_deps_valid = parse_deps_file(args);
|
||||
}
|
||||
|
@ -56,6 +58,11 @@ public:
|
|||
const pal::string_t& clr_dir,
|
||||
probe_paths_t* probe_paths);
|
||||
|
||||
pal::string_t resolve_coreclr_dir(
|
||||
const pal::string_t& app_dir,
|
||||
const pal::string_t& package_dir,
|
||||
const pal::string_t& package_cache_dir);
|
||||
|
||||
private:
|
||||
|
||||
bool load();
|
||||
|
@ -85,6 +92,9 @@ private:
|
|||
// Servicing index to resolve serviced assembly paths.
|
||||
servicing_index_t m_svc;
|
||||
|
||||
// Runtime servicing directory.
|
||||
pal::string_t m_runtime_svc;
|
||||
|
||||
// Map of simple name -> full path of local assemblies populated in priority
|
||||
// order of their extensions.
|
||||
std::unordered_map<pal::string_t, pal::string_t> m_local_assemblies;
|
||||
|
@ -92,6 +102,9 @@ private:
|
|||
// Entries in the dep file
|
||||
std::vector<deps_entry_t> m_deps_entries;
|
||||
|
||||
// Special entry for coreclr in the deps entries
|
||||
int m_coreclr_index;
|
||||
|
||||
// The dep file path
|
||||
pal::string_t m_deps_path;
|
||||
|
||||
|
|
|
@ -20,59 +20,7 @@ enum StatusCode
|
|||
ResolverResolveFailure = 0x87,
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// resolve_clr_path: Resolve CLR Path in priority order
|
||||
//
|
||||
// Description:
|
||||
// Check if CoreCLR library exists in runtime servicing dir or app
|
||||
// local or DOTNET_HOME directory in that order of priority. If these
|
||||
// fail to locate CoreCLR, then check platform-specific search.
|
||||
//
|
||||
// Returns:
|
||||
// "true" if path to the CoreCLR dir can be resolved in "clr_path"
|
||||
// parameter. Else, returns "false" with "clr_path" unmodified.
|
||||
//
|
||||
bool resolve_clr_path(const arguments_t& args, pal::string_t* clr_path)
|
||||
{
|
||||
const pal::string_t* dirs[] = {
|
||||
&args.dotnet_runtime_servicing, // DOTNET_RUNTIME_SERVICING
|
||||
&args.app_dir, // APP LOCAL
|
||||
&args.dotnet_home // DOTNET_HOME
|
||||
};
|
||||
for (int i = 0; i < sizeof(dirs) / sizeof(dirs[0]); ++i)
|
||||
{
|
||||
if (dirs[i]->empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// App dir should contain coreclr, so skip appending path.
|
||||
pal::string_t cur_dir = *dirs[i];
|
||||
if (dirs[i] != &args.app_dir)
|
||||
{
|
||||
append_path(&cur_dir, _X("runtime"));
|
||||
append_path(&cur_dir, _X("coreclr"));
|
||||
}
|
||||
|
||||
// Found coreclr in priority order.
|
||||
if (coreclr_exists_in_dir(cur_dir))
|
||||
{
|
||||
clr_path->assign(cur_dir);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Use platform-specific search algorithm
|
||||
pal::string_t home_dir = args.dotnet_home;
|
||||
if (pal::find_coreclr(&home_dir))
|
||||
{
|
||||
clr_path->assign(home_dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int run(const arguments_t& args, const pal::string_t& clr_path)
|
||||
int run(const arguments_t& args)
|
||||
{
|
||||
// Load the deps resolver
|
||||
deps_resolver_t resolver(args);
|
||||
|
@ -90,6 +38,17 @@ int run(const arguments_t& args, const pal::string_t& clr_path)
|
|||
}
|
||||
trace::info(_X("Package directory: %s"), packages_dir.empty() ? _X("not specified") : packages_dir.c_str());
|
||||
|
||||
pal::string_t clr_path = resolver.resolve_coreclr_dir(args.app_dir, packages_dir, args.dotnet_packages_cache);
|
||||
if (clr_path.empty() || !pal::realpath(&clr_path))
|
||||
{
|
||||
trace::error(_X("Could not resolve coreclr path"));
|
||||
return StatusCode::CoreClrResolveFailure;
|
||||
}
|
||||
else
|
||||
{
|
||||
trace::info(_X("CoreCLR directory: %s"), clr_path.c_str());
|
||||
}
|
||||
|
||||
probe_paths_t probe_paths;
|
||||
if (!resolver.resolve_probe_paths(args.app_dir, packages_dir, args.dotnet_packages_cache, clr_path, &probe_paths))
|
||||
{
|
||||
|
@ -240,13 +199,5 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
|
|||
return StatusCode::InvalidArgFailure;
|
||||
}
|
||||
|
||||
// Resolve CLR path
|
||||
pal::string_t clr_path;
|
||||
if (!resolve_clr_path(args, &clr_path))
|
||||
{
|
||||
trace::error(_X("Could not resolve coreclr path"));
|
||||
return StatusCode::CoreClrResolveFailure;
|
||||
}
|
||||
pal::realpath(&clr_path);
|
||||
return run(args, clr_path);
|
||||
return run(args);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ if(WIN32)
|
|||
endif()
|
||||
add_compile_options($<$<CONFIG:Debug>:-DDEBUG>)
|
||||
add_compile_options($<$<CONFIG:Debug>:/Od>)
|
||||
add_compile_options($<$<CONFIG:Debug>:/Gm>)
|
||||
add_compile_options(/DEBUG)
|
||||
add_compile_options(/GS)
|
||||
add_compile_options(/W1)
|
||||
|
|
|
@ -48,14 +48,19 @@
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define LIB_PREFIX
|
||||
#define MAKE_LIBNAME(NAME) (_X(NAME) _X(".dll"))
|
||||
#elif defined(__APPLE__)
|
||||
#define MAKE_LIBNAME(NAME) (_X("lib") _X(NAME) _X(".dylib"))
|
||||
#define LIB_PREFIX _X("lib")
|
||||
#define MAKE_LIBNAME(NAME) (LIB_PREFIX _X(NAME) _X(".dylib"))
|
||||
#else
|
||||
#define MAKE_LIBNAME(NAME) (_X("lib") _X(NAME) _X(".so"))
|
||||
#define LIB_PREFIX _X("lib")
|
||||
#define MAKE_LIBNAME(NAME) (LIB_PREFIX _X(NAME) _X(".so"))
|
||||
#endif
|
||||
|
||||
#define LIBCORECLR_FILENAME (LIB_PREFIX _X("coreclr"))
|
||||
#define LIBCORECLR_NAME MAKE_LIBNAME("coreclr")
|
||||
|
||||
#if !defined(PATH_MAX) && !defined(_WIN32)
|
||||
|
@ -118,7 +123,7 @@ namespace pal
|
|||
inline pal::string_t to_palstring(const std::string& str) { return str; }
|
||||
inline std::string to_stdstring(const pal::string_t& str) { return str; }
|
||||
inline void to_palstring(const char* str, pal::string_t* out) { out->assign(str); }
|
||||
inline void to_stdstring(const pal::char_t* str, std::string* out) { out->assign(str); }
|
||||
inline void to_stdstring(const char_t* str, std::string* out) { out->assign(str); }
|
||||
#endif
|
||||
bool realpath(string_t* path);
|
||||
bool file_exists(const string_t& path);
|
||||
|
|
|
@ -8,7 +8,7 @@ bool coreclr_exists_in_dir(const pal::string_t& candidate)
|
|||
{
|
||||
pal::string_t test(candidate);
|
||||
append_path(&test, LIBCORECLR_NAME);
|
||||
trace::verbose(_X("checking for CoreCLR in default location: %s"), test.c_str());
|
||||
trace::verbose(_X("Checking if CoreCLR path exists=[%s]"), test.c_str());
|
||||
return pal::file_exists(test);
|
||||
}
|
||||
|
||||
|
|
|
@ -404,6 +404,33 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
var libraryExporter = _rootProject.CreateExporter(_args.ConfigValue, _args.BuildBasePathValue);
|
||||
var executable = new Executable(_rootProject, outputPaths, libraryExporter);
|
||||
executable.MakeCompilationOutputRunnable();
|
||||
|
||||
PatchMscorlibNextToCoreClr(_rootProject, _args.ConfigValue);
|
||||
}
|
||||
|
||||
// Workaround: CoreCLR packaging doesn't include side by side mscorlib, so copy it at build
|
||||
// time. See: https://github.com/dotnet/cli/issues/1374
|
||||
private static void PatchMscorlibNextToCoreClr(ProjectContext context, string config)
|
||||
{
|
||||
{
|
||||
foreach (var exp in context.CreateExporter(config).GetAllExports())
|
||||
{
|
||||
var coreclrLib = exp.NativeLibraries.FirstOrDefault(nLib =>
|
||||
string.Equals(Constants.LibCoreClrFileName, nLib.Name));
|
||||
if (string.IsNullOrEmpty(coreclrLib.ResolvedPath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var coreclrDir = Path.GetDirectoryName(coreclrLib.ResolvedPath);
|
||||
if (File.Exists(Path.Combine(coreclrDir, "mscorlib.dll")) ||
|
||||
File.Exists(Path.Combine(coreclrDir, "mscorlib.ni.dll")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var mscorlibFile = exp.RuntimeAssemblies.FirstOrDefault(r => r.Name.Equals("mscorlib") || r.Name.Equals("mscorlib.ni")).ResolvedPath;
|
||||
File.Copy(mscorlibFile, Path.Combine(coreclrDir, Path.GetFileName(mscorlibFile)), overwrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ISet<ProjectDescription> Sort(Dictionary<string, ProjectDescription> projects)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
|
|
Loading…
Reference in a new issue