X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=NativeLauncher%2Ftool%2Fni_common.cc;h=f7b69ad7679a4e46881303c9910dadc1e0685b43;hb=4815801fb95b1cc086d4f1dc6e6b671f80767451;hp=7cc1d639ff1867f87ae6e118351e89542eb816e8;hpb=7a91946e9f06c8779cff7ee84177eea05a5fe111;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index 7cc1d63..f7b69ad 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -230,8 +230,39 @@ static bool createDirsAndCopyOwnerShip(std::string& target_path, const std::stri return true; } -static std::string getNIFilePath(const std::string& dllPath) +static std::string getNIFilePath(const std::string& absDllPath, NIOption* opt) { + std::string dllPath = absDllPath; + std::string fileName = getFileName(absDllPath); + if (opt->flags & NI_FLAGS_APPNI) { + std::string niDirPath; + std::string niTmpDirPath; + std::string prevPath; + + prevPath = getBaseName(absDllPath); + niDirPath = concatPath(prevPath, APP_NI_SUB_DIR); + niTmpDirPath = concatPath(prevPath, APP_NI_SUB_TMP_DIR); + + if (opt->flags & NI_FLAGS_APP_UNDER_RO_AREA) { + niTmpDirPath = replaceAll(niTmpDirPath, getBaseName(__pm->getAppRootPath()), __READ_ONLY_APP_UPDATE_DIR); + niDirPath = replaceAll(niDirPath, getBaseName(__pm->getAppRootPath()), __READ_ONLY_APP_UPDATE_DIR); + _INFO("App is installed in RO area. Change NI path to RW area(%s).", niTmpDirPath.c_str()); + } + + if (!isDirectory(niDirPath)) { + if (!createDirsAndCopyOwnerShip(niTmpDirPath, prevPath)) { + niTmpDirPath = prevPath; + _SERR("fail to create dir (%s)", niTmpDirPath.c_str()); + } + dllPath = concatPath(niTmpDirPath, fileName); + } else { + dllPath = concatPath(niDirPath, fileName); + } + } else if (opt->flags & NI_FLAGS_RESOURCE_NI) { + std::string rpkDir = concatPath(__pm->getAppRootPath(), APP_NI_SUB_DIR); + dllPath = createDir(rpkDir) ? concatPath(rpkDir, fileName) : concatPath(__pm->getAppRootPath(), fileName); + } + size_t index = dllPath.find_last_of("."); if (index == std::string::npos) { _SERR("File doesnot contain extension. fail to get NI file name"); @@ -247,33 +278,9 @@ static std::string getNIFilePath(const std::string& dllPath) return niPath; } -static std::string getAppNIFilePath(const std::string& absDllPath, NIOption* opt) -{ - std::string niDirPath; - std::string prevPath; - - prevPath = getBaseName(absDllPath); - niDirPath = concatPath(prevPath, APP_NI_SUB_TMP_DIR); - - if (opt->flags & NI_FLAGS_APP_UNDER_RO_AREA) { - niDirPath = replaceAll(niDirPath, getBaseName(__pm->getAppRootPath()), __READ_ONLY_APP_UPDATE_DIR); - _SERR("App is installed in RO area. Change NI path to RW area(%s).", niDirPath.c_str()); - _ERR("App is installed in RO area. Change NI path to RW area(%s).", niDirPath.c_str()); - } - - if (!isDirectory(niDirPath)) { - if (!createDirsAndCopyOwnerShip(niDirPath, prevPath)) { - niDirPath = prevPath; - _SERR("fail to create dir (%s)", niDirPath.c_str()); - } - } - - return getNIFilePath(concatPath(niDirPath, getFileName(absDllPath))); -} - -static bool checkNIExistence(const std::string& absDllPath) +static bool checkNIExistence(const std::string& absDllPath, NIOption* opt) { - std::string absNIPath = getNIFilePath(absDllPath); + std::string absNIPath = getNIFilePath(absDllPath, opt); if (absNIPath.empty()) { return false; } @@ -291,25 +298,11 @@ static bool checkNIExistence(const std::string& absDllPath) return false; } -static bool checkAppNIExistence(const std::string& absDllPath, NIOption* opt) -{ - std::string absNIPath = getAppNIFilePath(absDllPath, opt); - if (absNIPath.empty()) { - 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)) { + if (isManagedAssembly(f_name) || isR2RImage(f_name)) { ret = true; } }; @@ -320,41 +313,18 @@ static bool checkDllExistInDir(const std::string& path) } /* - * 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& 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 + * 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. - * + * If native image already exist in the (same / .native_image) directory, managed file is ignored. */ -static ni_error_e getAppTargetDllList(const std::string& path, std::vector& fileList, NIOption *opt) +static ni_error_e getTargetDllList(const std::string& path, std::vector& 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)) { + if (isManagedAssembly(f_path) && !checkNIExistence(f_path, opt)) { fileList.push_back(getAbsolutePath(f_path)); } }; @@ -482,7 +452,7 @@ static ni_error_e crossgen2PostAction(const std::string& dllPath, const std::str // if AppNI then move ni.dll file to .native_image and copy pdb to .native_image if (opt->flags & NI_FLAGS_APPNI) { - outFile = getAppNIFilePath(dllPath, opt); + outFile = getNIFilePath(dllPath, opt); makePdbSymlinkForNI(dllPath, outFile); if (opt->flags & NI_FLAGS_INPUT_BUBBLE && opt->flags & NI_FLAGS_NO_PIPELINE) { @@ -500,6 +470,11 @@ static ni_error_e crossgen2PostAction(const std::string& dllPath, const std::str } } + if (opt->flags & NI_FLAGS_RESOURCE_NI) { + moveFile(niPath, changeExtension(dllPath, ".dll", ".ni.dll")); + removeAll(concatPath(__pm->getAppRootPath(), APP_NI_SUB_DIR)); + } + if (!(opt->flags & NI_FLAGS_INPUT_BUBBLE && opt->flags & NI_FLAGS_NO_PIPELINE)) { _SOUT("Native image %s generated successfully.", outFile.c_str()); } @@ -581,11 +556,8 @@ static ni_error_e crossgen2NoPipeLine(const std::vector& dllList, c { for (auto& dllPath : dllList) { std::string niPath; - if (opt->flags & NI_FLAGS_APPNI) { - niPath = getAppNIFilePath(dllPath, opt); - } else { - niPath = getNIFilePath(dllPath); - } + niPath = getNIFilePath(dllPath, opt); + #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT uintptr_t baseAddr = 0; if (isTPADll(dllPath)) { @@ -721,6 +693,8 @@ static void renameAppNITmpPath(NIOption* opt) if (isDirectory(niTmpPath)) { if (rename(niTmpPath.c_str(), niPath.c_str())) { _SERR("Fail to rename from .native_image_tmp to .native_image"); + } else { + _SOUT("Success to rename from %s to %s", niTmpPath.c_str(), niPath.c_str()); } } } @@ -756,6 +730,11 @@ static ni_error_e doAOTList(std::vector& dllList, const std::string } } + // Error : Multiple input files matching same simple name + // So, Remove dulicate files from dll list + std::sort(dllList.begin(), dllList.end()); + dllList.erase(unique(dllList.begin(), dllList.end()), dllList.end()); + // In the case of SPC, post-processing is required to change the name of the native image. // In order to avoid repeatedly checking whether the generated native image is an SPC, // the SPC native image generation is performed separately. @@ -803,12 +782,7 @@ static ni_error_e doAOTList(std::vector& dllList, const std::string if (opt->flags & NI_FLAGS_INPUT_BUBBLE) { for (auto &dll : dllList) { std::string tmpFile; - std::string niFile; - if (opt->flags & NI_FLAGS_APPNI) { - niFile = getAppNIFilePath(dll, opt); - } else { - niFile = getNIFilePath(dll); - } + std::string niFile = getNIFilePath(dll, opt); tmpFile = niFile + ".tmp"; if (exist(tmpFile)) { @@ -832,58 +806,89 @@ static ni_error_e doAOTFile(const std::string& dllFile, const std::string& refPa return NI_ERROR_NO_SUCH_FILE; } + if (checkNIExistence(dllFile, opt)) { + _SERR("Native image file is already exist : %s", dllFile.c_str()); + return NI_ERROR_ALREADY_EXIST; + } + if (!isManagedAssembly(dllFile)) { _SERR("Failed. Input parameter is not managed dll (%s)\n", dllFile.c_str()); return NI_ERROR_INVALID_PARAMETER; } - if (checkNIExistence(dllFile)) { - _SERR("Native image file is already exist : %s", dllFile.c_str()); - return NI_ERROR_ALREADY_EXIST; - } - std::vector dllList; dllList.push_back(getAbsolutePath(dllFile)); return doAOTList(dllList, refPaths, opt); } -// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" -static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData) +static ni_error_e removeAndCreateNI(const char* pkgId, NIOption* pOptions) +{ + if (removeNIUnderPkgRoot(pkgId) != NI_ERROR_NONE) { + _SERR("Failed to remove previous dlls from [%s]", pkgId); + return NI_ERROR_UNKNOWN; + } + + if (createNIUnderPkgRoot(pkgId, pOptions) != NI_ERROR_NONE) { + _SERR("Failed to generate NI file [%s]", pkgId); + return NI_ERROR_UNKNOWN; + } + + _SOUT("Complete make native image for pkg (%s)", pkgId); + return NI_ERROR_NONE; +} + +static bool isReadOnlyPkg(std::string pkgId) { - char *pkgId = NULL; int ret = 0; - NIOption **pOptions = (NIOption**)userData; - - if ((*pOptions)->flags & NI_FLAGS_SKIP_RO_APP) { - bool isSystem = false; - int ret = pkgmgrinfo_appinfo_is_system(handle, &isSystem); - if (ret != PMINFO_R_OK) { - _SERR("Failed to check that app is System or not\n"); - return -1; - } - if (isSystem) { - return 0; - } + bool readonly = false; + pkgmgrinfo_pkginfo_h handle; + + ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + if (ret != PMINFO_R_OK) { + _ERR("Fail to get pkginfo"); + return false; } - ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId); + ret = pkgmgrinfo_pkginfo_is_readonly(handle, &readonly); if (ret != PMINFO_R_OK) { - _SERR("Failed to get pkgid"); - return -1; + _ERR("Fail to get is_readonly"); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return false; } - if (removeNIUnderPkgRoot(pkgId) != NI_ERROR_NONE) { - _SERR("Failed to remove previous dlls from [%s]", pkgId); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return readonly; +} + +// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" +static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData) +{ + char *pkgId = NULL; + int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId); + if (ret != PMINFO_R_OK) { + _SERR("Failed to get pkgid"); return -1; } - if (createNIUnderPkgRoot(pkgId, *pOptions) != NI_ERROR_NONE) { - _SERR("Failed to generate NI file [%s]", pkgId); + std::vector *pkgList = (std::vector *)userData; + pkgList->push_back(pkgId); + + return 0; +} + +// callback function of "pkgmgrinfo_pkginfo_metadata_filter_foreach" +static int pkgAotCb(pkgmgrinfo_pkginfo_h handle, void *userData) +{ + char *pkgId = NULL; + int ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgId); + if (ret != PMINFO_R_OK) { + _SERR("Failed to get pkgid"); return -1; - } else { - _SOUT("Complete make application to native image"); } + std::vector *pkgList = (std::vector *)userData; + pkgList->push_back(pkgId); + return 0; } @@ -968,8 +973,11 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re { ni_error_e ret; + // NI fils of TAC-related dlls under /opt/usr/dotnet should not be created under .native_image directory. + // So, unset NI_FLAGS_APPNI temporally and restore it after running AOT. bool isAppNI = false; if (opt->flags & NI_FLAGS_APPNI) { + opt->flags &= ~NI_FLAGS_APPNI; isAppNI = true; } @@ -985,7 +993,7 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re // get managed file list from targetPath std::vector dllList; - ret = getTargetDllList(targetPath, dllList); + ret = getTargetDllList(targetPath, dllList, opt); if (ret != NI_ERROR_NONE) { return ret; } @@ -994,26 +1002,21 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re std::vector niList; for (auto &dll : dllList) { - if (!checkNIExistence(dll)) { + if (!checkNIExistence(dll, opt)) { needNIList.push_back(dll); } - niList.push_back(getNIFilePath(dll)); + niList.push_back(getNIFilePath(dll, opt)); } if (!needNIList.empty()) { - // NI fils of TAC-related dlls under /opt/usr/dotnet should not be created under .native_image directory. - // So, unset NI_FLAGS_APPNI temporally and restore it after running AOT. - opt->flags &= ~NI_FLAGS_APPNI; ret = doAOTList(needNIList, refPaths, opt); - if (isAppNI) { - opt->flags |= NI_FLAGS_APPNI; - } if (ret != NI_ERROR_NONE) { return ret; } } if (isAppNI) { + opt->flags |= NI_FLAGS_APPNI; for (auto &niPath : niList) { if (exist(niPath)) { std::string symNIPath = concatPath(targetPath, getFileName(niPath)); @@ -1030,7 +1033,6 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re return NI_ERROR_NONE; } - ni_error_e createNIUnderDirs(const std::string& rootPaths, NIOption* opt) { ni_error_e ret = NI_ERROR_NONE; @@ -1057,13 +1059,8 @@ ni_error_e createNIUnderDirs(const std::string& rootPaths, NIOption* opt) if (ret != NI_ERROR_NONE) { return ret; } - } else if (opt->flags & NI_FLAGS_APPNI) { - ret = getAppTargetDllList(path, fileList, opt); - if (ret != NI_ERROR_NONE) { - return ret; - } } else { - ret = getTargetDllList(path, fileList); + ret = getTargetDllList(path, fileList, opt); if (ret != NI_ERROR_NONE) { return ret; } @@ -1091,7 +1088,6 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, NIOption* opt) _SERR("Failed to get root path from [%s]", pkgId.c_str()); return NI_ERROR_INVALID_PACKAGE; } - __pm->setAppRootPath(rootPath); char* extraDllPaths = pluginGetExtraDllPath(); @@ -1100,19 +1096,34 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, NIOption* opt) splitPath(extraDllPaths, opt->extraRefPath); } - opt->flags |= NI_FLAGS_APPNI; + std::string targetDirs; + if (isRPK(pkgId)) { + opt->flags &= ~NI_FLAGS_APPNI; // added to exclude logic of APP_NI + opt->flags |= NI_FLAGS_RESOURCE_NI; // added flag for RPK type + opt->flags |= NI_FLAGS_NO_PIPELINE; // added the flag to set the output path - if (isReadOnlyArea(rootPath)) { - opt->flags |= NI_FLAGS_APP_UNDER_RO_AREA; - opt->flags |= NI_FLAGS_NO_PIPELINE; - _SERR("Only no-pipeline mode supported for RO app. Set no-pipeline option forcibly"); + std::string paths = getResourcePaths(rootPath); + if (paths.empty()) { + _SERR("Failed to get rpk paths from [%s]", pkgId.c_str()); + return NI_ERROR_UNKNOWN; + } + targetDirs = paths; } else { - opt->flags &= ~NI_FLAGS_APP_UNDER_RO_AREA; + opt->flags |= NI_FLAGS_APPNI; + opt->flags &= ~NI_FLAGS_RESOURCE_NI; // added to exclude logic of RESOURCE_NI + + if (isReadOnlyArea(rootPath)) { + opt->flags |= NI_FLAGS_APP_UNDER_RO_AREA; + opt->flags |= NI_FLAGS_NO_PIPELINE; + _SERR("Only no-pipeline mode supported for RO app. Set no-pipeline option forcibly"); + } else { + opt->flags &= ~NI_FLAGS_APP_UNDER_RO_AREA; + } + + targetDirs = __pm->getAppPaths(); } - // create native image under bin and lib directory - // tac directory is skipped in the createNIUnderDirs. - return createNIUnderDirs(__pm->getAppPaths(), opt); + return createNIUnderDirs(targetDirs, opt); } void removeNIPlatform() @@ -1147,7 +1158,7 @@ void removeNIPlatform() void removeNIUnderDirs(const std::string& rootPaths) { auto convert = [](const std::string& path, const std::string& filename) { - if (isNativeImage(path)) { + if (isR2RImage(path)) { std::string assemblyPath = changeExtension(path, ".ni.dll", ".dll"); if (exist(assemblyPath)) { if (remove(path.c_str())) { @@ -1168,69 +1179,121 @@ void removeNIUnderDirs(const std::string& rootPaths) ni_error_e removeNIUnderPkgRoot(const std::string& pkgId) { + std::vector paths; + std::string rootPath = getRootPath(pkgId); if (rootPath.empty()) { _SERR("Failed to get root path from [%s]", pkgId.c_str()); return NI_ERROR_INVALID_PACKAGE; } - __pm->setAppRootPath(rootPath); - - // getAppNIPaths returns bin/.native_image, lib/.native_image and .tac_symlink. - std::string appNIPaths = __pm->getAppNIPaths(); - std::vector paths; - splitPath(appNIPaths, paths); - for (const auto &path : paths) { - if (!isReadOnlyArea(path)) { - // Only the native image inside the TAC should be removed. - if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) { + if (isRPK(pkgId)) { + std::string rpkPaths = getResourcePaths(rootPath); + if (rpkPaths.empty()) { + _SERR("Failed to get rpk path from [%s]", pkgId.c_str()); + return NI_ERROR_UNKNOWN; + } + splitPath(rpkPaths, paths); + for (const auto &path : paths) { + if (isDirectory(path)) { removeNIUnderDirs(path); - } else { - if (isDirectory(path)) { - if (!removeAll(path.c_str())) { - _SERR("Failed to remove app ni dir [%s]", path.c_str()); + } + } + } else { + __pm->setAppRootPath(rootPath); + + // getAppNIPaths returns bin/.native_image, lib/.native_image and .tac_symlink. + std::string appNIPaths = __pm->getAppNIPaths(); + splitPath(appNIPaths, paths); + for (const auto &path : paths) { + if (!isReadOnlyArea(path)) { + // Only the native image inside the TAC should be removed. + if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) { + removeNIUnderDirs(path); + } else { + if (isDirectory(path)) { + if (!removeAll(path.c_str())) { + _SERR("Failed to remove app ni dir [%s]", path.c_str()); + } } } } } - } - // In special cases, the ni file may exist in the dll location. - // The code below is to avoid this exceptional case. - std::string appPaths = __pm->getAppPaths(); - splitPath(appPaths, paths); - for (const auto &path : paths) { - if (isDirectory(path)) { - removeNIUnderDirs(path); + // In special cases, the ni file may exist in the dll location. + // The code below is to avoid this exceptional case. + std::string appPaths = __pm->getAppPaths(); + splitPath(appPaths, paths); + for (const auto &path : paths) { + if (isDirectory(path)) { + removeNIUnderDirs(path); + } } } return NI_ERROR_NONE; } -ni_error_e regenerateAppNI(NIOption* opt) +ni_error_e regeneratePkgNI(NIOption* opt) { - int ret = 0; - pkgmgrinfo_appinfo_metadata_filter_h handle; + std::vector pkgList; + ni_error_e ret = NI_ERROR_NONE; - ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle); - if (ret != PMINFO_R_OK) - return NI_ERROR_UNKNOWN; + // iterates for Packages's metadata (RPK) + pkgmgrinfo_pkginfo_metadata_filter_h pkgHandle; + if (pkgmgrinfo_pkginfo_metadata_filter_create(&pkgHandle) == PMINFO_R_OK) { + if (pkgmgrinfo_pkginfo_metadata_filter_add(pkgHandle, AOT_METADATA_KEY, METADATA_VALUE_TRUE) == PMINFO_R_OK) { + if (pkgmgrPkgMDFilterForeach(pkgHandle, pkgAotCb, &pkgList) != 0) { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrPkgMDFilterForeach failed"); + } + } else { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrinfo_pkginfo_metadata_filter_add failed"); + } + pkgmgrinfo_pkginfo_metadata_filter_destroy(pkgHandle); + } else { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrinfo_pkginfo_metadata_filter_create failed"); + } - ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, AOT_METADATA_KEY, METADATA_VALUE_TRUE); - if (ret != PMINFO_R_OK) { - pkgmgrinfo_appinfo_metadata_filter_destroy(handle); - return NI_ERROR_UNKNOWN; + // iterate for App's metadata + pkgmgrinfo_appinfo_metadata_filter_h appHandle; + if (pkgmgrinfo_appinfo_metadata_filter_create(&appHandle) == PMINFO_R_OK) { + if (pkgmgrinfo_appinfo_metadata_filter_add(appHandle, AOT_METADATA_KEY, METADATA_VALUE_TRUE) == PMINFO_R_OK) { + if (pkgmgrAppMDFilterForeach(appHandle, appAotCb, &pkgList) != 0) { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrAppMDFilterForeach failed"); + } + } else { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrinfo_appinfo_metadata_filter_add failed"); + } + pkgmgrinfo_appinfo_metadata_filter_destroy(appHandle); + } else { + ret = NI_ERROR_UNKNOWN; + _ERR("pkgmgrinfo_appinfo_metadata_filter_create failed"); } - ret = pkgmgrMDFilterForeach(handle, appAotCb, &opt); - if (ret != 0) { - pkgmgrinfo_appinfo_metadata_filter_destroy(handle); - return NI_ERROR_UNKNOWN; + // remove duplicated pkg in the list. + // If one package has multiple apps, there can be duplicate values. + std::sort(pkgList.begin(), pkgList.end()); + pkgList.erase(unique(pkgList.begin(), pkgList.end()), pkgList.end()); + + for (auto pkg : pkgList) { + if (isReadOnlyPkg(pkg) && opt->flags & NI_FLAGS_SKIP_RO_APP) { + continue; + } + + if (removeAndCreateNI(pkg.c_str(), opt) != NI_ERROR_NONE) { + _SERR("Failed to remove previous dlls from [%s]", pkg.c_str()); + ret = NI_ERROR_UNKNOWN; + } else { + _SOUT("Complete make application to native image"); + } } - pkgmgrinfo_appinfo_metadata_filter_destroy(handle); - return NI_ERROR_NONE; + return ret; } // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" @@ -1305,7 +1368,7 @@ ni_error_e regenerateTACNI(NIOption* opt) return NI_ERROR_UNKNOWN; } - ret = pkgmgrMDFilterForeach(handle, regenTacCb, &opt); + ret = pkgmgrAppMDFilterForeach(handle, regenTacCb, &opt); if (ret != 0) { pkgmgrinfo_appinfo_metadata_filter_destroy(handle); return NI_ERROR_UNKNOWN;