+ return false;
+ }
+
+ if (isFile(absNIPath)) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool checkDllExistInDir(const std::string& path)
+{
+ bool ret = false;
+ auto func = [&ret](const std::string& f_path, const std::string& f_name) {
+ if (isManagedAssembly(f_name) || isNativeImage(f_name)) {
+ ret = true;
+ }
+ };
+
+ scanFilesInDirectory(path, func, 0);
+
+ return ret;
+}
+
+/*
+ * Get the list of managed files in the specific directory
+ * Absolute paths of managed files are stored at the result list.
+ * If native image already exist in the same directory, managed file is ignored.
+ */
+static ni_error_e getTargetDllList(const std::string& path, std::vector<std::string>& fileList)
+{
+ if (!isDirectory(path)) {
+ return NI_ERROR_INVALID_PARAMETER;
+ }
+
+ auto func = [&fileList](const std::string& f_path, const std::string& f_name) {
+ if (isManagedAssembly(f_path) && !checkNIExistence(f_path)) {
+ fileList.push_back(getAbsolutePath(f_path));
+ }
+ };
+
+ scanFilesInDirectory(path, func, 0);
+
+ return NI_ERROR_NONE;
+}
+
+/*
+ * Get the list of managed files in the specific directory of Application
+ * Absolute paths of managed files are stored at the result list.
+ * If native image already exist in the .native_image directory, managed file is ignored.
+ *
+ */
+static ni_error_e getAppTargetDllList(const std::string& path, std::vector<std::string>& fileList, NIOption *opt)
+{
+ if (!isDirectory(path)) {
+ return NI_ERROR_INVALID_PARAMETER;
+ }
+
+ auto func = [&fileList, opt](const std::string& f_path, const std::string& f_name) {
+ if (isManagedAssembly(f_path) && !checkAppNIExistence(f_path, opt)) {
+ fileList.push_back(getAbsolutePath(f_path));
+ }
+ };
+
+ scanFilesInDirectory(path, func, 0);
+
+ return NI_ERROR_NONE;
+}
+
+static void makeArgs(std::vector<const char*>& args, const std::vector<std::string>& refPaths, NIOption* opt)
+{
+ args.push_back(CORERUN_CMD.c_str());
+ if (CROSSGEN2_PATH != "") {
+ args.push_back(CROSSGEN2_PATH.c_str());
+ }
+ args.push_back(CROSSGEN_OPT_JITPATH);
+ args.push_back(CLRJIT_PATH.c_str());
+ args.push_back(CROSSGEN_OPT_TARGET_ARCH);
+ args.push_back(ARCHITECTURE_IDENTIFIER);
+
+ //args.push_back(OPT_PARALLELISM);
+ //args.push_back(OPT_PARALLELISM_COUNT);
+ args.push_back(CROSSGEN_OPT_RESILIENT);
+
+ args.push_back(CROSSGEN_OPT_OPTIMIZE_TIME);
+
+ if (opt->flags & NI_FLAGS_INPUT_BUBBLE) {
+ args.push_back(CROSSGEN_OPT_INPUTBUBBLE);
+ args.push_back(CROSSGEN_OPT_COMPILE_BUBBLE_GENERICS);
+
+ INPUTBUBBLE_REF_VECTOR.clear();
+ for (const auto &path : opt->inputBubbleRefFiles) {
+ INPUTBUBBLE_REF_VECTOR.push_back("--inputbubbleref:" + path);
+ }
+ for (const auto &path : INPUTBUBBLE_REF_VECTOR) {
+ if (find(args.begin(), args.end(), path) == args.end()) {
+ args.push_back(path.c_str());
+ }
+ }
+ }
+
+ if (opt->flags & NI_FLAGS_MIBC) {
+ MIBC_VECTOR.clear();
+ for (const auto &path : opt->mibcPath) {
+ MIBC_VECTOR.push_back("--mibc:" + path);
+ }
+ for (const auto &path : MIBC_VECTOR) {
+ if (find(args.begin(), args.end(), path) == args.end()) {
+ args.push_back(path.c_str());
+ }
+ }
+ }
+
+ if (opt->flags & NI_FLAGS_VERBOSE) {
+ args.push_back(CROSSGEN_OPT_VERBOSE);
+ }
+
+ REF_VECTOR.clear();
+
+ // set reference path
+ for (const auto &path : opt->refFiles) {
+ REF_VECTOR.push_back("-r:" + path);
+ }
+
+ std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
+ for (const auto &path : paths) {
+ if (checkDllExistInDir(path)) {
+ REF_VECTOR.push_back("-r:" + path + "/*.dll");
+ }
+ }
+
+ if (opt->flags & NI_FLAGS_EXTRA_REF) {
+ for (const auto &erPath : opt->extraRefPath) {
+ std::string path = getAbsolutePath(erPath);
+ if (checkDllExistInDir(path)) {
+ REF_VECTOR.push_back("-r:" + path + "/*.dll");
+ }
+ }
+ }
+
+ for (const auto &path : refPaths) {
+ if (checkDllExistInDir(path)) {
+ REF_VECTOR.push_back("-r:" + path + "/*.dll");
+ }
+ }
+
+ for (const auto &path : REF_VECTOR) {
+ if (find(args.begin(), args.end(), path) == args.end()) {
+ args.push_back(path.c_str());
+ }
+ }
+}
+
+static void clearArgs(std::vector<const char*>& args)
+{
+ REF_VECTOR.clear();
+ args.clear();
+}
+
+static ni_error_e makePdbSymlinkForNI(std::string dllPath, std::string niPath)
+{
+ std::string pdbPath = changeExtension(dllPath, ".dll", ".pdb");
+ try {
+ if (exist(pdbPath)) {
+ std::string targetPDBPath = changeExtension(niPath, ".ni.dll", ".pdb");
+ if (!exist(targetPDBPath)) {
+ bf::create_symlink(pdbPath, targetPDBPath);
+ copySmackAndOwnership(pdbPath, targetPDBPath, true);
+ }
+ }
+ } catch (const bf::filesystem_error& error) {
+ _SERR("Fail to create symlink for %s", pdbPath.c_str());