diff --git a/uppsrc/ide/Builders/AndroidBuilder.cpp b/uppsrc/ide/Builders/AndroidBuilder.cpp index a2704f2e0..9a455ce90 100644 --- a/uppsrc/ide/Builders/AndroidBuilder.cpp +++ b/uppsrc/ide/Builders/AndroidBuilder.cpp @@ -1,6 +1,10 @@ #include "Builders.h" #include "AndroidBuilder.h" +#define METHOD_NAME "AndroidBuilder::" + String(__FUNCTION__) + "(): " +#define ERROR_METHOD_NAME "[ERROR] " METHOD_NAME +#define INFO_METHOD_NAME "[INFO] " METHOD_NAME + const String AndroidBuilder::RES_PKG_FLAG = "ANDROID_RESOURCES_PACKAGE"; Index AndroidBuilder::GetBuildersNames() @@ -40,6 +44,7 @@ bool AndroidBuilder::BuildPackage( const bool isMainPackage = HasFlag("MAIN"); const bool isResourcesPackage = HasFlag(RES_PKG_FLAG); + const bool isBlitz = HasFlag("BLITZ") && ndk_blitz; String uppManifestPath = PackagePath(package); String packageDir = GetFileFolder(uppManifestPath); String assemblyDir = AndroidBuilderUtils::GetAssemblyDir(packageDir, package); @@ -50,24 +55,18 @@ bool AndroidBuilder::BuildPackage( Package pkg; pkg.Load(uppManifestPath); - Vector javaSourceFiles; - Vector nativeFiles; - Vector nativeSourceFiles; - Vector nativeSourceFilesInPackage; - Vector nativeSourceFilesOptions; + Vector javaFiles; + Vector nativeSources; + Vector nativeSourcesOptions; Vector nativeObjects; Index noBlitzNativeSourceFiles; - bool error = false; String androidManifestPath; - bool isBlitz = HasFlag("BLITZ") && ndk_blitz; - String javaSourcesDir = project->GetJavaDir(); String jniSourcesDir = project->GetJniDir(); String pkgJavaSourcesDir = javaSourcesDir + DIR_SEPS + package; - String pkgJniSourcesDir = jniSourcesDir + DIR_SEPS + package; for(int i = 0; i < pkg.GetCount(); i++) { if(!IdeIsBuilding()) return false; @@ -77,58 +76,42 @@ bool AndroidBuilder::BuildPackage( String globalOptions = Gather(pkg[i].option, config.GetKeys()); String filePath = SourcePath(package, pkg[i]); - String fileExt = ToLower(GetFileExt(filePath)); String fileName = NormalizePathSeparator(pkg[i]); String packageFile = AppendFileName(package, fileName); String packageFileDir = GetFileFolder(packageFile); - if(isResourcesPackage) { if(packageFileDir.Find(package + DIR_SEPS) != -1) packageFileDir.Remove(0, String(package + DIR_SEPS).GetCount()); - String filePathInAndroidProject = GetFilePathInAndroidProject(project->GetResDir(), - packageFileDir, - fileName); + String filePathInAndroidProject + = GetFilePathInAndroidProject(project->GetResDir(), packageFileDir, fileName); if(!MovePackageFileToAndroidProject(filePath, filePathInAndroidProject)) - error = true; + return false; } else - if(fileExt == ".java") { - String filePathInAndroidProject = GetFilePathInAndroidProject(javaSourcesDir, - packageFileDir, - fileName); + if(AndroidBuilderUtils::IsJavaFile(filePath)) { + String filePathInAndroidProject + = GetFilePathInAndroidProject(javaSourcesDir, packageFileDir, fileName); if(!RealizePackageJavaSourcesDirectory(package)) return false; if(!MovePackageFileToAndroidProject(filePath, filePathInAndroidProject)) return false; - javaSourceFiles.Add(filePathInAndroidProject); + javaFiles.Add(filePathInAndroidProject); } else - if(fileExt == ".icpp" || fileExt == ".cpp" || fileExt == ".cxx" || - fileExt == ".c" || - fileExt == ".i" || fileExt == ".t") { - String filePathInAndroidProject = GetFilePathInAndroidProject(jniSourcesDir, - packageFileDir, - fileName); - - nativeFiles.Add(filePathInAndroidProject); - nativeSourceFilesOptions.Add(globalOptions); + if(AndroidBuilderUtils::IsCppOrCFile(filePath)) { + nativeSourcesOptions.Add(globalOptions); if(pkg[i].noblitz) noBlitzNativeSourceFiles.Add(packageFile); - if(!MovePackageFileToAndroidProject(filePath, filePathInAndroidProject)) - return false; - - if(fileExt == ".icpp" || fileExt == ".cpp" || fileExt == ".cxx" || - fileExt == ".c") { - nativeSourceFiles.Add(filePathInAndroidProject); - nativeSourceFilesInPackage.Add(NormalizePathSeparator(packageFile)); + if(AndroidBuilderUtils::IsCppOrCFile(filePath)) { + nativeSources.Add(NormalizePathSeparator(filePath)); } } else - if(fileExt == ".xml") { + if(AndroidBuilderUtils::IsXmlFile(filePath)) { if(isMainPackage && fileName == "AndroidManifest.xml") { if(androidManifestPath.GetCount()) { PutConsole("AndroidManifest.xml is duplicated."); @@ -142,7 +125,7 @@ bool AndroidBuilder::BuildPackage( } } else - if(fileExt == ".o") { + if(AndroidBuilderUtils::IsObjectFile(filePath)) { String filePathInAndroidProject = GetFilePathInAndroidProject(jniSourcesDir, packageFileDir, fileName); if(!MovePackageFileToAndroidProject(filePath, filePathInAndroidProject)) @@ -157,66 +140,59 @@ bool AndroidBuilder::BuildPackage( return false; } - DeleteUnusedSourceFiles(pkgJavaSourcesDir, javaSourceFiles, ".java"); - DeleteUnusedSourceFiles(pkgJniSourcesDir, - nativeFiles, - ".icpp, .cpp, .cxx, .c, .hpp, .hxx, .h, .i, .t", - "@blitz.cpp"); - - if(!isResourcesPackage && !error && !javaSourceFiles.IsEmpty()) { + DeleteUnusedSourceFiles(pkgJavaSourcesDir, javaFiles, ".java"); + if(!isResourcesPackage && !javaFiles.IsEmpty()) { if(!RealizeDirectory(project->GetClassesDir())) return false; - linkfile.Add(commands->PreperCompileJavaSourcesCommand(javaSourceFiles)); + linkfile.Add(commands->PreperCompileJavaSourcesCommand(javaFiles)); } - if(!isResourcesPackage && !error && !nativeSourceFiles.IsEmpty()) { - if(isBlitz) { - BlitzBuilderComponent bc(this); - Blitz blitz = bc.MakeBlitzStep(nativeSourceFilesInPackage, - nativeSourceFilesOptions, - nativeObjects, - immfile, - ".o", - noBlitzNativeSourceFiles); - - String destinationFileName = GetFileName(blitz.path); - destinationFileName.Replace("$blitz.cpp", "@blitz.cpp"); - - String blitzDestinationFileInPackage; - blitzDestinationFileInPackage << package << DIR_SEPS; - blitzDestinationFileInPackage << destinationFileName; - - if(FileExists(blitz.path)) { - String blitzDestinationFile; - blitzDestinationFile << project->GetJniDir() << DIR_SEPS; - blitzDestinationFile << blitzDestinationFileInPackage; - - CopyFile(blitzDestinationFile, blitz.path); - - nativeSourceFilesInPackage.Clear(); - nativeSourceFilesInPackage.Add(blitzDestinationFileInPackage); - for(int i = 0; i < noBlitzNativeSourceFiles.GetCount(); i++) - nativeSourceFilesInPackage.Add(noBlitzNativeSourceFiles[i]); - } - } - - AndroidModuleMakeFileCreator creator(config); - - creator.SetModuleName(NormalizeModuleName(package)); - creator.AddSources(nativeSourceFilesInPackage); - creator.AddInclude(assemblyDir); - creator.AddIncludeWithSubdirs(packageDir); - creator.AddIncludes(pkg.uses); - creator.AddFlags(pkg.flag); - creator.AddLdLibraries(pkg.library); - creator.AddStaticModuleLibrary(pkg.static_library); - creator.AddSharedLibraries(pkg.uses); - - UpdateFile(GetModuleMakeFilePath(package), creator.Create()); + if(isResourcesPackage || nativeSources.IsEmpty()) { + LOG(INFO_METHOD_NAME + "There is not native files in following package " + package + "."); + return true; } + + if(isBlitz) { + BlitzBuilderComponent bc(this); + Blitz blitz = bc.MakeBlitzStep( + nativeSources, nativeSourcesOptions, + nativeObjects, immfile, ".o", + noBlitzNativeSourceFiles); + + String destinationFileName = GetFileName(blitz.path); + destinationFileName.Replace("$blitz.cpp", "@blitz.cpp"); + + String blitzDestinationFileInPackage; + blitzDestinationFileInPackage << package << DIR_SEPS; + blitzDestinationFileInPackage << destinationFileName; + + if(FileExists(blitz.path)) { + String blitzDestinationFile; + blitzDestinationFile << project->GetJniDir() << DIR_SEPS; + blitzDestinationFile << blitzDestinationFileInPackage; + + CopyFile(blitzDestinationFile, blitz.path); + + nativeSources.Clear(); + nativeSources.Add(blitzDestinationFileInPackage); + for(int i = 0; i < noBlitzNativeSourceFiles.GetCount(); i++) + nativeSources.Add(noBlitzNativeSourceFiles[i]); + } + } + + AndroidModuleMakeFileCreator creator(config); + + creator.SetModuleName(NormalizeModuleName(package)); + creator.AddSources(nativeSources); + creator.AddInclude(assemblyDir); + creator.AddIncludes(pkg.uses); + creator.AddFlags(pkg.flag); + creator.AddLdLibraries(pkg.library); + creator.AddStaticModuleLibrary(pkg.static_library); + creator.AddSharedLibraries(pkg.uses); - return !error; + return creator.Save(GetModuleMakeFilePath(package)); } bool AndroidBuilder::Link( @@ -337,6 +313,28 @@ bool AndroidBuilder::Preprocess( return false; } +void AndroidBuilder::AddFlags(Index& cfg) +{ + // TODO: Blood hack - should be remove after release. + // Talk with Mirek how to do it well - without over engineering. + // U++ is not ready for full cross compilation right now. + + cfg.RemoveKey("WIN32"); + cfg.RemoveKey("LINUX"); + cfg.RemoveKey("POSIX"); + cfg.RemoveKey("BSD"); + cfg.RemoveKey("FREEBSD"); + cfg.RemoveKey("OPENBSD"); + cfg.RemoveKey("NETBSD"); + cfg.RemoveKey("DRAGONFLY"); + cfg.RemoveKey("SOLARIS"); + cfg.RemoveKey("OSX11"); + + cfg.Add("LINUX"); + cfg.Add("POSIX"); + cfg.Add("ANDROID"); +} + void AndroidBuilder::CleanPackage(const String& package, const String& outdir) { InitProject(); @@ -450,16 +448,19 @@ void AndroidBuilder::DeleteUnusedSourceFiles( bool AndroidBuilder::MovePackageFileToAndroidProject(const String& src, const String& dst) { - if(!RealizeDirectory(GetFileDirectory(dst))) + String directory = GetFileDirectory(dst); + if(!RealizeDirectory(directory)) { + LOG(ERROR_METHOD_NAME + "Cannot relize following directory: \"" + directory + "\"."); return false; + } if(FileExists(dst)) { if(GetFileTime(dst) > GetFileTime(src)) return true; } - SaveFile(dst, LoadFile(src)); - return true; + // TODO: Generic host should return bool flag. + return ::SaveFile(dst, LoadFile(src)); } bool AndroidBuilder::RealizePackageJavaSourcesDirectory(const String& packageName) @@ -840,7 +841,7 @@ String AndroidBuilder::NormalizeModuleName(String moduleName) const return moduleName; } -String AndroidBuilder::GetModuleMakeFilePath(const String& package) +String AndroidBuilder::GetModuleMakeFilePath(const String& package) const { return project->GetJniDir() + DIR_SEPS + package + DIR_SEPS + "Android.mk"; } diff --git a/uppsrc/ide/Builders/AndroidBuilder.h b/uppsrc/ide/Builders/AndroidBuilder.h index f362b41d8..c7286745c 100644 --- a/uppsrc/ide/Builders/AndroidBuilder.h +++ b/uppsrc/ide/Builders/AndroidBuilder.h @@ -31,24 +31,24 @@ public: void SetJdk(One jdk); - virtual String GetTargetExt() const override; - virtual bool BuildPackage( + String GetTargetExt() const override; + bool BuildPackage( const String& packageName, Vector& linkfile, Vector& immfile, String& linkoptions, const Vector& all_uses, const Vector& all_libraries, - int optimize) override; - virtual bool Link( - const Vector& linkfile, const String& linkoptions, bool createmap) override; - virtual bool Preprocess( + int optimize) override; + bool Link(const Vector& linkfile, const String& linkoptions, bool createmap) override; + bool Preprocess( const String& package, const String& file, const String& target, bool asmout) override; - virtual void CleanPackage(const String& package, const String& outdir) override; - virtual void AfterClean() override; + void AddFlags(Index& cfg) override; + void CleanPackage(const String& package, const String& outdir) override; + void AfterClean() override; protected: void ManageProjectCohesion(); @@ -88,7 +88,7 @@ protected: String RemoveDirNameFromFileName(String fileName) const; String NormalizeModuleName(String moduleName) const; - String GetModuleMakeFilePath(const String& packageName); + String GetModuleMakeFilePath(const String& package) const; private: void InitProject(); @@ -127,8 +127,25 @@ public: AndroidBuilderUtils& operator=(AndroidBuilderUtils&) = delete; ~AndroidBuilderUtils() = delete; + // TODO: Core should support creating symbolic link - not builder... + static bool CreateSymlink(const String& symbolicLink, const String& target); + static String GetAssemblyDir(const String& package); static String GetAssemblyDir(const String& packageDir, const String& package); + + static bool IsJavaFile(const String& path); + static bool IsHeaderFile(const String& path); + static bool IsCFile(const String& path); + static bool IsCppFile(const String& path); + static bool IsCppOrCFile(const String& path); + static bool IsObjectFile(const String& path); + static bool IsXmlFile(const String& path); + + static bool IsTranslationFile(const String& path); + +private: + static bool HasExt(const String& path, const Index& exts); + static String NormalizeAndGetFileExt(const String& path); }; class AndroidModuleMakeFileCreator { @@ -140,7 +157,6 @@ public: void AddSources(Vector& sources); void AddInclude(const String& path); - void AddIncludeWithSubdirs(const String& path); void AddIncludes(const Array& uses); void AddFlags(const Array& flags); @@ -148,6 +164,7 @@ public: void AddStaticModuleLibrary(Array& staticLibraries); void AddSharedLibraries(const Array& uses); + bool Save(const String& path); String Create() { return makeFile.ToString(); } private: diff --git a/uppsrc/ide/Builders/AndroidBuilderUtils.cpp b/uppsrc/ide/Builders/AndroidBuilderUtils.cpp index 734de46d8..cf696c616 100644 --- a/uppsrc/ide/Builders/AndroidBuilderUtils.cpp +++ b/uppsrc/ide/Builders/AndroidBuilderUtils.cpp @@ -1,5 +1,8 @@ #include "AndroidBuilder.h" +#define METHOD_NAME "AndroidBuilderUtils::" + String(__FUNCTION__) + "(): " +#define ERROR_METHOD_NAME "[ERROR] " METHOD_NAME + namespace Upp { String AndroidBuilderUtils::GetAssemblyDir(const String& package) @@ -21,4 +24,58 @@ String AndroidBuilderUtils::GetAssemblyDir(const String& packageDir, const Strin return assemblyDir != packageDir ? assemblyDir : ""; } +bool AndroidBuilderUtils::IsJavaFile(const String& path) +{ + return HasExt(path, { "java" }); +} + +bool AndroidBuilderUtils::IsHeaderFile(const String& path) +{ + return HasExt(path, { "i", "h", "hpp", "hxx" }); +} + +bool AndroidBuilderUtils::IsCFile(const String& path) +{ + return HasExt(path, { "c" }); +} + +bool AndroidBuilderUtils::IsCppFile(const String& path) +{ + return HasExt(path, { "icpp", "cpp", "cxx" }); +} + +bool AndroidBuilderUtils::IsCppOrCFile(const String& path) +{ + return HasExt(path, { "c", "icpp", "cpp", "cxx" }); +} + +bool AndroidBuilderUtils::IsXmlFile(const String& path) +{ + return HasExt(path, { "xml" }); +} + +bool AndroidBuilderUtils::IsObjectFile(const String& path) +{ + return HasExt(path, { "o" }); +} + +bool AndroidBuilderUtils::IsTranslationFile(const String& path) +{ + return HasExt(path, { "t" }); +} + +bool AndroidBuilderUtils::HasExt(const String& path, const Index& exts) +{ + return exts.Find(NormalizeAndGetFileExt(path)) != -1; +} + +String AndroidBuilderUtils::NormalizeAndGetFileExt(const String& path) +{ + String ext = ToLower(GetFileExt(path)); + if (ext.StartsWith(".")) { + ext.Remove(0); + } + return ext; +} + } diff --git a/uppsrc/ide/Builders/AndroidModuleMakeFileBuilder.cpp b/uppsrc/ide/Builders/AndroidModuleMakeFileBuilder.cpp index 4efa9300f..9aee0a94c 100644 --- a/uppsrc/ide/Builders/AndroidModuleMakeFileBuilder.cpp +++ b/uppsrc/ide/Builders/AndroidModuleMakeFileBuilder.cpp @@ -1,5 +1,9 @@ #include "AndroidBuilder.h" +#define METHOD_NAME "AndroidModuleMakeFileCreator::" + String(__FUNCTION__) + "(): " +#define ERROR_METHOD_NAME "[ERROR] " METHOD_NAME +#define INFO_METHOD_NAME "[INFO] " METHOD_NAME + namespace Upp { AndroidModuleMakeFileCreator::AndroidModuleMakeFileCreator(const Index& builderConfig) @@ -19,28 +23,6 @@ void AndroidModuleMakeFileCreator::AddInclude(const String& path) makeFile.AddInclude(path); } -void AndroidModuleMakeFileCreator::AddIncludeWithSubdirs(const String& path) -{ - BiVector dirs { path }; - while(!dirs.IsEmpty()) { - for(FindFile ff(AppendFileName(dirs.Head(), "*")); ff; ff.Next()) { - if(ff.IsHidden() || ff.IsSymLink() || !ff.IsFolder()) { - continue; - } - - String name = ff.GetName(); - if (name.EndsWith(".tpp")) { - continue; - } - - dirs.AddTail(ff.GetPath()); - } - - AddInclude(dirs.Head()); - dirs.DropHead(); - } -} - void AndroidModuleMakeFileCreator::AddIncludes(const Array& uses) { for(const OptItem& use : uses) { @@ -78,4 +60,26 @@ void AndroidModuleMakeFileCreator::AddSharedLibraries(const Array& uses } } +bool AndroidModuleMakeFileCreator::Save(const String& path) +{ + String directory = GetFileDirectory(path); + if (!RealizeDirectory(directory)) { + LOG(ERROR_METHOD_NAME + "Creating module directory failed \"" + directory + "\"."); + return false; + } + + String data = Create(); + if (FileExists(path) && LoadFile(path) == data) { + LOG(INFO_METHOD_NAME + "Following file \"" + path + "\" content is the same as previous one."); + return true; + } + + if (!SaveFile(path, Create())) { + LOG(ERROR_METHOD_NAME + "Saving module file failed \"" + path + "\"."); + return false; + } + + return true; +} + } diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h index 7cfda059d..eb9dce114 100644 --- a/uppsrc/ide/Core/Core.h +++ b/uppsrc/ide/Core/Core.h @@ -434,8 +434,8 @@ struct Builder { { return false; } virtual void CleanPackage(const String& package, const String& outdir) {} virtual void AfterClean() {} - virtual void AddFlags(Index& cfg) {} - virtual void AddMakeFile(MakeFile& mfinfo, String package, + virtual void AddFlags(Index& cfg) {} + virtual void AddMakeFile(MakeFile& mfinfo, String package, const Vector& all_uses, const Vector& all_libraries, const Index& common_config, bool exporting) {} virtual String GetTargetExt() const = 0; diff --git a/uppsrc/ide/Core/Host.cpp b/uppsrc/ide/Core/Host.cpp index 108de5cf4..ff581b850 100644 --- a/uppsrc/ide/Core/Host.cpp +++ b/uppsrc/ide/Core/Host.cpp @@ -80,7 +80,7 @@ void LocalHost::RealizeDir(const String& path) DoDir(path); } -void LocalHost::SaveFile(const String& path, const String& data) +void LocalHost::SaveFile(const String& path, const String& data) { ::SaveFile(path, data); }