android signing

This commit is contained in:
2026-01-01 16:13:08 +02:00
parent 37f689f36d
commit 95d7489aa3
8 changed files with 180 additions and 15 deletions

View File

@@ -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<CUtlString> 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 = {};

View File

@@ -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<CUtlString> BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName );
virtual CUtlVector<CUtlString> BuildArchiveCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName );
//virtual CUtlVector<CUtlString> BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName );
//virtual CUtlVector<CUtlString> 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<CUtlString> &cmd, LinkProject_t *pProject ) override;
virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) override;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd) override;
// sets rpath
@@ -50,6 +44,94 @@ protected:
virtual void LinkLibraryPath( CUtlVector<CUtlString> &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<CUtlString> &cmd, LinkProject_t *pProject )
{
}
void CClangLinker::SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot )
{
}
void CClangLinker::SetOutputFile( CUtlVector<CUtlString> &cmd)
{
}
void CClangLinker::SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd )
{
}
void CClangLinker::UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse )
{
}
void CClangLinker::UseDynamicLookup( CUtlVector<CUtlString> &cmd, bool bUse )
{
}
void CClangLinker::UseFullFile( CUtlVector<CUtlString> &cmd )
{
}
void CClangLinker::UsePartialFile( CUtlVector<CUtlString> &cmd )
{
}
void CClangLinker::LinkFile( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CClangLinker::LinkLibraryObject( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CClangLinker::LinkLibrary( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CClangLinker::LinkLibraryPath( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME);
CUtlString CClangLinker::Link( LinkProject_t *pProject )

View File

@@ -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();

View File

@@ -106,9 +106,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<CUtlString> &cmd, LinkProject_t *pProject ) = 0;
virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) = 0;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd ) = 0;

16
fpc/public/legal.h Normal file
View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);