openssl windows自动编译+静态库符号缺失问题(/Fd选项)

摘要:

    本文描述使用bat脚本自动编译openssl1.0.2j的过程,并解释了使用openssl静态库时可能出现的链接告警(warning LNK4099: PDB 'lib.pdb' was not found),原因是其符号文件lib.pdb缺失,本文提供的编译脚本将符号文件一并拷贝到输出目录。其背景是在windows平台下编译webrtc的debug版本时,在不使用boringssl而是使用openssl的情况下,出现这个告警会导致编译失败,而你又不打算去掉把告警当错误处理这个选项时,必须带这个符号文件。

平台:

    Windows10

工具:

    ActivePerl、Visual Studio 2015命令行工具

版本:

    openssl1.0.2j,实际上1.0版本应该都没有问题,替换1.0.2j为指定版本号即可。

编译:

    把所有文件都放到一个目录下。

   openssl windows自动编译+静态库符号缺失问题(/Fd选项)_第1张图片

    以下所有脚本以及操作都在Visual Studio 2015命令行工具中进行。
    先上编译脚本
    build_openssl_windows.bat

@echo off

::设置路径
call :get_pwd pwd
set build_path=%pwd%\openssl-1.0.2j
set build_tmp_output=output
set header_ouput_path=%pwd%\..\include
set lib_output_path=%pwd%\..\lib
set libeay32_lib=libeay32.lib
set ssleay32_lib=ssleay32.lib

::解压缩编译目录
if exist %build_path% rmdir /s /q %build_path%
echo Uncompressing...
call zip.bat unzip -source %pwd%\openssl-1.0.2j.zip -destination %build_path%tmp -keep yes -force no
move %build_path%tmp\openssl-1.0.2j %build_path%
rd %build_path%tmp

::==================编译过程===================::
::创建临时输出目录
echo Building...
cd %build_path%
md %build_tmp_output%

::运行configure:
perl Configure VC-WIN32 --prefix=./%build_tmp_output%

::创建Makefile文件
call ms\do_nasm

::修改pdb文件名,lib.pdb改成openssl.pdb
perl -i.bak -pe "s/\/lib/\/openssl/g" ms/nt.mak

::编译静态库
call nmake -f ms\nt.mak

::测试静态库
call nmake -f ms\nt.mak test

::拷贝pdb文件
echo Copying pdb... 
copy tmp32\openssl.pdb %lib_output_path%\

::安装静态库
call nmake -f ms\nt.mak install

::清除上次静态库的编译,以便重新编译
call nmake -f ms\nt.mak clean
::============================================::

::拷贝输出文件
echo Copying headers... 
if not exist %header_ouput_path% (
  move %build_tmp_output%\include %header_ouput_path%
)

echo Copying libraries... 
if not exist %lib_output_path% (
  md %lib_output_path%
)
copy %build_tmp_output%\lib\%libeay32_lib% %lib_output_path%\%libeay32_lib%
copy %build_tmp_output%\lib\%ssleay32_lib% %lib_output_path%\%ssleay32_lib%

::清除编译目录
cd ..
rmdir /s /q %build_path%

echo Done

exit /b

::获取当前路径
:get_pwd
for /f "delims=" %%i in ('cd') do set %~1=%%i
goto :eof

    注释很清楚,大致过程:

  1. 解压openssl-1.0.2j.zip,需要zip.bat,后面会附;
  2. 进入编译目录,执行perl Configure VC-WIN32 --prefix=./%build_tmp_output%,VC-WIN32指配置为win32 release版,并指定安装目录;
  3. 执行call ms\do_nasm,生成Makefile,对静态库是ms\nt.mk,动态库是ms\ntdll.mak,这里选择编译静态库;
  4. 红字部分执行perl -i.bak -pe "s/\/lib/\/openssl/g" ms/nt.mak,把nt.mk中
    LIB_CFLAG=/Zl /Zi /Fd$(TMP_D)/lib
    修改成了
    LIB_CFLAG=/Zl /Zi /Fd$(TMP_D)/openssl
    LIB_CFLAG是生成静态库时的选项,/Zi强制生成pdb文件,/Fd指定pdb文件名,TMP_D在nt.mk中被指定为tmp32,在tmp32目录中会生成obj、pdb等文件,这里只是把符号文件lib.pdb修改成了openssl.pdb,因为lib.pdb很有迷惑性,也有可能重名,后面还会执行:
    copy tmp32\openssl.pdb %lib_output_path%\
    把openssl.pdb拷贝到输出目录,这样其他程序链接openssl的时候就不会再报下面的告警,有些开源库把告警当错误处理,最好把告警都处理掉以免后患。|
    1>libeay32.lib(cryptlib.obj) : warning LNK4099: PDB 'lib.pdb' was not found with 'libeay32.lib(cryptlib.obj)' or at 'C:\Projects\openssl-test\x64\Release\lib.pdb'; linking object as if no debug info
    1>libeay32.lib(mem.obj) : warning LNK4099: PDB 'lib.pdb' was not found with 'libeay32.lib(mem.obj)' or at 'C:\Projects\openssl-test\x64\Release\lib.pdb'; linking object as if no debug info
    1>libeay32.lib(mem_dbg.obj) : warning LNK4099: PDB 'lib.pdb' was not found with 'libeay32.lib(mem_dbg.obj)' or at 'C:\Projects\openssl-test\x64\Release\lib.pdb'; linking object as if no debug info
  5. 执行call nmake -f ms\nt.mak,编译静态库;
  6. 执行call nmake -f ms\nt.mak test,测试静态库;
  7. 执行copy tmp32\openssl.pdb %lib_output_path%\,拷贝pdb文件;
  8. 执行call nmake -f ms\nt.mak install,安装静态库;
  9. 执行call nmake -f ms\nt.mak clean,清除静态库的编译目录;
  10. 后续拷贝需要的头文件、库文件到自定义的其他目录,然后删除代码目录,退出。

附zip.bat

@if (@X)==(@Y) @end /* JScript comment
	@echo off
	
	rem :: the first argument is the script name as it will be used for proper help message
	cscript //E:JScript //nologo "%~f0" "%~nx0" %*

	exit /b %errorlevel%
	
@if (@X)==(@Y) @end JScript comment */


/*
Compression/uncompression command-line tool that uses Shell.Application and WSH/Jscript -
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774085(v=vs.85).aspx

Some resources That I've used:
http://www.robvanderwoude.com/vbstech_files_zip.php
https://code.google.com/p/jsxt/source/browse/trunk/js/win32/ZipFile.js?r=161




UPDATE *17-03-15*

Devnullius Plussed noticed a bug in ZipDirItems  and ZipItem functions (now fixed)
And also following issues (at the moment not handled by the script):
- if there's not enough space on the system drive (usually C:\) the script could produce various errors , most often the script halts.
- Folders and files that contain unicode symbols cannot be handled by Shell.Application object.

UPDATE *24-03-15*

Error messages are caught in waitforcount method and if shuch pops-up the script is stopped.
As I don't know hoe to check the content of the pop-up the exact reason for the failure is not given
but only the possible reasons.

------
It's possible to be ported for C#,Powershell and JScript.net so I'm planning to do it at some time.

For sure there's a lot of room for improvements and optimization and I'm absolutely sure there are some bugs
as the script is big enough to not have.



!!!
For suggestions contact me at - [email protected]
!!!

*/


//////////////////////////////////////
//   CONSTANTS

// TODO - Shell.Application and Scripting.FileSystemObject objects could be set as global variables to avoid theit creation
// in every method.

//empty zip character sequense
var ZIP_DATA= "PK" + String.fromCharCode(5) + String.fromCharCode(6) + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

var SLEEP_INTERVAL=200;

//copy option(s) used by Shell.Application.CopyHere/MoveHere
var NO_PROGRESS_BAR=4;


//oprions used for zip/unzip
var force=true;
var move=false;

//option used for listing content of archive
var flat=false;

var source="";
var destination="";

var ARGS = WScript.Arguments;
var scriptName=ARGS.Item(0);

//
//////////////////////////////////////

//////////////////////////////////////
//   ADODB.Stream extensions

if ( ! this.ADODB ) {
	var ADODB = {};
}

if ( ! ADODB.Stream ) {
	ADODB.Stream = {};
}

// writes a binary data to a file
if ( ! ADODB.Stream.writeFile ) {
	ADODB.Stream.writeFile = function(filename, bindata)
	{
        var stream = new ActiveXObject("ADODB.Stream");
        stream.Type = 2;
        stream.Mode = 3;
        stream.Charset ="ASCII";
        stream.Open();
        stream.Position = 0;
        stream.WriteText(bindata);
        stream.SaveToFile(filename, 2);
        stream.Close();
		return true;
	};
}

//
//////////////////////////////////////

//////////////////////////////////////
//   common

if ( ! this.Common ) {
	var Common = {};
}

if ( ! Common.WaitForCount ) {
	Common.WaitForCount = function(folderObject,targetCount,countFunction){
		var shell = new ActiveXObject("Wscript.Shell");
		while (countFunction(folderObject) < targetCount ){
			WScript.Sleep(SLEEP_INTERVAL);
			//checks if a pop-up with error message appears while zipping
			//at the moment I have no idea how to read the pop-up content
			// to give the exact reason for failing
			if (shell.AppActivate("Compressed (zipped) Folders Error")) {
				WScript.Echo("Error While zipping");
				WScript.Echo("");
				WScript.Echo("Possible reasons:");
				WScript.Echo(" -source contains filename(s) with unicode characters");
				WScript.Echo(" -produces zip exceeds 8gb size (or 2,5 gb for XP and 2003)");
				WScript.Echo(" -not enough space on system drive (usually C:\\)");
				WScript.Quit(432);
			}
			
		}
	}
}

if ( ! Common.getParent ) {
	Common.getParent = function(path){
		var splitted=path.split("\\");
		var result="";
		for (var s=0;s

你可能感兴趣的:(webrtc)