diff --git a/fpc/library/android/apktool.cpp b/fpc/library/android/apktool.cpp index 7b413d6..c961e88 100644 --- a/fpc/library/android/apktool.cpp +++ b/fpc/library/android/apktool.cpp @@ -53,7 +53,7 @@ CUtlString AndroidManifest_t::BuildManifest() CPUProject_t project = {}; project.m_szName = m_szPackageName; unsigned int hash = project.GenerateProjectHash(); - CUtlString szOutputDir = CUtlString("%s/%s/android/%u_%s/",FPC_TEMPORAL_DIRNAME, project.m_target.GetTriplet().GetString(), hash, m_szPackageID.GetString()); + CUtlString szOutputDir = CUtlString("%s/android/%u_%s/",FPC_TEMPORAL_DIRNAME, hash, m_szPackageID.GetString()); filesystem2->MakeDirectory(szOutputDir); filesystem2->MakeDirectory(CUtlString("%s/res", szOutputDir.GetString())); @@ -84,6 +84,7 @@ class CAPKTool : public IAPKTool { public: virtual CUtlString BuildPackage( AndroidManifest_t manifest, CUtlString szManifestDir ) override; + virtual CUtlString SignPackage( const char *szApk, LegalInfo_t *pLegalInfo, const char *szAlias, const char *szStorePassword, const char *szKeyPassword ) override; private: }; @@ -131,9 +132,74 @@ CUtlString CAPKTool::BuildPackage( AndroidManifest_t manifest, CUtlString szMani CUtlString("%s.apk", manifest.m_szPackageID.GetString()), }; runner->Run(CUtlString("%s/zipalign",szBuildTools),szManifestDir,args); - return manifest.m_szPackageID; + runner->Wait(); + + return CUtlString("%s/%s.apk",szManifestDir.GetString(), manifest.m_szPackageID.GetString()); } +CUtlString CAPKTool::SignPackage( const char *szApk, LegalInfo_t *pLegalInfo, const char *szAlias, const char *szStorePassword, const char *szKeyPassword ) +{ + V_printf(" APKSIGN %s\n", szApk ); + CUtlString szOutput = CUtlString("%s.signed", szApk); + LegalInfo_t stLegalInfo = {}; + CUtlVector args = {}; + + CPUProject_t project = {}; + project.m_szName = szAlias; + unsigned int hash = project.GenerateProjectHash(); + CUtlString szOutputDir = CUtlString("%s/android/%u_%s/",FPC_TEMPORAL_DIRNAME, hash, szAlias); + filesystem2->MakeDirectory(szOutputDir); + CUtlString szKeystoreDir = CUtlString("%s/%s.jks",szOutputDir.GetString(),szAlias); + CUtlString szDname = ""; + + IINISection *pSection = NULL; + const char *szBuildTools; + pSection = g_pConfig->GetSection("Android_Build_Tools"); + if (!pSection) + Plat_FatalErrorFunc("build_tools are required for this target"); + szBuildTools = pSection->GetStringValue("path"); + + // We need to have a name at least + stLegalInfo.FirstName = "Gordon"; + stLegalInfo.LastName = "Freeman"; + + if (pLegalInfo != NULL) + stLegalInfo = *pLegalInfo; + + if (!stLegalInfo.FirstName) + Plat_FatalErrorFunc("First name wasn't provided\n"); + if (!stLegalInfo.LastName) + Plat_FatalErrorFunc("Last name wasn't provided\n"); + szDname.AppendTail(CUtlString("CN=%s %s", stLegalInfo.FirstName, stLegalInfo.LastName)); + + args = { + "-genkeypair", + "-keystore", szKeystoreDir, + "-alias", szAlias, + "-keyalg", "RSA", + "-keysize", "2048", + "-validity", "10000", + "-storepass", szStorePassword, + "-keypass", szKeyPassword, + "-dname", szDname, + }; + runner->Run("keytool", args); + runner->Wait(); + + args = { + "sign", + "--ks", szKeystoreDir, + "--ks-key-alias", szAlias, + "--ks-pass", CUtlString("pass:%s",szStorePassword), + "--key-pass", CUtlString("pass:%s",szKeyPassword), + szApk, + }; + runner->Run(CUtlString("%s/apksigner",szBuildTools), args); + runner->Wait(); + + return szApk; +}; + IAPKTool *APKTool() { static CAPKTool s_apktool = {}; diff --git a/fpc/library/clang/ld.cpp b/fpc/library/clang/ld.cpp index 0d1c789..0d8828b 100644 --- a/fpc/library/clang/ld.cpp +++ b/fpc/library/clang/ld.cpp @@ -12,21 +12,15 @@ public: virtual CUtlString Link( LinkProject_t *pProject ) override; virtual bool IsLibraryExists( CUtlString szName ) override; protected: - // Returns file name of the - CUtlString GetOutputObjectName( LinkProject_t *pProject, unsigned int hash, CUtlString szFileName ); - - virtual CUtlVector BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); - virtual CUtlVector BuildArchiveCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); + //virtual CUtlVector BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); + //virtual CUtlVector BuildArchiveCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); // Returns executable which should the OS run virtual const char *GetCompilerExecutable( LinkProject_t *pProject ) override; - - // returns object file format, eg .obj or .o - virtual const char *GetOutputObjectFormat() override; virtual void SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) override; virtual void SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) override; - virtual void SetOutputFile( CUtlVector &cmd, const char *szName ) override; + virtual void SetOutputFile( CUtlVector &cmd) override; // sets rpath @@ -50,6 +44,94 @@ protected: virtual void LinkLibraryPath( CUtlVector &cmd, const char *szName ) override; }; + + +const char *CClangLinker::GetCompilerExecutable( LinkProject_t *pProject ) +{ + IINISection *pSection = NULL; + const char *szLinker = "clang++"; + if (!g_pConfig) + return szLinker; + + + pSection = g_pConfig->GetSection(pProject->m_target.GetTriplet()); + if (!pSection) + return szLinker; + + + szLinker = pSection->GetStringValue("CLANG_LINKER_INTERFACE_NAME"); + if (szLinker == NULL) + return "clang++"; + return szLinker; +} + + + +void CClangLinker::SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) +{ + +} + +void CClangLinker::SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) +{ + +} + +void CClangLinker::SetOutputFile( CUtlVector &cmd) +{ + +} + +void CClangLinker::SetDefaultLibraryPaths( CUtlVector &cmd ) +{ + +} + + +void CClangLinker::UseStdLib( CUtlVector &cmd, bool bUse ) +{ + +} + + +void CClangLinker::UseDynamicLookup( CUtlVector &cmd, bool bUse ) +{ + +} + + +void CClangLinker::UseFullFile( CUtlVector &cmd ) +{ + +} + + +void CClangLinker::UsePartialFile( CUtlVector &cmd ) +{ + +} + + +void CClangLinker::LinkFile( CUtlVector &cmd, const char *szName ) +{ + +} + +void CClangLinker::LinkLibraryObject( CUtlVector &cmd, const char *szName ) +{ + +} + +void CClangLinker::LinkLibrary( CUtlVector &cmd, const char *szName ) +{ + +} + +void CClangLinker::LinkLibraryPath( CUtlVector &cmd, const char *szName ) +{ + +} + EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME); CUtlString CClangLinker::Link( LinkProject_t *pProject ) diff --git a/fpc/public/apktool.h b/fpc/public/apktool.h index 12a1f29..8a64624 100644 --- a/fpc/public/apktool.h +++ b/fpc/public/apktool.h @@ -7,6 +7,7 @@ #include "tier0/platform.h" #include "tier1/utlstring.h" +#include "legal.h" struct AndroidManifest_t { @@ -36,6 +37,7 @@ abstract_class IAPKTool { public: virtual CUtlString BuildPackage( AndroidManifest_t manifest, CUtlString szManifestDir ) = 0; + virtual CUtlString SignPackage( const char *szApk, LegalInfo_t *pLegalInfo, const char *szAlias, const char *szStorePassword, const char *szKeyPassword ) = 0; }; IAPKTool *APKTool(); diff --git a/fpc/public/ld.h b/fpc/public/ld.h index 710cfc1..b276e87 100644 --- a/fpc/public/ld.h +++ b/fpc/public/ld.h @@ -105,9 +105,6 @@ protected: // Returns executable which should the OS run virtual const char *GetCompilerExecutable( LinkProject_t *pProject ) = 0; - - // returns object file format, eg .obj or .o - virtual const char *GetOutputObjectFormat() = 0; virtual void SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) = 0; virtual void SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) = 0; diff --git a/fpc/public/legal.h b/fpc/public/legal.h new file mode 100644 index 0000000..9097751 --- /dev/null +++ b/fpc/public/legal.h @@ -0,0 +1,16 @@ +#ifndef LEGAL_H +#define LEGAL_H + +struct LegalInfo_t +{ + const char *FirstName; + const char *LastName; + const char *OrganizationalUnitName; + const char *OrganizationName; + const char *City; + const char *State; + const char *CountryCode; +}; + + +#endif diff --git a/fpc/tests/android_build/build.cpp b/fpc/tests/android_build/build.cpp index 42ec776..5318a80 100644 --- a/fpc/tests/android_build/build.cpp +++ b/fpc/tests/android_build/build.cpp @@ -31,7 +31,8 @@ DECLARE_BUILD_STAGE(android_build) filesystem2->MakeDirectory(CUtlString("%s/lib/x86_64",szManifestDir.GetString())); filesystem2->CopyFile(CUtlString("%s/lib/x86_64/libnative-app.so",szManifestDir.GetString()), szOutputDir); - APKTool()->BuildPackage(manifest, szManifestDir); + CUtlString szApk = APKTool()->BuildPackage(manifest, szManifestDir); + APKTool()->SignPackage(szApk, NULL, "mykey", "storepass", "storepass"); return 0; } diff --git a/fpc/tests/android_build/main.c b/fpc/tests/android_build/main.c index 118e3ff..1c77754 100644 --- a/fpc/tests/android_build/main.c +++ b/fpc/tests/android_build/main.c @@ -26,6 +26,7 @@ void android_main(struct android_app* app) { struct android_poll_source* source; while (1) { + LOGI("what"); int ident; while ((ident = ALooper_pollOnce(0, NULL, &events, (void**)&source)) >= 0) { if (source) source->process(app, source); diff --git a/fpc/tests/android_build/my-release-key.jks b/fpc/tests/android_build/my-release-key.jks index 091a293..227d6f7 100644 Binary files a/fpc/tests/android_build/my-release-key.jks and b/fpc/tests/android_build/my-release-key.jks differ