Added experimental Target and CPU attributes

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6664 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2015-12-09 00:47:50 +00:00
parent 5e4e293df7
commit f88888388a
5 changed files with 69 additions and 41 deletions

View file

@ -3792,10 +3792,12 @@ int CEXEBuild::change_target_architecture(TARGETTYPE tt)
const bool wide = TARGET_X86ANSI != tt;
if (build_compressor_set || (build_unicode != wide && build_lockedunicodetarget))
{
ERROR_MSG(_T("Error: Can't change target architecture after data already got compressed!\n"));
ERROR_MSG(_T("Error: Can't change target %") NPRIs _T(" after data already got compressed or header already changed!\n"), _T("architecture"));
return PS_ERROR;
}
if (TARGET_X86ANSI == m_target_type || TARGET_X86UNICODE == m_target_type)
m_previous_x86_unicode = build_unicode;
m_target_type = tt;
build_unicode = wide;
@ -3807,16 +3809,6 @@ int CEXEBuild::change_target_architecture(TARGETTYPE tt)
return ec;
}
#ifdef _UNICODE
int CEXEBuild::set_target_charset(bool unicode)
{
if (build_lockedunicodetarget) return PS_ERROR;
TARGETTYPE tt = unicode ? m_target_type : TARGET_X86ANSI;
if (TARGET_X86ANSI == tt && unicode) tt = TARGET_X86UNICODE;
return change_target_architecture(tt);
}
#endif
int CEXEBuild::set_compressor(const tstring& compressor, const bool solid) {
stub_filename = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor;
if (solid)
@ -3838,15 +3830,27 @@ const TCHAR* CEXEBuild::get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*
{
switch(tt)
{
case TARGET_X86ANSI :return _T("x86-ansi");
case TARGET_X86UNICODE:return _T("x86-unicode");
#if !defined(_WIN32) || defined(_WIN64) // BUGBUG: Need a better define for this
case TARGET_AMD64 :return _T("amd64-unicode");
#endif
default:return defval;
case TARGET_X86ANSI : return _T("x86-ansi");
case TARGET_X86UNICODE: return _T("x86-unicode");
case TARGET_AMD64 : return _T("amd64-unicode");
default: return defval;
}
}
void CEXEBuild::print_bad_targettype_parameter(const TCHAR*cmdname, const TCHAR*prefix) const
{
tstring errstr = cmdname;
errstr += _T(": Target parameter must be one of: "), errstr += prefix;
for(int comma = 0, i = CEXEBuild::TARGETFIRST; i < CEXEBuild::TARGETCOUNT; ++i)
{
const TCHAR *ts = get_target_suffix((CEXEBuild::TARGETTYPE) i, 0);
if (!ts) continue;
if (comma++) errstr += _T(", "), errstr += prefix;
errstr += ts;
}
ERROR_MSG(_T("Error: %") NPRIs _T("\n"), errstr.c_str());
}
int CEXEBuild::load_stub()
{
return update_exehead(stub_filename+_T("-")+get_target_suffix(), &m_exehead_original_size);

View file

@ -127,10 +127,12 @@ class CEXEBuild {
} TARGETTYPE;
TARGETTYPE m_target_type;
TARGETTYPE get_target_type(const TCHAR*s) const;
bool m_previous_x86_unicode;
const TCHAR* get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*defval = _T("?")) const;
const TCHAR* get_target_suffix() const {return get_target_suffix(m_target_type);}
const TCHAR* get_target_suffix() const { return get_target_suffix(m_target_type); }
static bool is_targettype_64bit(TARGETTYPE tt) { return TARGET_AMD64 == tt; }
bool is_target_64bit() const { return is_targettype_64bit(m_target_type); }
void print_bad_targettype_parameter(const TCHAR*cmdname, const TCHAR*prefix = _T("")) const;
unsigned int get_header_size() const { return (unsigned int)sizeof(header) + (is_target_64bit() ? (4 * BLOCKS_NUM) : 0); }
void set_default_output_filename(const tstring& filename);
@ -169,7 +171,6 @@ class CEXEBuild {
int prepare_uninstaller();
int pack_exe_header();
int set_target_charset(bool unicode);
int set_compressor(const tstring& compressor, const bool solid);
int load_stub();
int update_exehead(const tstring& file, size_t *size=NULL);

View file

@ -2896,23 +2896,51 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_OK;
#ifdef _UNICODE
case TOK_TARGET:
{
const TCHAR *cmdnam = get_commandtoken_name(which_token);
CEXEBuild::TARGETTYPE tt = get_target_type(line.gettoken_str(1));
if (CEXEBuild::TARGET_UNKNOWN == tt)
{
print_bad_targettype_parameter(cmdnam);
return PS_ERROR;
}
if (m_target_type != tt && PS_OK != change_target_architecture(tt))
{
ERROR_MSG(_T("Error: Unable to set target %") NPRIs _T(" (adequate stub not found?)\n"), _T("architecture"));
return PS_ERROR;
}
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\n"), cmdnam, get_target_suffix(tt));
}
return PS_OK;
case TOK_TARGETCPU:
{
int k = line.gettoken_enum(1, _T("x86\0amd64\0x64\0"));
if (-1 == k) PRINTHELP();
CEXEBuild::TARGETTYPE tt = TARGET_AMD64;
if (0 == k) tt = m_previous_x86_unicode ? TARGET_X86UNICODE : TARGET_X86ANSI;
if (m_target_type != tt && PS_OK != change_target_architecture(tt))
{
ERROR_MSG(_T("Error: Unable to set target %") NPRIs _T(" (adequate stub not found?)\n"), _T("architecture"));
return PS_ERROR;
}
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\n"), get_commandtoken_name(which_token), line.gettoken_str(1));
}
return PS_OK;
case TOK_TARGETUNICODE:
{
int k = line.gettoken_enum(1,_T("false\0true\0"));
if (-1==k) PRINTHELP();
SCRIPT_MSG(_T("Unicode: %") NPRIs _T("\n"),k?_T("true"):_T("false"));
const bool newtargetcs = !!k;
if (newtargetcs != build_unicode)
int k = line.gettoken_enum(1, _T("false\0true\0"));
if (-1 == k) PRINTHELP();
CEXEBuild::TARGETTYPE tt = k ? (TARGET_X86ANSI == m_target_type ? TARGET_X86UNICODE : m_target_type) : TARGET_X86ANSI;
if (tt != m_target_type && (build_compressor_set | build_lockedunicodetarget))
{
if (build_compressor_set || build_lockedunicodetarget)
{
ERROR_MSG(_T("Error: Can't change target charset after data already got compressed or header already changed!\n"));
return PS_ERROR;
}
ERROR_MSG(_T("Error: Can't change target %") NPRIs _T(" after data already got compressed or header already changed!\n"), _T("charset"));
return PS_ERROR;
}
if (set_target_charset(newtargetcs) != PS_OK)
SCRIPT_MSG(_T("Unicode: %") NPRIs _T("\n"), k ? _T("true") : _T("false"));
if (is_targettype_64bit(tt) != is_targettype_64bit(m_target_type) || PS_OK != change_target_architecture(tt))
{
ERROR_MSG(_T("Error: Unable to set target charset (adequate stub not found?)\n"));
ERROR_MSG(_T("Error: Unable to set target %") NPRIs _T(" (adequate stub not found?)\n"), _T("charset"));
return PS_ERROR;
}
}
@ -6109,16 +6137,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
arcstr = line.gettoken_str(--numtok);
if (_T('/') != *arcstr || CEXEBuild::TARGET_UNKNOWN == (tt = get_target_type(++arcstr)))
{
tstring errstr = cmdnam;
errstr += _T(": Target parameter must be one of: /");
for(int comma = 0, i = CEXEBuild::TARGETFIRST; i < CEXEBuild::TARGETCOUNT; ++i)
{
const TCHAR *ts = get_target_suffix((CEXEBuild::TARGETTYPE) i, 0);
if (!ts) continue;
if (comma++) errstr += _T(", /");
errstr += ts;
}
ERROR_MSG(_T("Error: %") NPRIs _T("\n"), errstr.c_str());
print_bad_targettype_parameter(cmdnam, _T("/"));
return PS_ERROR;
}
}

View file

@ -218,6 +218,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_STRLEN,_T("StrLen"),2,0,_T("$(user_var: length output) str"),TP_CODE},
{TOK_SUBCAPTION,_T("SubCaption"),2,0,_T("page_number(0-4) new_subcaption"),TP_GLOBAL},
#ifdef _UNICODE
{TOK_TARGET,_T("Target"),1,0,_T("cpu-charset"),TP_GLOBAL},
{TOK_TARGETCPU,_T("CPU"),1,0,_T("x86|amd64"),TP_GLOBAL},
{TOK_TARGETUNICODE,_T("Unicode"),1,0,_T("true|false"),TP_GLOBAL},
#endif
{TOK_UNINSTALLEXENAME,_T("UninstallExeName"),0,0,_T("no longer supported, use WriteUninstaller from section."),TP_ALL},

View file

@ -76,6 +76,8 @@ enum
TOK_VI_SETPRODUCTVERSION,
TOK_VI_SETFILEVERSION,
#ifdef _UNICODE
TOK_TARGET,
TOK_TARGETCPU,
TOK_TARGETUNICODE,
#endif