From f88888388a9129f308592b0bf7941cad35a206f9 Mon Sep 17 00:00:00 2001 From: anders_k Date: Wed, 9 Dec 2015 00:47:50 +0000 Subject: [PATCH] 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 --- Source/build.cpp | 38 +++++++++++++++------------- Source/build.h | 5 ++-- Source/script.cpp | 63 ++++++++++++++++++++++++++++++----------------- Source/tokens.cpp | 2 ++ Source/tokens.h | 2 ++ 5 files changed, 69 insertions(+), 41 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 6fd1add1..bcc85a51 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -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); diff --git a/Source/build.h b/Source/build.h index c37c3471..7bd865c2 100644 --- a/Source/build.h +++ b/Source/build.h @@ -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); diff --git a/Source/script.cpp b/Source/script.cpp index 12013a57..0dc5e61f 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -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; } } diff --git a/Source/tokens.cpp b/Source/tokens.cpp index f0936c43..48ae6e4a 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -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}, diff --git a/Source/tokens.h b/Source/tokens.h index 089b25b5..fe93b20b 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -76,6 +76,8 @@ enum TOK_VI_SETPRODUCTVERSION, TOK_VI_SETFILEVERSION, #ifdef _UNICODE + TOK_TARGET, + TOK_TARGETCPU, TOK_TARGETUNICODE, #endif