}
}
-static bool niExist(const std::string& path, std::string& ni)
+static std::string getNiFileName(const std::string& dllPath)
{
- static std::string possibleExts[] = {
- ".ni.dll", ".NI.dll", ".NI.DLL", ".ni.DLL",
- ".ni.exe", ".NI.exe", ".NI.EXE", ".ni.EXE"
- };
- std::string fName = path.substr(0, path.size() - 4);
+ size_t index = dllPath.find_last_of(".");
+ if (index == std::string::npos) {
+ fprintf(stderr, "File doesnot contain extension. fail to get NI file name\n");
+ return "";
+ }
+ std::string fName = dllPath.substr(0, index);
+ std::string fExt = dllPath.substr(index, dllPath.length());
- struct stat sb;
+ // crossgen generate file with lower case extension only
+ std::transform(fExt.begin(), fExt.end(), fExt.begin(), ::tolower);
+ std::string niPath = fName + ".ni" + fExt;
- for (std::string ext : possibleExts) {
- std::string f = fName + ext;
- if (stat(f.c_str(), &sb) == 0) {
- ni = f;
- return true;
- }
+ return niPath;
+}
+
+static bool niExist(const std::string& path)
+{
+ std::string f = getNiFileName(path);
+ if (f.empty()) {
+ return false;
+ }
+
+ if (isFileExist(f)) {
+ return true;
}
// native image of System.Private.CoreLib.dll should have to overwrite
if (path.find("System.Private.CoreLib.dll") != std::string::npos) {
std::string coreLibBackup = path + ".Backup";
if (isFileExist(coreLibBackup)) {
- ni = path;
return true;
}
}
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 ni_error_e 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 NI_ERROR_NO_SUCH_FILE;
+ }
+
+ if (!isManagedAssembly(dllPath)) {
+ fprintf(stderr, "Input file is not a dll file : %s\n", dllPath.c_str());
+ return NI_ERROR_INVALID_PARAMETER;
+ }
+
+ if (niExist(dllPath)) {
+ fprintf(stderr, "Already ni file is exist for %s\n", dllPath.c_str());
+ return NI_ERROR_ALREADY_EXIST;
+ }
+
std::string absDllPath = absolutePath(dllPath);
+ std::string absNiPath = getNiFileName(dllPath);
+ if (absNiPath.empty()) {
+ fprintf(stderr, "Fail to get ni file name\n");
+ return NI_ERROR_UNKNOWN;
+ }
pid_t pid = fork();
if (pid == -1)
- return;
+ return NI_ERROR_UNKNOWN;
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 NI_ERROR_NONE;
+ } else {
+ fprintf(stderr, "Fail to create native image for %s\n", dllPath.c_str());
+ return NI_ERROR_NO_SUCH_FILE;
+ }
}
} else {
std::string jitPath = getRuntimeDir() + "/libclrjit.so";
}
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);
execv(__CROSSGEN_PATH, const_cast<char* const*>(argv.data()));
exit(0);
}
+
+ return NI_ERROR_NONE;
}
-static int getRootPath(std::string pkgId, std::string& rootPath)
+static ni_error_e getRootPath(std::string pkgId, std::string& rootPath)
{
int ret = 0;
char *path = 0;
if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
_ERR("Failed to get UID");
- return -1;
+ return NI_ERROR_UNKNOWN;
}
pkgmgrinfo_pkginfo_h handle;
if (uid == 0) {
ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
if (ret != PMINFO_R_OK)
- return -1;
+ return NI_ERROR_UNKNOWN;
} else {
ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
if (ret != PMINFO_R_OK)
- return -1;
+ return NI_ERROR_UNKNOWN;
}
ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
if (ret != PMINFO_R_OK) {
pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return -1;
+ return NI_ERROR_UNKNOWN;
}
rootPath = path;
pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return 0;
+ return NI_ERROR_NONE;
}
-
+// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
{
char *pkgId = NULL;
int ret = 0;
+ bool* enableR2R = (bool*)userData;
ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
if (ret != PMINFO_R_OK) {
}
// Regenerate ni files with R2R mode forcibiliy. (there is no way to now which option is used)
- if (createNiUnderPkgRoot(pkgId, true) != 0) {
+ if (createNiUnderPkgRoot(pkgId, *enableR2R) != 0) {
fprintf(stderr, "Failed to get root path from [%s]\n", pkgId);
return -1;
} else {
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");
}
}
}
-int initNICommon(NiCommonOption* option)
+ni_error_e initNICommon(NiCommonOption* option)
{
+#if defined(__arm__)
// get interval value
const char* intervalFile = "/usr/share/dotnet.tizen/lib/crossgen_interval.txt";
std::ifstream inFile(intervalFile);
if (initializePluginManager("normal")) {
fprintf(stderr, "Fail to initialize plugin manager\n");
- return -1;
+ return NI_ERROR_UNKNOWN;
}
if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) {
fprintf(stderr, "Fail to initialize path manager\n");
- return -1;
+ return NI_ERROR_UNKNOWN;
}
__tpa = getTPA();
- return 0;
+ return NI_ERROR_NONE;
+#else
+ fprintf(stderr, "crossgen supports arm architecture only. skip ni file generation\n");
+ return NI_ERROR_NOT_SUPPORTED;
+#endif
}
void finalizeNICommon()
void createNiPlatform(bool enableR2R)
{
const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
-
createNiUnderDirs(platformDirs, 2, enableR2R);
}
-void createNiDll(const std::string& dllPath, bool enableR2R)
+ni_error_e 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;
+ // System.Private.CoreLib.dll is generated in the createCoreLibNI function.
+ // Skip if input dll is System.Private.CoreLib.dll
+ if (dllPath.find("System.Private.CoreLib.dll") != std::string::npos) {
+ return NI_ERROR_NONE;
}
- 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);
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)
+ni_error_e createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
{
std::string pkgRoot;
- if (getRootPath(pkgName, pkgRoot) < 0)
- return -1;
+ if (getRootPath(pkgName, pkgRoot) != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
+ return NI_ERROR_INVALID_PACKAGE;
+ }
std::string binDir = concatPath(pkgRoot, "bin");
std::string libDir = concatPath(pkgRoot, "lib");
createNiUnderDirs(paths, 2, enableR2R);
- return 0;
+ return NI_ERROR_NONE;
}
-int createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
{
std::string pkgRoot;
- if (getRootPath(pkgName, pkgRoot) < 0)
- return -1;
+ if (getRootPath(pkgName, pkgRoot) < 0) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
+ return NI_ERROR_INVALID_PACKAGE;
+ }
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()
scanFilesInDir(rootPaths[i], convert, -1);
}
-int removeNiUnderPkgRoot(const std::string& pkgName)
+ni_error_e removeNiUnderPkgRoot(const std::string& pkgName)
{
std::string pkgRoot;
- if (getRootPath(pkgName, pkgRoot) < 0)
- return -1;
+ if (getRootPath(pkgName, pkgRoot) < 0) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
+ return NI_ERROR_INVALID_PACKAGE;
+ }
std::string binDir = concatPath(pkgRoot, "bin");
std::string libDir = concatPath(pkgRoot, "lib");
removeNiUnderDirs(paths, 2);
- return 0;
+ return NI_ERROR_NONE;
}
-int regenerateAppNI()
+ni_error_e regenerateAppNI(bool enableR2R)
{
int ret = 0;
pkgmgrinfo_appinfo_metadata_filter_h handle;
ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
if (ret != PMINFO_R_OK)
- return -1;
+ return NI_ERROR_UNKNOWN;
ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, "http://tizen.org/metadata/prefer_dotnet_aot", "true");
if (ret != PMINFO_R_OK) {
pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
+ return NI_ERROR_UNKNOWN;
}
- ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, NULL);
+ ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, &enableR2R);
if (ret != PMINFO_R_OK) {
fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
+ return NI_ERROR_UNKNOWN;
}
fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return 0;
+ return NI_ERROR_NONE;
}