libzimg在MSVC的移植,nmake的使用记录

文章讲述了在不使用CMake的情况下,如何通过nmake和Makefile手动编译libzimg库,特别是在VisualStudio2015环境下,解决版本兼容性问题,以及如何处理编译错误和设置环境变量。作者还分享了关于nmake的使用技巧和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作需要libzimg库,下载源代码下面有一个"_msvc"的子目录,都已经做好适配了。但问题是,这个适配是适配当前的Visual studio C++的版本的,而一些低一级的版本就老报错。要解决这个问题,其实也简单,这个需要CMake(CMake原理)。而libzimg提供的是经典一套的autoconf工具链。所以我没有功夫去研究CMake了,还是直接用的nmake解决问题。

命令行都是相通的。

工作场景:libzimg最新版本

VC2015 Express,Windows 7 SDK

首先构筑环境设置

一般在VS安装以后,会存在一个环境变量:VSnnnCOMMTOOLS(nnn版本号,VS2015就是240),用 set vs命令可以查看具体版本号: 

C:\Qt\zimg-2.8>set vs
VS140COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\
VSSDK140Install=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VSSDK\

C:\Qt\zimg-2.8>dir "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat"
 驱动器 C 中的卷是 Windows 7 SSD
 卷的序列号是 44D7-DBAA

 C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC 的目录

2016/06/09  22:25             3,337 vcvarsall.bat
               1 个文件          3,337 字节
               0 个目录  3,597,721,600 可用字节

C:\Qt\zimg-2.8>

里面有一个 vcvarsall.bat 文件。编译哪个平台,就设置里面的参数。默认x86是32位的,如果要64就是 call vcvarsall.bat x64,具体去看面的源代码。如果没有,会出现LIBCMT.lib没有找到的问题

Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1104: 无法打开文件“LIBCMT.lib”
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio 14.
0\Common7\Tools\\..\..\vc\bin\link.EXE"”: 返回代码“0x450”

另外需要添加 PATH : PATH=%PATH%;%VS140COMNTOOLS%\..\..\vc\bin

VS2017环境设置看这里:https://blog.youkuaiyun.com/harborian/article/details/126297812

nmake的一些点滴:

https://learn.microsoft.com/zh-cn/cpp/build/reference/special-nmake-macros

nmake和make有一些不兼容的地方:

  1. make的子目录递归 make -C subdir 可以搜索subdir下的Makefile,而nmake的-C参数不是这个意义,需要自己的文件里 CD subsir,nmake -F makefile 进行处理。
  2. make文件内搜索子目录路径。make用 VPATH,nmake使用{src1:src2:}。
  3. 搜索子目录可以带入规则

libzimg的目录结构非常合理,但嵌套麻烦,查了下没有相同的文件名,那么就写一个Makefile就凑合了。

cat /mnt/Qt/zimg-2.8/_msvc/zimg/zimg.vcxproj |\
 grep Include | cut -d'"' -f2 | \
awk -F"\\" '{print $NF}' | sort | uniq -c | more

nmake点滴:

  1. NMAKE [选项] [/f makefile] [/x stderrfile] [macrodefs] [targets]
    其中 macrodefs是宏定义;targets是里面的目标(块规则名),默认第一个伪目标
  2. nmake /P 查看nmake内部的预定义变量和配置,了解默认参数。
  3. nmake /A 查看nmake的实际解析的makefile文件的操作步骤。调试很有用。
  4. $*$**的解释要看 https://learn.microsoft.com/zh-cn/cpp/build/reference/special-nmake-macros
  5. 点规则的定义,https://learn.microsoft.com/zh-cn/cpp/build/reference/inference-rules,如果文件名是cpp的话,那么点规则要看补充默认点规则。可能原来的是 .cc.obj,而新的是.cpp.obj
  6. make文件需要 -L[连接路径名] -l(小写l,库名还不要lib的名称开头或结尾的一些特别明明规则),而nmake需要用 /libpath:,库名直接和obj一样写在参数内。如果是dl的,dll的lib可以用 /DYNAMICBASE "dll.lib"来处理也行,都可以。具体看手册。

移植过程没有太大困难,就是vs2015不支持C++18的新特性constexpr,所以相关的static_map开头需要屏蔽掉,constexpr取消了。其他没有什么问题,就是调整目录的事情。zimg 2.4是最后支持MSVC 2015的版本。可以借鉴_MSVC目录的文件,照抄命令行参数。zimg 3.0就需要新版本的C++特性,所以还是用zimg 2.9

#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
  //#define SM_CONSTEXPR_14 constexpr
  #define SM_CONSTEXPR_14
#else
  #define SM_CONSTEXPR_14
#endif

由于我只要dll和一个exe就可以了。所以,Makefle只做了两个。保持原来的目录结构。

 C:\Qt\zimg-2.9 的目录

2023/03/22  13:10    <DIR>          .
2023/03/22  13:10    <DIR>          ..
2023/03/22  13:10               141 .coverity-prepare.sh
2023/03/22  13:10               585 .gitignore
2023/03/22  13:10               114 .gitmodules
2023/03/22  13:10               561 .travis-script.sh
2023/03/22  13:10             1,772 .travis.yml
2023/03/22  13:10                50 autogen.sh
2023/03/22  13:10             5,566 ChangeLog
2023/03/22  13:10             4,120 configure.ac
2023/03/22  13:10               484 COPYING
2023/03/22  13:10    <DIR>          doc
2023/03/22  13:10                 0 dummy.cpp
2023/03/22  13:10    <DIR>          m4
2023/03/22  13:10            11,600 Makefile.am
2023/03/22  13:10             3,432 README.md
2023/03/22  13:10    <DIR>          src
2023/03/22  13:10    <DIR>          test
2023/03/22  13:10               372 zimg.pc.in
2023/03/22  13:10    <DIR>          _msvc
              13 个文件         28,797 字节

 C:\Qt\zimg-2.9\_msvc 的目录

2023/03/22  13:10    <DIR>          .
2023/03/22  13:10    <DIR>          ..
2023/03/23  12:33    <DIR>          dll
2023/03/22  13:10    <DIR>          testapp
2023/03/22  13:10    <DIR>          testcommon
2023/03/22  13:10    <DIR>          unit_test
2023/03/22  13:10    <DIR>          zimg
2023/03/22  13:10               381 zimg.def
2023/03/22  13:10            16,542 zimg.sln
2023/03/22  13:10    <DIR>          _example_alpha
2023/03/22  13:10    <DIR>          _example_api
2023/03/22  13:10    <DIR>          _example_api_c
2023/03/23  12:33    <DIR>          _example_hdr
2023/03/22  13:10    <DIR>          _example_interlace
2023/03/22  13:10    <DIR>          _example_tile

_dll里面的Makefile.vs

#
# Makefile for Microsoft Visual Studio
#
CFLAGS=/I..\..\src\zimg
CC=cl /nologo
LINK=link /nologo /subsystem:console
DEFINES=/DWIN32 /D_WIN32_WINNT=0x0400 /DNDEBUG /DLIBDE265_EXPORTS /D_CRT_SECURE_NO_WARNINGS /DHAVE_SSE4_1 /DHAVE_STDINT_H

#CFLAGS=$(CFLAGS) /MT /Ox /Ob2 /Oi /TP /W4 /GL /EHsc
CFLAGS=$(CFLAGS) /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Zc:inline /fp:precise /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /EHsc /nologo

# type conversion, possible loss of data
CFLAGS=$(CFLAGS) /wd4244
# unreferenced formal parameter
CFLAGS=$(CFLAGS) /wd4100
# local variable is initialized but not referenced
CFLAGS=$(CFLAGS) /wd4189
# unreferenced local function has been removed
CFLAGS=$(CFLAGS) /wd4505
# padded structures
CFLAGS=$(CFLAGS) /wd4324
# conversion signed/unsigned
CFLAGS=$(CFLAGS) /wd4245
# comparison signed/unsigned
CFLAGS=$(CFLAGS) /wd4018 /wd4389
# possible loss of data with return
CFLAGS=$(CFLAGS) /wd4267
# forcing value to bool (performance warning)
CFLAGS=$(CFLAGS) /wd4800

CFLAGS=$(CFLAGS) $(DEFINES)

OBJS=..\..\src\zimg\api\zimg.obj \
	..\..\src\zimg\colorspace\colorspace.obj \
	..\..\src\zimg\colorspace\colorspace_param.obj \
	..\..\src\zimg\colorspace\gamma.obj \
	..\..\src\zimg\colorspace\graph.obj \
	..\..\src\zimg\colorspace\matrix3.obj \
	..\..\src\zimg\colorspace\operation.obj \
	..\..\src\zimg\colorspace\operation_impl.obj \
	..\..\src\zimg\colorspace\x86\gamma_constants_avx512.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_avx.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_avx2.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_avx512.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_sse.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_sse2.obj \
	..\..\src\zimg\colorspace\x86\operation_impl_x86.obj \
	..\..\src\zimg\common\cpuinfo.obj \
	..\..\src\zimg\common\libm_wrapper.obj \
	..\..\src\zimg\common\matrix.obj \
	..\..\src\zimg\common\x86\cpuinfo_x86.obj \
	..\..\src\zimg\common\x86\x86util.obj \
	..\..\src\zimg\depth\blue.obj \
	..\..\src\zimg\depth\depth.obj \
	..\..\src\zimg\depth\depth_convert.obj \
	..\..\src\zimg\depth\dither.obj \
	..\..\src\zimg\depth\quantize.obj \
	..\..\src\zimg\depth\x86\depth_convert_avx2.obj \
	..\..\src\zimg\depth\x86\depth_convert_avx512.obj \
	..\..\src\zimg\depth\x86\depth_convert_sse2.obj \
	..\..\src\zimg\depth\x86\depth_convert_x86.obj \
	..\..\src\zimg\depth\x86\dither_avx2.obj \
	..\..\src\zimg\depth\x86\dither_avx512.obj \
	..\..\src\zimg\depth\x86\dither_sse2.obj \
	..\..\src\zimg\depth\x86\dither_x86.obj \
	..\..\src\zimg\depth\x86\error_diffusion_avx2.obj \
	..\..\src\zimg\depth\x86\error_diffusion_sse2.obj \
	..\..\src\zimg\depth\x86\f16c_ivb.obj \
	..\..\src\zimg\depth\x86\f16c_sse2.obj \
	..\..\src\zimg\graph\copy_filter.obj \
	..\..\src\zimg\graph\filtergraph.obj \
	..\..\src\zimg\graph\graphbuilder.obj \
	..\..\src\zimg\resize\filter.obj \
	..\..\src\zimg\resize\resize.obj \
	..\..\src\zimg\resize\resize_impl.obj \
	..\..\src\zimg\resize\x86\resize_impl_avx.obj \
	..\..\src\zimg\resize\x86\resize_impl_avx2.obj \
	..\..\src\zimg\resize\x86\resize_impl_avx512.obj \
	..\..\src\zimg\resize\x86\resize_impl_sse.obj \
	..\..\src\zimg\resize\x86\resize_impl_sse2.obj \
	..\..\src\zimg\resize\x86\resize_impl_x86.obj \
	..\..\src\zimg\unresize\bilinear.obj \
	..\..\src\zimg\unresize\unresize.obj \
	..\..\src\zimg\unresize\unresize_impl.obj	

all: z.dll

.c.obj:
	$(CC) /c $*.c /Fo$*.obj $(CFLAGS)

.cc.obj:
	$(CC) /c $*.cc /Fo$*.obj $(CFLAGS)

.cpp.obj:
	$(CC) /c $*.cpp /Fo$*.obj $(CFLAGS)

.cxx.obj:
	$(CC) /c $*.cxx /Fo$*.obj $(CFLAGS)


z.dll: $(OBJS)
	$(LINK) /def:..\zimg.def /dll /out:z.dll $**

clean:
	del z.dll z.lib z.exp
	del $(OBJS)


_example_hdr里面的Makefile

#
# Makefile for Microsoft Visual Studio
#
CFLAGS=/I..\..\src\zimg\api /I..\..\src/testcommon
CC=cl /nologo
LINK=link /nologo /subsystem:console
DEFINES=/DWIN32 /D_WIN32_WINNT=0x0400 /DNDEBUG /DLIBDE265_EXPORTS /D_CRT_SECURE_NO_WARNINGS /DHAVE_SSE4_1 /DHAVE_STDINT_H


LDFLAGS=/nologo /subsystem:console
LDFLAGS=$(LFLAGS) /IMPLIB:z.lib /DYNAMICBASE "z.lib"  /libpath:..\dll


CFLAGS=$(CFLAGS) /MT /Ox /Ob2 /Oi /TP /W4 /GL /EHsc /Gd

# type conversion, possible loss of data
CFLAGS=$(CFLAGS) /wd4244
# unreferenced formal parameter
CFLAGS=$(CFLAGS) /wd4100
# local variable is initialized but not referenced
CFLAGS=$(CFLAGS) /wd4189
# unreferenced local function has been removed
CFLAGS=$(CFLAGS) /wd4505
# padded structures
CFLAGS=$(CFLAGS) /wd4324
# conversion signed/unsigned
CFLAGS=$(CFLAGS) /wd4245
# comparison signed/unsigned
CFLAGS=$(CFLAGS) /wd4018 /wd4389
# possible loss of data with return
CFLAGS=$(CFLAGS) /wd4267
# forcing value to bool (performance warning)
CFLAGS=$(CFLAGS) /wd4800

CFLAGS=$(CFLAGS) $(DEFINES)

OBJS=..\..\src\testcommon\argparse.obj \
	..\..\src\testcommon\mmap.obj \
	..\..\src\testcommon\win32_bitmap.obj \
	..\..\doc\example\hdr_example.obj

OBJSV30=..\..\src\testcommon\argparse.obj \
	..\..\src\testcommon\mmap.obj \
	..\..\src\testcommon\win32_bitmap.obj \
	..\..\doc\example\hdr_example_v30.obj

all: hdr_example.exe

.c.obj:
	$(CC) /c $*.c /Fo$*.obj $(CFLAGS)

.cc.obj:
	$(CC) /c $*.cc /Fo$*.obj $(CFLAGS)

.cpp.obj:
	$(CC) /c $*.cpp /Fo$*.obj $(CFLAGS)

.cxx.obj:
	$(CC) /c $*.cxx /Fo$*.obj $(CFLAGS)


hdr_example.exe: $(OBJS)
	$(LINK) /out:hdr_example.exe $(LFLAGS) $**

hdr_example_v30.exe: $(OBJSV30)
	$(LINK) /out:hdr_example_v30.exe $(LFLAGS) $**

clean:
	del hdr_example.exe hdr_example_v30.exe
	del $(OBJS)


其实其他的也一样,ffmpeg的移植也能这么抄作业。就是一些关联关系,我移植了好几个库文件,用MSVC编译通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值