ScrollerBlaster
ScrollerBlaster

Reputation: 1598

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

Recently my gnu makefile stopped linking my C++ project. I had made some changes. I have copied the link line out and run it from a batch file. It builds fine. But the same line strangely fails when I run make. The error it gives is:

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

which has to be a red herring because from the same command line prompt, running the link command succeeds. I am beginning to suspect GNU make. This used to work from within make but I made a few additions and changes to the makefile to get it building on Linux which seemed to introduce the problem.

I am using :

GNU Make 3.80
MS Visual C++ Linker 10.00.40219.01

on Windows XP.

My LIB and LIBPATH both include the path to the SDK directory which contains the libraries. My link command is as follows:

link  C:\SDL-1.2.14\lib\SDL.lib C:\SDL-1.2.14\lib\SDLmain.lib C:\SDL-1.2.14\lib\SDL_image.lib C:\SDL-1.2.14\lib\SDL_ttf.lib C:\SDL-1.2.14\lib\SDL_mixer.lib C:\SDL-1.2.14\lib\SDL_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 

EDIT: Bit of progress with C++ program below. My Environment variables were:

LIB=C:\Program Files\Microsoft Visual Studio 10.0\VC\LIB;C:\Program Files\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;C:\Program Files\Microsoft SDKs\Windows\v7.0A\lib;
LIBPATH=C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319;C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\Program Files\Microsoft Visual Studio 10.0\VC\LIB;C:\Program Files\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;

But when printed out by program run from within make, they are:

LIB=.lib
LIBPATH=C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319;C:\WINDOWS\Microsoft.NETFramework\v3.5;C:\Program Files\Microsoft Visual Studio 10.0\VC\LIB;C:\Program Files\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;

Upvotes: 1

Views: 784

Answers (3)

MadScientist
MadScientist

Reputation: 101081

Based on your description of the value of LIB, I suspect that you have simply set the "LIB" variable in your makefile (to ".lib"). In standard GNU make (actually, all versions of make) all the environment variables are imported into make as make variables when make starts up (there are exceptions, such as SHELL, which are handled differently).

Whenever make invokes a command, all the current values of variables that were imported are written out to the environment of the child process.

Put another way, any variable that make read from its environment is considered to be marked for export when make runs any command from a recipe.

So if you have a makefile like this:

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

and you run it like this:

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

then the output will be "LIB = .lib", not "LIB = C:\foo;C:\bar"

Upvotes: 3

Michael Burr
Michael Burr

Reputation: 340436

I suspect that your LIB and LIBPATH variables aren't set the way you think they are when link is invoked from make.

Try creating your own link.exe program that gets invoked from make and dumps the command line and environment. That'll tell you for certain whether or not the variables are set correctly by the 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( "%s\n", *env);
        ++env;
    }

   return 0;
}

Also check that there aren't unquoted spaces in the wrong place in the link command line. While it would seem to be unrelated to the error you mention in the question (and is probably really just a cut/paste error), the link command line you gave has a space in the middle of the path/file name for explosion.obj.

Upvotes: 1

Brooks Moses
Brooks Moses

Reputation: 9537

This is likely to be a path issue. Are you using the mingw version of GNU make, or the Cygwin version?

One way to debug this is to put an echo $LIB and echo $LIBPATH command into the make recipe to confirm that these are getting set as you expect.

Upvotes: 0

Related Questions