Merge pull request #1243 from schellap/dotnethome

Remove DOTNET_HOME from the CoreCLR probe path
This commit is contained in:
Senthil 2016-02-12 17:43:13 -08:00
commit 328e806069
9 changed files with 155 additions and 77 deletions

View file

@ -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";

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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);
}

View file

@ -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)

View file

@ -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;