mirror of https://github.com/mamba-org/mamba.git
Refactor env::which (#2997)
* Clenup env::which * RAII C calls * Refactor which functions * Remove second param from which * Change which namespace * Fix which extension * Add missing OSX headers * Add util::which tests
This commit is contained in:
parent
7c5f0562c4
commit
139b7ef020
|
@ -186,7 +186,6 @@ set(
|
|||
${LIBMAMBA_SOURCE_DIR}/core/context.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/download.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/download_progress_bar.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/environment.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/environments_manager.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/error_handling.cpp
|
||||
${LIBMAMBA_SOURCE_DIR}/core/transaction_context.cpp
|
||||
|
@ -285,7 +284,6 @@ set(
|
|||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/context.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/download.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/download_progress_bar.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/environment.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/environments_manager.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/error_handling.hpp
|
||||
${LIBMAMBA_INCLUDE_DIR}/mamba/core/satisfiability_error.hpp
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) 2019-2023, QuantStack and Mamba Contributors
|
||||
//
|
||||
// Distributed under the terms of the BSD 3-Clause License.
|
||||
//
|
||||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#ifndef MAMBA_CORE_ENVIRONMENT_HPP
|
||||
#define MAMBA_CORE_ENVIRONMENT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
|
||||
namespace mamba::env
|
||||
{
|
||||
auto which(const std::string& exe, const std::string& override_path = "") -> fs::u8path;
|
||||
auto which(const std::string& exe, const std::vector<fs::u8path>& search_paths) -> fs::u8path;
|
||||
}
|
||||
#endif
|
|
@ -9,17 +9,14 @@
|
|||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
#include "mamba/util/build.hpp"
|
||||
|
||||
namespace mamba::util
|
||||
{
|
||||
/**
|
||||
* Return the character use to separate paths.
|
||||
*/
|
||||
[[nodiscard]] constexpr auto pathsep() -> char;
|
||||
|
||||
/**
|
||||
* Get an environment variable encoded in UTF8.
|
||||
*/
|
||||
|
@ -91,6 +88,31 @@ namespace mamba::util
|
|||
*/
|
||||
[[nodiscard]] auto user_cache_dir() -> std::string;
|
||||
|
||||
/**
|
||||
* Return the character use to separate paths.
|
||||
*/
|
||||
[[nodiscard]] constexpr auto pathsep() -> char;
|
||||
|
||||
/**
|
||||
* Return the full path of a program from its name.
|
||||
*/
|
||||
[[nodiscard]] auto which(std::string_view exe) -> fs::u8path;
|
||||
|
||||
/**
|
||||
* Return the full path of a program from its name if found inside the given directories.
|
||||
*/
|
||||
template <typename Iter>
|
||||
[[nodiscard]] auto which_in(std::string_view exe, Iter search_path_first, Iter search_path_last)
|
||||
-> fs::u8path;
|
||||
|
||||
/**
|
||||
* Return the full path of a program from its name if found inside the given directories.
|
||||
*
|
||||
* The directies can be given as a range or as a @ref pathsep separated list.
|
||||
*/
|
||||
template <typename Range>
|
||||
[[nodiscard]] auto which_in(std::string_view exe, const Range& search_paths) -> fs::u8path;
|
||||
|
||||
/********************
|
||||
* Implementation *
|
||||
********************/
|
||||
|
@ -106,5 +128,43 @@ namespace mamba::util
|
|||
return ':';
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
[[nodiscard]] auto which_in_one(const fs::u8path& exe, const fs::u8path& dir) -> fs::u8path;
|
||||
|
||||
[[nodiscard]] auto which_in_split(const fs::u8path& exe, std::string_view paths)
|
||||
-> fs::u8path;
|
||||
}
|
||||
|
||||
template <typename Iter>
|
||||
auto which_in(std::string_view exe, Iter first, Iter last) -> fs::u8path
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
{
|
||||
if (auto p = detail::which_in_one(exe, *first); !p.empty())
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
auto which_in(std::string_view exe, const Range& search_paths) -> fs::u8path
|
||||
{
|
||||
if constexpr (std::is_same_v<Range, fs::u8path>)
|
||||
{
|
||||
return detail::which_in_one(exe, search_paths);
|
||||
}
|
||||
else if constexpr (std::is_convertible_v<Range, std::string_view>)
|
||||
{
|
||||
return detail::which_in_split(exe, search_paths);
|
||||
}
|
||||
else
|
||||
{
|
||||
return which_in(exe, search_paths.cbegin(), search_paths.cend());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "mamba/core/channel.hpp"
|
||||
#include "mamba/core/download.hpp"
|
||||
#include "mamba/core/env_lockfile.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/environments_manager.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/package_cache.hpp"
|
||||
|
@ -43,7 +42,7 @@ namespace mamba
|
|||
)
|
||||
{
|
||||
const auto get_python_path = [&]
|
||||
{ return env::which("python", get_path_dirs(target_prefix)).string(); };
|
||||
{ return util::which_in("python", get_path_dirs(target_prefix)).string(); };
|
||||
|
||||
const std::unordered_map<std::string, command_args> other_pkg_mgr_install_instructions{
|
||||
{ "pip",
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "mamba/core/activation.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/shell_init.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) 2019, QuantStack and Mamba Contributors
|
||||
//
|
||||
// Distributed under the terms of the BSD 3-Clause License.
|
||||
//
|
||||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <mutex>
|
||||
|
||||
#include <Shlobj.h>
|
||||
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/util/os_win.hpp"
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#include <wordexp.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern char** environ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/util/environment.hpp"
|
||||
#include "mamba/util/string.hpp"
|
||||
|
||||
namespace mamba::env
|
||||
{
|
||||
fs::u8path which(const std::string& exe, const std::string& override_path)
|
||||
{
|
||||
// TODO maybe add a cache?
|
||||
auto env_path = override_path == "" ? util::get_env("PATH") : override_path;
|
||||
if (env_path)
|
||||
{
|
||||
std::string path = env_path.value();
|
||||
const auto parts = util::split(path, util::pathsep());
|
||||
const std::vector<fs::u8path> search_paths(parts.begin(), parts.end());
|
||||
return which(exe, search_paths);
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
if (override_path == "")
|
||||
{
|
||||
char* pathbuf;
|
||||
size_t n = confstr(_CS_PATH, NULL, static_cast<size_t>(0));
|
||||
pathbuf = static_cast<char*>(malloc(n));
|
||||
if (pathbuf != NULL)
|
||||
{
|
||||
confstr(_CS_PATH, pathbuf, n);
|
||||
return which(exe, pathbuf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ""; // empty path
|
||||
}
|
||||
|
||||
fs::u8path which(const std::string& exe, const std::vector<fs::u8path>& search_paths)
|
||||
{
|
||||
for (auto& p : search_paths)
|
||||
{
|
||||
std::error_code _ec; // ignore
|
||||
if (!fs::exists(p, _ec) || !fs::is_directory(p, _ec))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
const auto exe_with_extension = exe + ".exe";
|
||||
#endif
|
||||
for (const auto& entry : fs::directory_iterator(p, _ec))
|
||||
{
|
||||
const auto filename = entry.path().filename();
|
||||
if (filename == exe
|
||||
|
||||
#ifdef _WIN32
|
||||
|| filename == exe_with_extension
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return entry.path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""; // empty path
|
||||
}
|
||||
}
|
|
@ -13,18 +13,20 @@
|
|||
#include <reproc++/reproc.hpp>
|
||||
#include <reproc++/run.hpp>
|
||||
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/link.hpp"
|
||||
#include "mamba/core/match_spec.hpp"
|
||||
#include "mamba/core/menuinst.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/transaction_context.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/core/validate.hpp"
|
||||
#include "mamba/util/build.hpp"
|
||||
#include "mamba/util/environment.hpp"
|
||||
#include "mamba/util/string.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#include "../data/conda_exe.hpp"
|
||||
#endif
|
||||
|
@ -384,10 +386,10 @@ namespace mamba
|
|||
else
|
||||
{
|
||||
// shell_path = 'sh' if 'bsd' in sys.platform else 'bash'
|
||||
fs::u8path shell_path = env::which("bash");
|
||||
fs::u8path shell_path = util::which("bash");
|
||||
if (shell_path.empty())
|
||||
{
|
||||
shell_path = env::which("sh");
|
||||
shell_path = util::which("sh");
|
||||
}
|
||||
|
||||
if (activate)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "mamba/core/channel.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/match_spec.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "mamba/core/activation.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/shell_init.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
|
@ -251,11 +250,9 @@ namespace mamba
|
|||
bash = parent_process_name;
|
||||
}
|
||||
else
|
||||
#ifdef _WIN32
|
||||
bash = env::which("bash.exe");
|
||||
#else
|
||||
bash = env::which("bash");
|
||||
#endif
|
||||
{
|
||||
bash = util::which("bash");
|
||||
}
|
||||
const std::string command = bash.empty() ? "cygpath"
|
||||
: (bash.parent_path() / "cygpath").string();
|
||||
std::string out, err;
|
||||
|
|
|
@ -53,7 +53,6 @@ extern "C"
|
|||
#include <tl/expected.hpp>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/error_handling.hpp"
|
||||
#include "mamba/core/execution.hpp"
|
||||
#include "mamba/core/invoke.hpp"
|
||||
|
@ -1541,10 +1540,10 @@ namespace mamba
|
|||
else
|
||||
{
|
||||
// shell_path = 'sh' if 'bsd' in sys.platform else 'bash'
|
||||
fs::u8path shell_path = env::which("bash");
|
||||
fs::u8path shell_path = util::which("bash");
|
||||
if (shell_path.empty())
|
||||
{
|
||||
shell_path = env::which("sh");
|
||||
shell_path = util::which("sh");
|
||||
}
|
||||
if (shell_path.empty())
|
||||
{
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <fmt/ostream.h>
|
||||
#include <reproc++/run.hpp>
|
||||
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/util/build.hpp"
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <reproc++/run.hpp>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environment.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/core/virtual_packages.hpp"
|
||||
|
|
|
@ -194,12 +194,23 @@ namespace mamba::util
|
|||
}
|
||||
return util::get_windows_known_user_folder(WindowsKnowUserFolder::LocalAppData);
|
||||
}
|
||||
|
||||
auto which_system(std::string_view exe) -> fs::u8path
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
constexpr auto exec_extension() -> std::string_view
|
||||
{
|
||||
return ".exe";
|
||||
};
|
||||
}
|
||||
|
||||
#else // #ifdef _WIN32
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <pwd.h>
|
||||
|
@ -305,11 +316,25 @@ namespace mamba::util
|
|||
}
|
||||
return path_concat(user_home_dir(), ".cache");
|
||||
}
|
||||
|
||||
auto which_system(std::string_view exe) -> fs::u8path
|
||||
{
|
||||
const auto n = ::confstr(_CS_PATH, nullptr, static_cast<std::size_t>(0));
|
||||
auto pathbuf = std::vector<char>(n, '\0');
|
||||
::confstr(_CS_PATH, pathbuf.data(), n);
|
||||
return which_in(exe, std::string_view(pathbuf.data(), n));
|
||||
}
|
||||
|
||||
constexpr auto exec_extension() -> std::string_view
|
||||
{
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#include "mamba/util/environment.hpp"
|
||||
#include "mamba/util/string.hpp"
|
||||
|
||||
namespace mamba::util
|
||||
{
|
||||
|
@ -329,4 +354,82 @@ namespace mamba::util
|
|||
}
|
||||
update_env_map(env);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
auto
|
||||
which_in_one_impl(const fs::u8path& exe, const fs::u8path& dir, const fs::u8path& extension)
|
||||
-> fs::u8path
|
||||
{
|
||||
std::error_code _ec; // ignore
|
||||
if (!fs::exists(dir, _ec) || !fs::is_directory(dir, _ec))
|
||||
{
|
||||
return ""; // Not found
|
||||
}
|
||||
|
||||
const auto strip_ext = [&extension](const fs::u8path& p)
|
||||
{
|
||||
if (p.extension() == extension)
|
||||
{
|
||||
return p.stem();
|
||||
}
|
||||
return p.filename();
|
||||
};
|
||||
|
||||
const auto exe_striped = strip_ext(exe);
|
||||
for (const auto& entry : fs::directory_iterator(dir, _ec))
|
||||
{
|
||||
if (auto p = entry.path(); strip_ext(p) == exe_striped)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return ""; // Not found
|
||||
}
|
||||
|
||||
auto which_in_split_impl(
|
||||
const fs::u8path& exe,
|
||||
std::string_view paths,
|
||||
const fs::u8path& extension,
|
||||
char pathsep
|
||||
) -> fs::u8path
|
||||
{
|
||||
auto elem = std::string_view();
|
||||
auto rest = std::optional<std::string_view>(paths);
|
||||
while (rest.has_value())
|
||||
{
|
||||
std::tie(elem, rest) = util::split_once(rest.value(), pathsep);
|
||||
if (auto p = which_in_one_impl(exe, elem, extension); !p.empty())
|
||||
{
|
||||
return p;
|
||||
};
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
auto which(std::string_view exe) -> fs::u8path
|
||||
{
|
||||
if (auto paths = get_env("PATH"))
|
||||
{
|
||||
if (auto p = which_in(exe, paths.value()); !p.empty())
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return which_system(exe);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
auto which_in_one(const fs::u8path& exe, const fs::u8path& dir) -> fs::u8path
|
||||
{
|
||||
return which_in_one_impl(exe, dir, exec_extension());
|
||||
}
|
||||
|
||||
auto which_in_split(const fs::u8path& exe, std::string_view paths) -> fs::u8path
|
||||
{
|
||||
return which_in_split_impl(exe, paths, exec_extension(), util::pathsep());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,11 @@ namespace mambatests
|
|||
#endif
|
||||
inline static const mamba::fs::u8path test_data_dir = MAMBA_TEST_DATA_DIR;
|
||||
|
||||
#ifndef MAMBA_TEST_LOCK_EXE
|
||||
#error "MAMBA_TEST_LOCK_EXE must be defined pointing to testing_libmamba_lock"
|
||||
#endif
|
||||
inline static const mamba::fs::u8path testing_libmamba_lock_exe = MAMBA_TEST_LOCK_EXE;
|
||||
|
||||
struct Singletons
|
||||
{
|
||||
// mamba::MainExecutor main_executor; // FIXME: reactivate once the tests are not indirectly
|
||||
|
|
|
@ -27,15 +27,10 @@ extern "C"
|
|||
}
|
||||
#endif
|
||||
|
||||
#include "mambatests.hpp"
|
||||
|
||||
namespace mamba
|
||||
{
|
||||
|
||||
#ifndef MAMBA_TEST_LOCK_EXE
|
||||
#error "MAMBA_TEST_LOCK_EXE must be defined pointing to testing_libmamba_lock"
|
||||
#endif
|
||||
inline static const fs::u8path testing_libmamba_lock_exe = MAMBA_TEST_LOCK_EXE;
|
||||
|
||||
namespace testing
|
||||
{
|
||||
|
||||
|
@ -123,7 +118,7 @@ namespace mamba
|
|||
|
||||
TEST_CASE_FIXTURE(LockDirTest, "different_pid")
|
||||
{
|
||||
std::string const lock_exe = testing_libmamba_lock_exe.string();
|
||||
std::string const lock_exe = mambatests::testing_libmamba_lock_exe.string();
|
||||
std::string out, err;
|
||||
std::vector<std::string> args;
|
||||
|
||||
|
@ -247,7 +242,7 @@ namespace mamba
|
|||
|
||||
TEST_CASE_FIXTURE(LockFileTest, "different_pid")
|
||||
{
|
||||
std::string const lock_exe = testing_libmamba_lock_exe.string();
|
||||
std::string const lock_exe = mambatests::testing_libmamba_lock_exe.string();
|
||||
std::string out, err;
|
||||
std::vector<std::string> args;
|
||||
{
|
||||
|
|
|
@ -192,4 +192,72 @@ TEST_SUITE("util::environment")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("which_in")
|
||||
{
|
||||
SUBCASE("Inexistant search dirs")
|
||||
{
|
||||
CHECK_EQ(which_in("echo", "/obviously/does/not/exist"), "");
|
||||
}
|
||||
|
||||
SUBCASE("testing_libmamba_lock")
|
||||
{
|
||||
const auto test_exe = which_in(
|
||||
"testing_libmamba_lock",
|
||||
mambatests::testing_libmamba_lock_exe.parent_path()
|
||||
);
|
||||
CHECK_EQ(test_exe.stem(), "testing_libmamba_lock");
|
||||
CHECK(mamba::fs::exists(test_exe));
|
||||
}
|
||||
|
||||
SUBCASE("testing_libmamba_lock.exe")
|
||||
{
|
||||
if (on_win)
|
||||
{
|
||||
const auto test_exe = which_in(
|
||||
"testing_libmamba_lock.exe",
|
||||
mambatests::testing_libmamba_lock_exe.parent_path()
|
||||
);
|
||||
CHECK_EQ(test_exe.stem(), "testing_libmamba_lock");
|
||||
CHECK(mamba::fs::exists(test_exe));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("which")
|
||||
{
|
||||
SUBCASE("echo")
|
||||
{
|
||||
const auto echo = which("echo");
|
||||
CHECK_EQ(echo.stem(), "echo");
|
||||
CHECK(mamba::fs::exists(echo));
|
||||
|
||||
if (!on_win)
|
||||
{
|
||||
const auto dir = echo.parent_path();
|
||||
constexpr auto reasonable_locations = std::array{
|
||||
"/bin",
|
||||
"/sbin",
|
||||
"/usr/bin",
|
||||
"/usr/sbin",
|
||||
};
|
||||
CHECK(starts_with_any(echo.string(), reasonable_locations));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("echo.exe")
|
||||
{
|
||||
if (on_win)
|
||||
{
|
||||
const auto echo = which("echo.exe");
|
||||
CHECK_EQ(echo.stem(), "echo");
|
||||
CHECK(mamba::fs::exists(echo));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Inexistant path")
|
||||
{
|
||||
CHECK_EQ(which("obvisously-does-not-exist"), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/util/build.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#endif
|
||||
|
||||
#include "common_options.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
|
|
Loading…
Reference in New Issue