not found or not built by the last incremental link; performing full link类似问题的解析

4 篇文章 0 订阅

我们在用VC6.0的时候可能会遇到如下的问题:

LINK : LNK6004: Debug/aoe.exe not found or not built by the last incremental link; performing full link
一句话说:此问题是微软clean工程功能的bug。

我的程序是VC6.0下编的,
LINK : LNK6004: Debug/aoe.exe not found or not built by the last incremental link; performing full link

这种情况很可能是因为没有使用预编译,所以每次都全部链接了。假如每次都这样,修改项目属性中的“链接器”-“常规”-“启用增量链接”选项为“是(/INCREMENTAL)”。
但是若链接设置本身就是/INCREMENTAL,则可能是由于obj文件不是最新的,所以无法使用增量编译。最好清理解决方案,完全重新编译一次,以后应该不会出现这个提示

还有经常遇到的碰到的问题如下:
在源代码文件目录里的Debug文件夹里没有exe文件生成,是在外面一层文件夹里有一个debug文件夹里,里面有exe文件生成,以为出错没有生成exe文件了。。。
 (以下aoe为工程名)
【在源文件目录中有如下结构】
-aoe-aoe-debug 1
-debug 2

第一个debug文件夹编译后不会有exe文件生成 ,第二个debug文件夹编译后会有exe文件生成。

【解决方法如下】

假如出现上述错误,可以使用clean,然后第一个文件就剩了BuildLog.htm文件 ,

而第二个文件夹还存在aoe.ilk文件,删除这个文件,再编译即可怀疑这个问题是clean的一个bug,没有清除

aoe.ilk(关键文件啊)文件。

接下来了解一下Incremental Link Table。

那么什么是Incremental Link Table呢?

想想如果我们自己要做编译器(compiler)和连接器(linker),当然希望编译连接运行得越快越好,同时也希望产生的二进制代码也是又快又小,上帝是公平的,鱼与熊掌不可兼得,所以我们

自然想到用两种build方式,一种Release,编译慢一些,但是产生的二进制代码紧凑精悍,一种Debug,编译运行快,产生的代码臃肿一点没关系,Debug版本嘛,就是指望程序员在开发的时

候反复的build,为了不浪费程序员的时候,要想尽办法让编译连接速度变快。

假如一个程序有连续两个foo和bar (所谓连续,就是他们编译连接之后函数体连续存放), foo入口位置在0x0400,长度为0x200个字节,那么bar入口就应该在0x0600 = 0x0400+0x0200。程序

员在开发的时候总是频繁的修改code然后build,假如程序员在foo里面增加了一些内容,现在foo函数体占0x300个字节了,bar的入口也就只好往后移0x100变成了0x0700,这样就有一个问题

,如果foo在程序中被调用了n次,那么linker不得不修改这n个函数调用点,虽然linker不嫌累,但是link时间长了,程序员会觉得不爽。所以MSVC在Debug版的build,不会让各个函数体之间

这么紧凑,每个函数体后都有padding(全是汇编代码int 3,作用是引发中断,这样因为古怪原因运行到不该运行的padding部分,会发生异常),有了这些padding,就可以一定程度上缓解

上面提到的问题,不过当函数增加内容太多超过padding,还是有问题,怎么办呢?MSVC在Debug build中用上了Incremental Link Table, ILT其实就是一串jmp语句,每个jmp语句对应一个

函数,jmp的目的地就是函数的入口点,和没有ILT的区别是,现在对函数的调用不是直接call到函数入口点了,而是call到ILT中对应的位置,而这个位置上什么也不做,直接jmp到函数中去

。这样的好处是,当一个函数入口地址改变时,只要修改ILT中对应值就搞定了,用不着修改每一个调用位置,用一个冗余的ITL把时间复杂度从O(n)将为O(1),值得,当然Debug版的二进制文

件会稍大稍慢,Release版不会用上ILT。
 

下面是有关的英语文献,有兴趣的可以看看啊:

/INCREMENTAL (Link Incrementally)
                                      
/INCREMENTAL[:NO]

The /INCREMENTAL option controls how the linker handles incremental linking.

By default, the linker runs in incremental mode. To override a default incremental link, specify /INCREMENTAL:NO.

An incrementally linked program is functionally equivalent to a program that is nonincrementally linked. However, because it is prepared for subsequent incremental

links, an incrementally linked executable (.exe) file or dynamic-link library (DLL):

Is larger than a nonincrementally linked program because of padding of code and data. (Padding allows the linker to increase the size of functions and data without

recreating the .exe file.)
May contain jump thunks to handle relocation of functions to new addresses.
Note   To ensure that your final release build does not contain padding or thunks, link your program nonincrementally.
To link incrementally regardless of the default, specify /INCREMENTAL. When this option is selected, the linker issues a warning if it cannot link incrementally, and

then links the program nonincrementally. Certain options and situations override /INCREMENTAL.

Most programs can be linked incrementally. However, some changes are too great, and some options are incompatible with incremental linking. LINK performs a full link

if any of the following options are specified:

Link Incrementally is not selected (/INCREMENTAL:NO)
/OPT:REF is selected
/OPT:ICF is selected
/ORDER is selected
The use of /INCREMENTAL is not compatible with /MAPINFO:LINES.

/INCREMENTAL is implied when /DEBUG is specified.

Additionally, LINK performs a full link if any of the following situations occur:

The incremental status (.ilk) file is missing. (LINK creates a new .ilk file in preparation for subsequent incremental linking.)
There is no write permission for the .ilk file. (LINK ignores the .ilk file and links nonincrementally.)
The .exe or .dll output file is missing.
The timestamp of the .ilk, .exe, or .dll is changed.
A LINK option is changed. Most LINK options, when changed between builds, cause a full link.
An object (.obj) file is added or omitted.
An object that was compiled with the /Yu /Z7 option is changed.
To set this linker option in the Visual Studio development environment

Open the project's Property Pages dialog box. For details, see Setting Visual C++ Project Properties.
Click the Linker folder.
Click the General property page.
Modify the Enable Incremental Linking property.
To set this linker option programmatically

这个问题不难了吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值