linux下使用mingw编译NSIS-3.03
简述
最近在研究使用NSIS
做安装包,语法不算复杂,插件也很多,中文资料也不少,还挺好用的。先后用NSIS做出了安装和卸载需要输入密码,通过自定义页面实现安装时候选择多个目录、安装的时候输入配置文件信息,禁止在某些平台或环境下安装,检测是否已经安装或正在运行等,稍后将把这些都放出来,做个记录。
有一个问题就是NSIS
打包的文件可以直接使用7zip
解压,安装过程做的事情就被跳过了。为了解决这个问题,我想修改一下NSIS
的源码,来使得打包的程序无法使用7zip
等软件解压。这里记录一下编译过程。
修改过的文件及编译好的文件下载nsis-3.03-src_修改.7z
准备工作
我是在linux
下使用mingw32
进行编译的,所以先要安装mingw32
。
然后是下载zlib
库,我是在这里下载的https://jaist.dl.sourceforge.net/project/mingw/MinGW/Extension/zlib/zlib-1.2.3-1-mingw32/libz-1.2.3-1-mingw32-dev.tar.gz,这个说不定哪天就过期了,这是项目的页面https://sourceforge.net/projects/mingw/files/MinGW/Extension/zlib/。
下载之后解压,将其中lib
目录下的文件拷贝到/usr/lib/gcc/i686-w64-mingw32/6.3-win32/lib
目录下,将include
目录下的文件拷贝到/usr/lib/gcc/i686-w64-mingw32/6.3-win32/include
目录下。
然后是下载NSIS-3.03
的源码,地址在这里[https://jaist.dl.sourceforge.net/project/nsis/NSIS 3/3.03/nsis-3.03-src.tar.bz2](https://jaist.dl.sourceforge.net/project/nsis/NSIS 3/3.03/nsis-3.03-src.tar.bz2),下载之后解压即可。
因为NSIS
使用scons
进行构建,所以还需要安装python2.7
和scons
工具。
编译过程
关于NSIS
的编译,在这里Appendix G: Building NSIS有部分介绍。
准备工作做好后,使用下面命令进行构建。
scons SKIPSTUBS=all XGCC_W32_PREFIX=i686-w64-mingw32- SKIPPLUGINS=all SKIPUTILS=all SKIPMISC=all NSIS_CONFIG_CONST_DATA_PATH=no PREFIX=./build
如果没有问题的话,正常会构建成功。但是会发现一个问题,build/urelease/makensis
下面没有生成makensis.exe
文件,只有一个makensis
文件,而且使用readelf
查看,这是一个ELF
文件,而不是PE
格式文件。
使用PETool查看结果如下:
这个错误的原因在这里:
根据这个报错,查看了Sconstruct
文件后,找到错误的原因,是因为其中一个环境变量没有设置对。
打开nsis-3.03-src/SCons/Config/gnu
文件,找到364行,在下面添加一行内容makensis_env.Replace(CXX = stub_env['CXX'])
。
然后重新执行构建命令。
解决完g++
的问题后,继续编译遇到下面的问题。
下面有些修改其实是因为PLATFROM
没有识别或者设置为win32
的原因。
错误 Source/scriptpp.cpp:1054:93: error: call to non-constexpr function 'size_t wcslen(const wchar_t*)'
i686-w64-mingw32-g++ -o build/urelease/makensis/scriptpp.o -c -Wno-non-virtual-dtor -Wall -O2 -DNSISCALL= -D_UNICODE -DUNICODE -DMAKENSIS -D_WIN32_IE=0x0500 -Ibuild/urelease/config Source/scriptpp.cpp
In file included from /usr/share/mingw-w64/include/minwindef.h:163:0,
from /usr/share/mingw-w64/include/windef.h:8,
from /usr/share/mingw-w64/include/windows.h:69,
from Source/Platform.h:38,
from Source/scriptpp.cpp:17:
Source/scriptpp.cpp: In member function 'int CEXEBuild::pp_finalize(LineParser&)':
Source/scriptpp.cpp:1054:93: error: call to non-constexpr function 'size_t wcslen(const wchar_t*)'
newcmd = (struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd, cmd[_tcsclen(cmdstr)+1])]);
这里FIELD_OFFSET
宏的参数应该是结构体的名称
和成员的名称
,但这里明显不是,结合代码上下文来看,我把这里给修改为了
newcmd = (struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd, cmd)* (_tcsclen(cmdstr)+1)]);
没有仔细研究它的代码,所以这里就多分配一点了。
继续编译。
错误 Source/util.cpp:1072:11: error: jump to label 'finalwrite' [-fpermissive]
i686-w64-mingw32-g++ -o build/urelease/makensis/util.o -c -Wno-non-virtual-dtor -Wall -O2 -DNSISCALL= -D_UNICODE -DUNICODE -DMAKENSIS -D_WIN32_IE=0x0500 -Ibuild/urelease/config Source/util.cpp
Source/util.cpp: In function 'int RunChildProcessRedirected(LPCWSTR, LPCWSTR, bool)':
Source/util.cpp:1072:11: error: jump to label 'finalwrite' [-fpermissive]
{ finalwrite:
^~~~~~~~~~
Source/util.cpp:1085:25: note: from here
if (cchwb) goto finalwrite; // End of stream without a ending newline, write out the remaining data.
^~~~~~~~~~
Source/util.cpp:1033:17: note: skips initialization of 'DWORD i'
for(DWORD i = 0; i < cbRead;)
^
Source/util.cpp: At global scope:
Source/util.cpp:1159:15: warning: 'void* NSISRT_GetConsoleScreenHandle()' defined but not used [-Wunused-function]
static HANDLE NSISRT_GetConsoleScreenHandle()
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scons: *** [build/urelease/makensis/util.o] Error 1
scons: building terminated because of errors.
看来一下这里的代码,比较繁杂,就不改了,直接使用下面的命令先编译通过
i686-w64-mingw32-g++ -o build/urelease/makensis/util.o -c -fpermissive -Wno-non-virtual-dtor -Wall -O2 -DNSISCALL= -D_UNICODE -DUNICODE -DMAKENSIS -D_WIN32_IE=0x0500 -Ibuild/urelease/config Source/util.cpp
这里需要再次修改一下nsis-3.03-src/SCons/Config/gnu
文件,在119行下添加一行makensis_env.Append(CXXFLAGS = ['-fpermissive'])
修改直接继续编译。
错误 build/urelease/makensis/crc32.o: file not recognized: File format not recognized
解决上面的错误之后,编译就没有问题了,一直到最后的链接这一步,又有点小问题了。
gcc -o build/urelease/makensis/crc32.o -c -Wall -O2 -DNSISCALL= -D_UNICODE -DUNICODE -DMAKENSIS -D_WIN32_IE=0x0500 -Ibuild/urelease/config Source/crc32.c
i686-w64-mingw32-g++ -o build/urelease/makensis/makensis -Wl,-Map,build/urelease/makensis/makensis.map -s -pthread build/urelease/makensis/build.o build/urelease/makensis/clzma.o build/urelease/makensis/crc32.o build/urelease/makensis/DialogTemplate.o build/urelease/makensis/dirreader.o build/urelease/makensis/fileform.o build/urelease/makensis/growbuf.o build/urelease/makensis/icon.o build/urelease/makensis/lang.o build/urelease/makensis/lineparse.o build/urelease/makensis/makenssi.o build/urelease/makensis/manifest.o build/urelease/makensis/mmap.o build/urelease/makensis/Plugins.o build/urelease/makensis/ResourceEditor.o build/urelease/makensis/ResourceVersionInfo.o build/urelease/makensis/BinInterop.o build/urelease/makensis/script.o build/urelease/makensis/scriptpp.o build/urelease/makensis/ShConstants.o build/urelease/makensis/strlist.o build/urelease/makensis/tokens.o build/urelease/makensis/tstring.o build/urelease/makensis/utf.o build/urelease/makensis/util.o build/urelease/makensis/winchar.o build/urelease/makensis/writer.o build/urelease/makensis/bzip2/blocksort.o build/urelease/makensis/bzip2/bzlib.o build/urelease/makensis/bzip2/compress.o build/urelease/makensis/bzip2/huffman.o build/urelease/makensis/7zip/7zGuids.o build/urelease/makensis/7zip/7zip/Common/OutBuffer.o build/urelease/makensis/7zip/7zip/Common/StreamUtils.o build/urelease/makensis/7zip/7zip/Compress/LZ/LZInWindow.o build/urelease/makensis/7zip/7zip/Compress/LZMA/LZMAEncoder.o build/urelease/makensis/7zip/7zip/Compress/RangeCoder/RangeCoderBit.o build/urelease/makensis/7zip/Common/Alloc.o build/urelease/makensis/7zip/Common/CRC.o -lpthread -lz
build/urelease/makensis/crc32.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
scons: *** [build/urelease/makensis/makensis] Error 1
scons: building terminated because of errors.
看我选中的部分,这里编译crc32.c
的时候使用的是gcc
而不是mingw32-gcc
,所以这里的crc32.o
文件是不能被正常识别的。
因为这是编译makensis
部分出现的问题,所以这里还是环境没有设置对。
这里再次修改nsis-3.03-src/SCons/Config/gnu
文件,在之前改CXX
变量的前面吧CC
也改了。这里在一开始就应该想到两个都应该重新设置的。
修改之后继续编译。
错误 build/urelease/makensis/BinInterop.o:BinInterop.cpp:(.text+0xf5): undefined reference to 'GetFileVersionInfoSizeW@8' 等
这是最后链接的一点小问题
build/urelease/makensis/BinInterop.o:BinInterop.cpp:(.text+0xf5): undefined reference to `GetFileVersionInfoSizeW@8'
build/urelease/makensis/BinInterop.o:BinInterop.cpp:(.text+0x136): undefined reference to `GetFileVersionInfoW@16'
build/urelease/makensis/BinInterop.o:BinInterop.cpp:(.text+0x183): undefined reference to `VerQueryValueW@16'
这三个函数找不到,其实是没有链接versions.lib
的原因,这里手动添加一下,执行链接即可。
这里也可以修改nsis-3.03-src/Source/SConscript
文件,在libs
中添加version
即可。
这时候编译出来的makensis
就是一个有效的PE
文件了。
linux下使用mingw编译NSIS-3.03的更多相关文章
- 在Linux下使用MinGW静态交叉编译带有zlib的libcurl(包括交叉编译openssl,即--cross-compile-prefix=i686-w64-mingw32- mingw)
在Linux下使用MinGW静态交叉编译带有zlib的libcurl libcurl是一个跨平台的.易用的.强大的网络库.在大部分Linux发行版中都有编译好的二进制包可供使用,Mac系统更是将其作为 ...
- 手把手教你在Windows下使用MinGW编译libav(参考libx264的编入)
转自:http://www.th7.cn/Program/cp/201407/242762.shtml 手把手教你在Windows下使用MinGW编译libav libav是在Linux下使用纯c语言 ...
- Linux下指定版本编译安装LAMP
说明: 操作系统:CentOS 6.5 64位 需求: 编译安装LAMP运行环境 各软件版本如下: MySQL:mysql-5.1.73 Apache:httpd-2.2.31 PHP:php-5.2 ...
- Linux下使用javac编译
Linux下使用javac编译Hadoop程序 首先要配置好Hadoop, 给出两个教程 Hadoop安装教程单机/伪分布式配置Hadoop2.6.0/Ubuntu14.04 Hadoop集群安装配置 ...
- Windows7下使用mingw编译openssl
Windows7下使用mingw编译openssl 首先参考这篇文章安装mingw/minsys: http://blog.csdn.net/ubuntu64fan/article/details/8 ...
- linux下面用Mingw编译libx264
linux下面用Mingw编译libx264 首先要先安装好mingw 我用的是Ubuntu 编译ffmpeg的时候 ,官方上面有一个自动化脚本能够把mingw安装好 这里就不说了 新版本的libx2 ...
- 在Windows环境下使用MinGW编译Qt 4.8.6
1.修改环境变量工具推荐:Rapid Environment Editor.官网:http://www.rapidee.com/ 修改前请先备份当前的环境变量.然后: (1)检查系统变量path,删除 ...
- Windows下使用MINGW编译ffplay
之前考虑到需要快速配置编译ffplay,使用了比较暴力的方法,具体可以参考编译ffplay.exe简化版. 这里介绍下相对规范的做法. 前提:已经安装了Windows下GCC开发环境--MINGW+m ...
- Linux下使用NDK编译FFMPEG(libstagefright)
这个月要负责一个项目,使用FFMPEG渲染视频,主要是Android端的,由于性能要求,要使用硬解码,但网上大多数教程都是没有libstagefright的,所以个人觉得,生成的so库文件也是没有开启 ...
随机推荐
- 基于bootstrap的基本模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- java加密工具类,可设置对应的加解密key
public class AesEncryptUtil { //使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同! private static String KEY =& ...
- Mistwald POJ
一开始看不出来是快速幂矩阵的题目 先要把整个地图离散化为1,2,3,4,.... 连成一个有向图 邻接矩阵的平方意为:假如a->b 且b->c 那么一次平方后 a->c ...
- Java 处理 iphone拍照后 图片EXIF属性翻转90度的方法
http://blog.csdn.net/z69183787/article/details/50320821 Java获取照片EXIF信息 http://blog.csdn.net/ghsau/ar ...
- java中的instanceof用法详解
instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字.它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据.用它来判断某个对象是否是某个Clas ...
- angular中使用代理
使用代理 1.在跟目录创建proxy.config.json文件 { "/api": { "target": "http://localhost:30 ...
- TypeReference -- 让Jackson Json在List/Map中识别自己的Object
private Map<String, Object> buildHeaders(Object params) { ObjectMapper objectMapper = JacksonH ...
- hql查询后释放内存
Session session=getSession(); //进行session查询,取得前16个数据 Query q=session.createQuery(hql).setFirstResult ...
- Java实验-课程设计报告一:个人银行账户管理系统SavingAccountManageSystem-具体文档+源码
课程设计报告一:个人银行账户管理系统 此文档及源码仅供参考 不得直接复制使用 author: [xxxxxxxxx xx xxxx] date: "2019-04-12" 作 者: ...
- 替换字符串空格、tab制表符
\ ASCII (NUL ) 字符 \' ASCII 39 单引号 (“'” ) 字符 \" ASCII 34 双引号 (“"” ) 字符 \b ASCII 退格符 \n ASCI ...