我正在尝试编译开源项目Programmer Dvorak。问题是它有点旧,并且不能使用当前版本的构建工具进行构建。
您可以在我的项目的 Google 代码页上查看经过我在线修改的完整源代码。 修订版 2是原始项目中未修改的源文件。 修订版 3是我做出所有重大改变的地方。您可以此处查看两个版本之间的差异< /a>.
剩下的唯一明显的问题是一些链接警告:
- LNK4254 (例如
“.edata”部分(40000040)合并到具有不同属性的“.data”(C0000040)中。
)--我问了一个独立版本的问题此处。
- LNK4210(例如
.CRT 部分存在;可能存在未处理的静态初始化程序或终止符
)
如何修复这些警告? 我可以忽略它们吗?
尽管有这些警告,它仍然会生成一个 exe。但是,如果我继续运行它,它不会正确安装,我需要诉诸系统还原才能再次安装官方版本。
这可能是因为警告或仅仅因为我没有正确修改项目。
我还需要做什么才能使该项目可安装?
构建过程(以及我的修改的解释):
它说您需要 Windows DDK,但看起来像是 Windows 驱动程序工具包 已替换它,所以我得到了它。我只安装了“构建环境”。
build-layout && build-installer
我必须修改此文件(在此处查看差异):
-
WinDDK
路径为由于我有更新的版本(MOD-1),因此进行了修改。
-
set PATH=
... %WINDDK%\bin\x86\x86;
已添加,因为 link.exe
位于此处 ( MOD-2)。
- 在
set INCLUDE=
中,将%WINDDK%\inc\wxp
更改为%WINDDK%\inc\api
,因为wxp
文件夹不存在,我最好的猜测是需要 api
文件夹,因为它包含 kbd.h
,其中 kbddvp.c
使用 (MOD-3)。
- 对于
set LIB=
,将%WINDDK%\lib\crt
修改为%WINDDK%\lib\crt\i386
,这样libcmt.lib
可以找到。请参阅下面的 MOD-7。 (MOD-4)
我必须修改此文件(在此处查看差异):
- 变量
CL32
的路径已从 $(WINDDK )\bin\x86\cl.exe
到 $(WINDDK)\bin\x86\x86\cl.exe
,第一个.exe不存在,我相信这是我应该使用 .exe 来代替。 (MOD-5)
- 变量
CL64
的路径已从 $(WINDDK)\bin\win64\x86\amd64\cl.exe
更改> 到 $(WINDDK)\bin\x86\amd64\cl.exe,这是我对丢失的 .exe 在哪里的最佳猜测。 (MOD-6)
-
-opt:nowin98
已删除以抑制警告 LNK4224(即不再支持/OPT:NOWIN98
),如鲍比建议。 (MOD-10)
- 我没有使用不存在的
libc.lib
,而是使用 libcmt.lib
。我读了这篇文章 建议使用此文件。 (MOD-7)
- 我没有使用过时的实用程序
cabarc
,而是使用 makecab
和 makecab-dir.ddf
。我采取了我最好的猜测如何使用这个新实用程序执行相同的逻辑。 (MOD-8)
我必须修改此文件(查看此处的差异):
- 这也是使用
cabarc,我将其修改为使用 makcab
,类似于 MOD-8,只不过这里它以编程方式创建 .ddf 文件。 (MOD-9)
完整的输出
如果您想查看的话,这是完整的输出:
>build-layout && build-installer
"C:\WinDDK\7600.16385.1\bin\x86\x86\cl.exe" -nologo -c -I..\inc -Zp8 -Gy
-W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Zl -Oxs -D_WIN32_WINNT=0x0501 -Fokbddvp32.o
bj kbddvp.c
kbddvp.c
rc kbddvp.rc
Microsoft (R) Windows (R) Resource Compiler Version 6.1.6908.0
Copyright (C) Microsoft Corporation. All rights reserved.
link -machine:ix86 -nologo -dll -base:0x5FFF0000 -subsystem:native -def:
kbddvp.def -noentry -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data
-merge:.bss=.data -ignore:4078,4070 -section:.data,re -stack:0x40000,0x1000 -op
t:ref,icf -release -out:kbddvp32.dll kbddvp32.obj kbddvp.res
Creating library kbddvp32.lib and object kbddvp32.exp
LINK : warning LNK4254: section '.edata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.rdata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.text' (60000020) merged into '.data' (C0000040
) with different attributes
LINK : warning LNK4254: section '.bss' (C0000080) merged into '.data' (C0000040)
with different attributes
"C:\WinDDK\7600.16385.1\bin\x86\amd64\cl.exe" -nologo -c -I..\inc -Zp8 -
Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Zl -Oxs -DBUILD_WOW6432 -D_WIN32_WINNT=0x
0501 -Fokbddvp64.obj kbddvp.c
kbddvp.c
link -machine:amd64 -nologo -dll -base:0x5FFE0000 -subsystem:native -def
:kbddvp.def -noentry -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data
-merge:.bss=.data -ignore:4078,4070 -section:.data,re -stack:0x40000,0x1000 -o
pt:ref,icf -release -out:kbddvp64.dll kbddvp64.obj kbddvp.res
Creating library kbddvp64.lib and object kbddvp64.exp
LINK : warning LNK4254: section '.edata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.rdata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.text' (60000020) merged into '.data' (C0000040
) with different attributes
LINK : warning LNK4254: section '.bss' (C0000080) merged into '.data' (C0000040)
with different attributes
"C:\WinDDK\7600.16385.1\bin\x86\x86\cl.exe" -nologo -c -Folauncher.obj l
auncher.c
launcher.c
link -machine:ix86 -nologo -subsystem:windows -release -nodefaultlib -ou
t:launcher.exe launcher.obj kernel32.lib libcmt.lib user32.lib shell32.lib
libcmt.lib(cpu_disp.obj) : warning LNK4210: .CRT section exists; there may be un
handled static initializers or terminators
makecab /F makecab-dir.ddf
Microsoft (R) Cabinet Maker - Version 5.1.2600.5512
Copyright (c) Microsoft Corporation. All rights reserved..
27,686 bytes in 4 files
Total files: 4
Bytes before: 27,686
Bytes after: 8,140
After/Before: 29.40% compression
Time: 0.19 seconds ( 0 hr 0 min 0.19 sec)
Throughput: 144.58 Kb/second
iexpress /N /Q /M kbddvp.sed
1 file(s) copied.
Microsoft (R) Cabinet Maker - Version 5.1.2600.5512
Copyright (c) Microsoft Corporation. All rights reserved..
60,290 bytes in 16 files
Total files: 16
Bytes before: 60,290
Bytes after: 16,876
After/Before: 27.99% compression
Time: 0.27 seconds ( 0 hr 0 min 0.27 sec)
Throughput: 221.34 Kb/second
I'm trying to compile the open source project Programmer Dvorak. The problem is that it's a bit old and doesn't build with the current versions of the build tools.
You can see the full source code with modifications I made online at my project's Google Code page. Revision 2 is the unmodified source files from the original project. Revision 3 is where I made all the significant changes. You can see a diff between the two revisions here.
The only obvious problems that are left are a few LINK warnings:
- LNK4254 (e.g.
section '.edata' (40000040) merged into '.data' (C0000040) with different attributes.
) -- I asked a stand-alone version of the question here.
- LNK4210 (e.g.
.CRT section exists; there may be unhandled static initializers or terminators
)
How do I fix these warnings? Can I ignore them?
Despite these warnings, it still produces an exe. If I go ahead and run it, though, it doesn't get installed correctly and I need to resort to a system restore in order to install the official version again.
This might be because of the warnings or simply because I didn't modify the project correctly.
What else do I need to do to make this project installable?
The build process (and an explanation of my modifications):
It says that you need the Windows DDK, but it seems like the Windows Driver Kit has replaced it, so I got that instead. I only installed the "Build Environments".
1. According to Readme.txt
, you are supposed to run:
build-layout && build-installer
I had to modify this file (see the diff here):
WinDDK
path was modified since I have a newer version (MOD-1).
set PATH=
... %WINDDK%\bin\x86\x86;
was added since link.exe
is located there (MOD-2).
- In
set INCLUDE=
, %WINDDK%\inc\wxp
was changed to %WINDDK%\inc\api
, because the wxp
folder does not exist, and my best guess is that the api
folder was needed since it contains kbd.h
, which kbddvp.c
uses (MOD-3).
- For
set LIB=
, %WINDDK%\lib\crt
was modified to %WINDDK%\lib\crt\i386
, so that libcmt.lib
could be found. See MOD-7 below. (MOD-4)
I had to modify this file (see the diff here):
- The path for the variable
CL32
was changed from $(WINDDK)\bin\x86\cl.exe
to $(WINDDK)\bin\x86\x86\cl.exe
, the first .exe doesn't exist, I believe this is the .exe I'm supposed to use instead. (MOD-5)
- The path for the variable
CL64
was changed from $(WINDDK)\bin\win64\x86\amd64\cl.exe
to $(WINDDK)\bin\x86\amd64\cl.exe
, this is my best guess as to where the missing .exe is. (MOD-6)
-opt:nowin98
removed to suppress warning LNK4224 (i.e. /OPT:NOWIN98 is no longer supported
), as suggested by Bobby. (MOD-10)
- Instead of using the non-existent
libc.lib
, I'm using libcmt.lib
. I read this post which recommends using this file instead. (MOD-7)
- Instead of using the obsolete utility
cabarc
, I'm using makecab
with makecab-dir.ddf
. I took my best guess as to how to execute the same logic with this new utility. (MOD-8)
I had to modify this file (see the diff here):
- This was also using
cabarc
and I modified it to use makcab
, similar to MOD-8, except that here it creates the .ddf file programmaticaly. (MOD-9)
The complete output
Here's the complete output, if you want to see it:
>build-layout && build-installer
"C:\WinDDK\7600.16385.1\bin\x86\x86\cl.exe" -nologo -c -I..\inc -Zp8 -Gy
-W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Zl -Oxs -D_WIN32_WINNT=0x0501 -Fokbddvp32.o
bj kbddvp.c
kbddvp.c
rc kbddvp.rc
Microsoft (R) Windows (R) Resource Compiler Version 6.1.6908.0
Copyright (C) Microsoft Corporation. All rights reserved.
link -machine:ix86 -nologo -dll -base:0x5FFF0000 -subsystem:native -def:
kbddvp.def -noentry -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data
-merge:.bss=.data -ignore:4078,4070 -section:.data,re -stack:0x40000,0x1000 -op
t:ref,icf -release -out:kbddvp32.dll kbddvp32.obj kbddvp.res
Creating library kbddvp32.lib and object kbddvp32.exp
LINK : warning LNK4254: section '.edata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.rdata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.text' (60000020) merged into '.data' (C0000040
) with different attributes
LINK : warning LNK4254: section '.bss' (C0000080) merged into '.data' (C0000040)
with different attributes
"C:\WinDDK\7600.16385.1\bin\x86\amd64\cl.exe" -nologo -c -I..\inc -Zp8 -
Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Zl -Oxs -DBUILD_WOW6432 -D_WIN32_WINNT=0x
0501 -Fokbddvp64.obj kbddvp.c
kbddvp.c
link -machine:amd64 -nologo -dll -base:0x5FFE0000 -subsystem:native -def
:kbddvp.def -noentry -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data
-merge:.bss=.data -ignore:4078,4070 -section:.data,re -stack:0x40000,0x1000 -o
pt:ref,icf -release -out:kbddvp64.dll kbddvp64.obj kbddvp.res
Creating library kbddvp64.lib and object kbddvp64.exp
LINK : warning LNK4254: section '.edata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.rdata' (40000040) merged into '.data' (C000004
0) with different attributes
LINK : warning LNK4254: section '.text' (60000020) merged into '.data' (C0000040
) with different attributes
LINK : warning LNK4254: section '.bss' (C0000080) merged into '.data' (C0000040)
with different attributes
"C:\WinDDK\7600.16385.1\bin\x86\x86\cl.exe" -nologo -c -Folauncher.obj l
auncher.c
launcher.c
link -machine:ix86 -nologo -subsystem:windows -release -nodefaultlib -ou
t:launcher.exe launcher.obj kernel32.lib libcmt.lib user32.lib shell32.lib
libcmt.lib(cpu_disp.obj) : warning LNK4210: .CRT section exists; there may be un
handled static initializers or terminators
makecab /F makecab-dir.ddf
Microsoft (R) Cabinet Maker - Version 5.1.2600.5512
Copyright (c) Microsoft Corporation. All rights reserved..
27,686 bytes in 4 files
Total files: 4
Bytes before: 27,686
Bytes after: 8,140
After/Before: 29.40% compression
Time: 0.19 seconds ( 0 hr 0 min 0.19 sec)
Throughput: 144.58 Kb/second
iexpress /N /Q /M kbddvp.sed
1 file(s) copied.
Microsoft (R) Cabinet Maker - Version 5.1.2600.5512
Copyright (c) Microsoft Corporation. All rights reserved..
60,290 bytes in 16 files
Total files: 16
Bytes before: 60,290
Bytes after: 16,876
After/Before: 27.99% compression
Time: 0.27 seconds ( 0 hr 0 min 0.27 sec)
Throughput: 221.34 Kb/second
发布评论
评论(7)
链接的源代码缺少sources.inc 文件,这使得使用最新版本的WDK 构建此文件变得困难。附带的.bat 文件毫无用处,它们只能在作者的机器上运行。我使用 WDK 版本 6001.18002 使用以下步骤获得了干净的构建:
不需要很长时间,干净的构建。没有实际测试,配备两只左手。
您需要的sources.inc文件:
The linked source code is missing the sources.inc file which makes it difficult to get this built with a recent version of the WDK. The included .bat files are quite useless, they can only work on the author's machine. I got a clean build using the following steps with WDK version 6001.18002:
Doesn't take long, clean build. No actual test, being equipped with two left hands.
The sources.inc file you need:
launcher
是一个启动 .inf 文件的提升安装的程序,禁用重定向,以便显示真正的
%SystemRoot%
目录即使它在 Wow64 中运行,也可以转换为 32 位进程。
它使用的 C 运行时的唯一例程是
ZeroMemory
,它是扩展为
_memset
的宏。在早期版本中,没有问题静态链接这一例程时,忽略运行时初始化。
也许是在以后的版本中,触发了LNK4210警告。
您可以使用此函数替换对
ZeroMemory
的调用:并删除对
libc
/libcmt
和目录%WINDDK%\ 的引用lib\crt\i386
.另请注意,如果您作为管理员从上下文菜单中选择“安装”
在资源管理器中查找
kbddvp.inf
文件,您应该能够进行设置没有
launcher
程序,从而消除了该阶段的任何错误。它存在只是为了更容易重新分配,并不重要。
launcher
is a program to start an elevated installation of the .inf file,disabling redirection so that the true
%SystemRoot%
directory is revealedto a 32-bit process even if it is running in Wow64.
The only routine from the C runtime which it uses is
ZeroMemory
, which isa macro expanding to
_memset
. In earlier versions, there was no problemsin linking this one routine statically, ignoring the runtime initialization.
Perhaps it is in later versions, which triggers the LNK4210 warning.
You can replace the calls to
ZeroMemory
with this function:and remove the reference to
libc
/libcmt
and the directory%WINDDK%\lib\crt\i386
.Note also that if you as an Administrator choose Install from the context-menu
in Explorer for the
kbddvp.inf
file, you should be able to do the setupwithout the
launcher
program, thus eliminating any errors from that stage. Itis only present for easier redistribution and is not vital.
从版本 1.2.6 开始,还可以在 Windows 7 64 位计算机上使用 Visual Studio 2013 Community Edition Update 4 构建布局。
As of version 1.2.6 the layout can also be built using the Visual Studio 2013 Community Edition Update 4, on a Windows 7 64-bits machine.
AMD64?我认为这就是问题所在。
也许问题只是您同时使用 32 或 64 ISA 的文件的问题。
像:
kbddvp32.dll
kbddvp64.dll
尝试使用适合您的平台 ISA 的那些,然后取出其余的。
AMD64? I think that is the issue there.
Perhaps the problem is just a matter of you using BOTH the files for 32 or 64 ISA at the same time.
Like:
kbddvp32.dll
kbddvp64.dll
Try using the ones for your platform ISA and take out the rest.
MSDN 链接:
http://msdn.microsoft.com/en-us /library/ms235500(VS.80).aspx -- LNK4254
http://msdn.microsoft.com/en-us /library/708by912(VS.71).aspx -- LNK4210
注意:LNK4210 可能是由 -NOENTRY 引起的,但只有您的代码可以判断使用它是对是错
LNK4254 最有可能是一个“政治”警告(在某些库的新版本中声明为“只读”的部分)
并且我假设您正在运行 2 个完全干净且独立的 x86 和 x64 版本。如果没有,无论如何你都必须这样做,并且首先要做。所谓的混合构建会导致所有孩子出现看似随机的失败,并且需要注意修复那里 - 只需单独构建即可。
MSDN links:
http://msdn.microsoft.com/en-us/library/ms235500(VS.80).aspx -- LNK4254
http://msdn.microsoft.com/en-us/library/708by912(VS.71).aspx -- LNK4210
Note: LNK4210 can be caused by -NOENTRY but only your code can tell is using it is right or wrong
LNK4254 is most probalby a "poltical" warning (a section declared as "read only" in a new version of some lib)
And I assume that you are running 2 completely clean and separated builds for x86 and x64. If not, you have to do that no matter what and do it first. So called mixed builds result in all kids of random-looking failures and there's noting to fix there - just have to build separately.
我之前已经合并过各个部分(为了我们正在做的事情,必须这样做)。它可能会变得棘手,我认为我们遇到的问题之一也困扰着您:您将
.text
部分(包含可执行代码)合并到.data
部分(没有)。.data
部分没有获得可执行位,并且 /SECTION 链接器选项(应该能够强制其可执行)显然不适用于.data.
我们解决这个问题的方法是创建一个新部分,然后将所有其他部分合并到其中。操作方法如下:
在一个 *.cpp 文件中,在 #include 行之后添加以下行:(
第二行必须位于某些实际代码之上,以创建新部分。)
然后更改
-merge:
命令转到新的.merged
部分而不是.data
部分......并添加一个新部分来放置
.data
部分也有:这应该可以解决问题。您仍然会收到一些有关具有不同属性的部分的警告,但您现在应该能够忽略它们(我们通过在链接器上使用
/ignore:4254
来抑制它们)。最后的 .merged 部分将具有可执行、读取和写入权限,这将消除该问题。(我们的代码是用 MSVC2005 编译的,但这也应该适用于更高版本。)
I've merged sections before (had to, for what we were doing). It can get tricky, and I think one of the problems we had has bitten you too: you're merging the
.text
section (which contains executable code) into the.data
section (which doesn't). The.data
section doesn't get the executable bit, and the /SECTION linker option (which should be able to force it to be executable) apparently doesn't work on.data
.The way we worked around it is to create a new section, then merge all of the others into it. Here's how:
In one of your *.cpp files, add the following lines after your #include lines:
(The second line has to be above some actual code, to create the new section.)
Then change the
-merge:
commands to go to a new.merged
section instead of the.data
section......and add a new one to put the
.data
section there too:That should do the trick. You'll still get some warnings about the sections having different attributes, but you should be able to ignore them now (we suppress them by using
/ignore:4254
on the linker). The final.merged
section will have executable, read, and write permissions, which will eliminate the problem.(Our code is compiled with MSVC2005, but this should work in later ones too.)
您会注意到所有这些命令行参数的来源是 http://levicki.net/articles/tips/2006/09/29/HOWTO_Build_keyboard_layouts_for_Windows_x64.php。使用它的原因是KLC 1.3不支持64位操作系统。 KLC 1.4,增加了对64位操作系统的支持。这意味着,如果您可以使用 KLC 创建支持您想要的所有功能的布局,那么您应该使用它。
但是,如果您需要更高级的功能并希望自己编译这些文件,则需要找出用于 KLC 1.4 的新实用程序和参数。您列出的那些已过时,适用于 KLC 1.3。
我使用 Process Monitor 来确定运行了哪些实用程序,以及向它们发送了哪些命令行参数。它们在这里,按运行顺序排列:
You'll notice that the source of where all these command line parameters came from is http://levicki.net/articles/tips/2006/09/29/HOWTO_Build_keyboard_layouts_for_Windows_x64.php. The reason it was used was that KLC 1.3 did not support 64 bit operating systems. KLC 1.4, added support for 64 bit operating systems. That means that if you can get away with creating a layout using KLC that supports all of the features you want, you should use that instead.
If, however, you need more advanced features and would like to compile these files yourself, you need to find out the new utilities and parameters that are used for KLC 1.4. The ones you have listed are outdated and meant for KLC 1.3.
I used Process Monitor to figure out which utilities are run, and what command line parameters are sent to them. Here they are, in the order they are run: