MS链接从gnu-make失败,但从cmd行工作

MS link fails from gnu make, but works from cmd line

本文关键字:但从 cmd 工作 失败 链接 gnu-make MS      更新时间:2023-10-16

最近我的gnu makefile停止链接我的C++项目。我做了一些改变。我已经复制了链接行,并从批处理文件中运行它。它建造得很好。但奇怪的是,当我运行make时,同一行却失败了。它给出的错误是:

LINK : fatal error LNK1181: cannot open input file 'user32.lib'

这不得不转移注意力,因为在同一命令行提示符下,运行link命令会成功。我开始怀疑GNU制造。这曾经在make中工作,但我对makefile进行了一些添加和更改,使其在Linux上构建,这似乎引入了问题。

我正在使用:

GNU Make 3.80
MS Visual C++ Linker 10.00.40219.01

在Windows XP上。

我的LIBLIBPATH都包含包含库的SDK目录的路径。我的链接命令如下:

link  C:SDL-1.2.14libSDL.lib C:SDL-1.2.14libSDLmain.lib C:SDL-1.2.14libSDL_image.lib C:SDL-1.2.14libSDL_ttf.lib C:SDL-1.2.14libSDL_mixer.lib C:SDL-1.2.14libSDL_net.lib  ../../build/lib/sdlhal.lib  user32.lib gdi32.lib kernel32.lib oldnames.lib wsock32.lib advapi32.lib comdlg32.lib comctl32.lib wsock32.lib winmm.lib netapi32.lib  OpenGL32.lib glu32.lib /nologo /incremental:no  -subsystem:console /PDB:../../build/bin/Prog.pdb /OUT:../../build/bin/Prog.exe /MAP:../../build/bin/Prog.map ../../build/Prog/intr/util.obj  ../../build/Prog/intr/objwithvel.obj  ../../build/Prog/intr/rock.obj  ../../build/Prog/intr/explosion.obj  ../../build/Prog/intr/ship.obj  ../../build/Prog/intr/photon.obj  ../../build/Prog/intr/world.obj ../../build/Prog/intr/test.obj  ../../build/Prog/intr/main.obj 

编辑:下面的C++程序的一些进展。我的环境变量是:

LIB=C:Program FilesMicrosoft Visual Studio 10.0VCLIB;C:Program FilesMicrosoft Visual Studio 10.0VCATLMFCLIB;C:Program FilesMicrosoft SDKsWindowsv7.0Alib;
LIBPATH=C:WINDOWSMicrosoft.NETFrameworkv4.0.30319;C:WINDOWSMicrosoft.NETFrameworkv3.5;C:Program FilesMicrosoft Visual Studio 10.0VCLIB;C:Program FilesMicrosoft Visual Studio 10.0VCATLMFCLIB;

但当由make内部运行的程序打印出来时,它们是:

LIB=.lib
LIBPATH=C:WINDOWSMicrosoft.NETFrameworkv4.0.30319;C:WINDOWSMicrosoft.NETFrameworkv3.5;C:Program FilesMicrosoft Visual Studio 10.0VCLIB;C:Program FilesMicrosoft Visual Studio 10.0VCATLMFCLIB;

根据您对LIB值的描述,我怀疑您只是简单地将makefile中的"LIB"变量设置为".LIB"。在标准GNU make(实际上是make的所有版本)中,当make启动时,所有环境变量都作为make变量导入到make中(也有例外,如SHELL,处理方式不同)。

每当make调用命令时,导入的变量的所有当前值都会写入到子进程的环境中。

换句话说,当make运行配方中的任何命令时,从其环境中读取的任何变量都被视为标记为导出。

所以,如果你有一个像这样的makefile:

LIB = .lib
all: ; @echo "LIB = %LIB%"

你这样运行它:

> set LIB=C:foo;C:bar
> make

则输出将是"LIB=.LIB",而不是"LIB=C:\foo;C:\bar"

我怀疑当从make调用link时,您的LIBLIBPATH变量并没有按照您认为的方式设置。

尝试创建自己的link.exe程序,该程序从make调用并转储命令行和环境。这将确切地告诉您makefile是否正确设置了变量。

#include <stdlib.h>
#include <stdio.h>

int main( int argc, char** argv, char** env)
{
    int i = 0;
    for (i = 0; i < argc; ++i, ++argv) {
        if (!(*argv)) {
            *argv = "(null)";
        }
        printf( "arg[%d]: "%s"n", i, *argv);
    }
    puts("nENVIRONMENT...n");
    while (*env) {
        printf( "%sn", *env);
        ++env;
    }
   return 0;
}

还要检查链接命令行中的错误位置是否没有未引用的空格。虽然它似乎与问题中提到的错误无关(可能实际上只是剪切/粘贴错误),但您给出的链接命令行在explosion.obj的路径/文件名中间有一个空格。

这可能是路径问题。你使用的是GNU make的mingw版本,还是Cygwin版本?

调试的一种方法是将echo $LIBecho $LIBPATH命令放入make配方中,以确认它们是否按预期设置。