Refactoring ni_common.cc
authorWoongsuk Cho <ws77.cho@samsung.com>
Wed, 13 Mar 2019 05:46:00 +0000 (14:46 +0900)
committerWoongsuk Cho <ws77.cho@samsung.com>
Wed, 13 Mar 2019 05:46:00 +0000 (14:46 +0900)
1. add /out option to crossgen to handle extension change case
2. move duplicated code

NativeLauncher/installer-plugin/ni_common.cc
NativeLauncher/installer-plugin/ni_common.h
NativeLauncher/installer-plugin/nitool.cc

index 8384fea..4b5fe3d 100644 (file)
@@ -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<char* const*>(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");
index 4b17905..91c8def 100644 (file)
@@ -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.
index afae251..aac3d0e 100644 (file)
@@ -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);
        }