From 7c62440d66c5a6ca97ba054682bd3fe4e03196e5 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Wed, 13 Mar 2019 14:46:00 +0900 Subject: [PATCH] Refactoring ni_common.cc 1. add /out option to crossgen to handle extension change case 2. move duplicated code --- NativeLauncher/installer-plugin/ni_common.cc | 184 +++++++++++++-------------- NativeLauncher/installer-plugin/ni_common.h | 23 +--- NativeLauncher/installer-plugin/nitool.cc | 7 +- 3 files changed, 93 insertions(+), 121 deletions(-) diff --git a/NativeLauncher/installer-plugin/ni_common.cc b/NativeLauncher/installer-plugin/ni_common.cc index 8384fea..4b5fe3d 100644 --- a/NativeLauncher/installer-plugin/ni_common.cc +++ b/NativeLauncher/installer-plugin/ni_common.cc @@ -69,20 +69,31 @@ static void waitInterval() } } -static bool niExist(const std::string& path, std::string& ni) +static std::string getNiFileName(const std::string& dllPath) { - size_t index = path.find_last_of("."); + size_t index = dllPath.find_last_of("."); if (index == std::string::npos) { - return false; + fprintf(stderr, "File doesnot contain extension. fail to get NI file name\n"); + return ""; } - std::string fName = path.substr(0, index); - std::string fExt = path.substr(index, path.length()); + std::string fName = dllPath.substr(0, index); + std::string fExt = dllPath.substr(index, dllPath.length()); // crossgen generate file with lower case extension only std::transform(fExt.begin(), fExt.end(), fExt.begin(), ::tolower); - std::string f = fName + ".ni" + fExt; + std::string niPath = fName + ".ni" + fExt; + + return niPath; +} + +static bool niExist(const std::string& path) +{ + std::string f = getNiFileName(path); + if (f.empty()) { + return false; + } + if (isFileExist(f)) { - ni = f; return true; } @@ -91,7 +102,6 @@ static bool niExist(const std::string& path, std::string& ni) if (path.find("System.Private.CoreLib.dll") != std::string::npos) { std::string coreLibBackup = path + ".Backup"; if (isFileExist(coreLibBackup)) { - ni = path; return true; } } @@ -99,43 +109,67 @@ static bool niExist(const std::string& path, std::string& ni) return false; } -static void updateNiFileInfo(const std::string& path) +static void updateNiFileInfo(const std::string& dllPath, const std::string& niPath) { char* label = NULL; - std::string niPath; - if (niExist(path, niPath)) { - // change smack label - if (smack_getlabel(path.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { - if (smack_setlabel(niPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { - fprintf(stderr, "Fail to set smack label\n"); - } - free(label); + // change smack label + if (smack_getlabel(dllPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { + if (smack_setlabel(niPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { + fprintf(stderr, "Fail to set smack label\n"); } + free(label); + } - // change owner and groups for generated ni file. - struct stat info; - if (!stat(path.c_str(), &info)) { - if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1) - fprintf(stderr, "Failed to change owner and group name\n"); - } + // change owner and groups for generated ni file. + struct stat info; + if (!stat(dllPath.c_str(), &info)) { + if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1) + fprintf(stderr, "Failed to change owner and group name\n"); } } -static void crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R) +static int crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R) { + if (!isFileExist(dllPath)) { + fprintf(stderr, "dll file is not exist : %s\n", dllPath.c_str()); + return -1; + } + + if (!isManagedAssembly(dllPath)) { + fprintf(stderr, "Input file is not a dll file : %s\n", dllPath.c_str()); + return-1; + } + + if (niExist(dllPath)) { + fprintf(stderr, "Already ni file is exist for %s\n", dllPath.c_str()); + return-1; + } + std::string absDllPath = absolutePath(dllPath); + std::string absNiPath = getNiFileName(dllPath); + if (absNiPath.empty()) { + fprintf(stderr, "Fail to get ni file name\n"); + return-1; + } pid_t pid = fork(); if (pid == -1) - return; + return-1; if (pid > 0) { int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { - updateNiFileInfo(absDllPath); - return; + // Do not use niExist() function to check whether ni file created or not. + // niEixst() return false for System.Private.Corelib.dll + if (isFileExist(absNiPath)) { + updateNiFileInfo(absDllPath, absNiPath); + return 0; + } else { + fprintf(stderr, "Fail to create native image for %s\n", dllPath.c_str()); + return -1; + } } } else { std::string jitPath = getRuntimeDir() + "/libclrjit.so"; @@ -159,6 +193,9 @@ static void crossgen(const std::string& dllPath, const std::string& appPath, boo } argv.push_back(absAppPath.c_str()); + argv.push_back("/out"); + argv.push_back(absNiPath.c_str()); + argv.push_back(absDllPath.c_str()); argv.push_back(nullptr); @@ -167,6 +204,8 @@ static void crossgen(const std::string& dllPath, const std::string& appPath, boo execv(__CROSSGEN_PATH, const_cast(argv.data())); exit(0); } + + return 0; } static int getRootPath(std::string pkgId, std::string& rootPath) @@ -238,9 +277,8 @@ static void createCoreLibNI(bool enableR2R) std::string niCoreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.ni.dll"); std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup"); - if (!niExist(coreLib, niCoreLib)) { - crossgen(coreLib, std::string(), enableR2R); - if (isFileExist(niCoreLib)) { + if (!isFileExist(coreLibBackup)) { + if (!crossgen(coreLib, std::string(), enableR2R)) { if (rename(coreLib.c_str(), coreLibBackup.c_str())) { fprintf(stderr, "Failed to rename System.Private.CoreLib.dll\n"); } @@ -296,32 +334,16 @@ void finalizeNICommon() void createNiPlatform(bool enableR2R) { const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()}; - createNiUnderDirs(platformDirs, 2, enableR2R); } -void createNiDll(const std::string& dllPath, bool enableR2R) +int createNiDll(const std::string& dllPath, bool enableR2R) { createCoreLibNI(enableR2R); - - if (!isFileExist(dllPath)) { - fprintf(stderr, "Failed to find dll : %s\n", dllPath.c_str()); - return; - } - - std::string niPath; - if (niExist(dllPath, niPath)) { - fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str()); - return; - } - - crossgen(dllPath, std::string(), enableR2R); - if (!niExist(dllPath, niPath)) { - fprintf(stderr, "Failed to create native image for %s\n", dllPath.c_str()); - } + return crossgen(dllPath, std::string(), enableR2R); } -void createNiUnderDirs(const std::string rootPaths[], int count, const std::string ignores[], int igcount, afterCreate cb, bool enableR2R) +void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R) { createCoreLibNI(enableR2R); @@ -334,45 +356,24 @@ void createNiUnderDirs(const std::string rootPaths[], int count, const std::stri if (appPaths.back() == ':') appPaths.pop_back(); - auto convert = [&appPaths, ignores, igcount, &cb, enableR2R](const std::string& path, const char* name) { - for (int i = 0; i < igcount; i++) { - if (path == ignores[i]) - return; - } - std::string niPath; - if (isManagedAssembly(path)) { - if (niExist(path, niPath)) { - fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str()); - return; - } - crossgen(path, appPaths.c_str(), enableR2R); - if (niExist(path, niPath)) { - if (cb != nullptr) - cb(niPath.c_str()); - } else { - fprintf(stderr, "Failed to create native image for %s\n", path.c_str()); - } + auto convert = [&appPaths, enableR2R](const std::string& path, const char* name) { + if (!crossgen(path, appPaths.c_str(), enableR2R)) { waitInterval(); } }; - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { scanFilesInDir(rootPaths[i], convert, 1); -} -void createNiUnderDirs(const std::string rootPaths[], int count, afterCreate cb, bool enableR2R) -{ - createNiUnderDirs(rootPaths, count, nullptr, 0, cb, enableR2R); -} -void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R) -{ - createNiUnderDirs(rootPaths, count, nullptr, enableR2R); + } } int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R) { std::string pkgRoot; - if (getRootPath(pkgName, pkgRoot) < 0) + if (getRootPath(pkgName, pkgRoot) < 0) { + fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str()); return -1; + } std::string binDir = concatPath(pkgRoot, "bin"); std::string libDir = concatPath(pkgRoot, "lib"); @@ -386,31 +387,16 @@ int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R) int createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R) { std::string pkgRoot; - if (getRootPath(pkgName, pkgRoot) < 0) + if (getRootPath(pkgName, pkgRoot) < 0) { + fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str()); return -1; + } std::string binDir = concatPath(pkgRoot, "bin"); std::string libDir = concatPath(pkgRoot, "lib"); - std::string appPaths = binDir + ":" + libDir; - - if (!isFileExist(dllPath)) { - fprintf(stderr, "Failed to find dll : %s\n", dllPath.c_str()); - return -1; - } + std::string paths = binDir + ":" + libDir; - std::string niPath; - if (niExist(dllPath, niPath)) { - fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str()); - return -1; - } - - crossgen(dllPath, appPaths, enableR2R); - if (!niExist(dllPath, niPath)) { - fprintf(stderr, "Failed to create native image for %s\n", dllPath.c_str()); - return -1; - } - - return 0; + return crossgen(dllPath, paths, enableR2R); } void removeNiPlatform() @@ -453,8 +439,10 @@ void removeNiUnderDirs(const std::string rootPaths[], int count) int removeNiUnderPkgRoot(const std::string& pkgName) { std::string pkgRoot; - if (getRootPath(pkgName, pkgRoot) < 0) + if (getRootPath(pkgName, pkgRoot) < 0) { + fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str()); return -1; + } std::string binDir = concatPath(pkgRoot, "bin"); std::string libDir = concatPath(pkgRoot, "lib"); diff --git a/NativeLauncher/installer-plugin/ni_common.h b/NativeLauncher/installer-plugin/ni_common.h index 4b17905..91c8def 100644 --- a/NativeLauncher/installer-plugin/ni_common.h +++ b/NativeLauncher/installer-plugin/ni_common.h @@ -52,28 +52,9 @@ void createNiPlatform(bool enableR2R); * @brief create native image for specific dll with file path. * @param[i] dllPath file path to generate native image * @param[i] enableR2R enable ready-to-run mode + * @return 0 on success, otherwise a negative error value */ -void createNiDll(const std::string& dllPath, bool enableR2R); - -/** - * @brief create native images with files under specific directory. - * @param[i] rootPaths directories whicn contains DLLs - * @param[i] count number of rootPath - * @param[i] ignores DLL list which should be ignored - * @param[i] igcount number of ignores - * @param[i] cb callback function whicn will be called after generating native image - * @param[i] enableR2R enable ready-to-run mode - */ -void createNiUnderDirs(const std::string rootPaths[], int count, const std::string ignores[], int igcount, afterCreate cb, bool enableR2R); - -/** - * @brief create native images with files under specific directory. - * @param[i] rootPaths directories whicn contains DLLs - * @param[i] count number of rootPath - * @param[i] cb callback function whicn will be called after generating native image - * @param[i] enableR2R enable ready-to-run mode - */ -void createNiUnderDirs(const std::string rootPaths[], int count, afterCreate cb, bool enableR2R); +int createNiDll(const std::string& dllPath, bool enableR2R); /** * @brief create native images with files under specific directory. diff --git a/NativeLauncher/installer-plugin/nitool.cc b/NativeLauncher/installer-plugin/nitool.cc index afae251..aac3d0e 100644 --- a/NativeLauncher/installer-plugin/nitool.cc +++ b/NativeLauncher/installer-plugin/nitool.cc @@ -141,8 +141,11 @@ int main(int argc, char* argv[]) } } } else if (dllMode) { - for (const std::string dll : args) - createNiDll(dll, enableR2R); + for (const std::string dll : args) { + if (createNiDll(dll, enableR2R) != 0) { + fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str()); + } + } } else if (dirMode) { createNiUnderDirs(args.data(), args.size(), enableR2R); } -- 2.7.4