Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture Visual Studio response file?

I'm having trouble porting a C++ library to Windows Phone via the command line with nmake. The makefile invokes cl.exe and link.exe using Visual Studio's x86_arm tools and has basic recipes.

I'm using a Visual Studio Phone project as a reference. Under Process Monitor, I noticed Visual Studio uses a response file rather than driving the compiler directly. That is, Visual Studio invoke cl.exe <response file>.

According to the Compiler Options, Response Files (the @ option):

A response file can contain any commands that you would specify on the command line. This can be useful if your command-line arguments exceed 127 characters.

This might be my problem with the port since my command line is over 500 characters (7+ lines with wrap in the console).

Visual Studio uses a temporary response file written to AppData file that is immediately deleted. I want to inspect Visual Studio's response file and try to use one.

Question: How can I capture or inspect a Visual Studio response file?

like image 684
jww Avatar asked May 04 '14 00:05

jww


People also ask

How do I create a Vsconfig file?

You can also generate a . vsconfig file right from Solution Explorer. Right-click on your solution file. Choose Add > Installation Configuration File.

How do I open a Vssettings file?

They are saved in an XML format. To import or export VSSETTINGS files in Visual Studio 2010, select Tools → Import and Export Settings... and follow the instructions in the wizard that is displayed.

How can we include the response file while executing a command in MSBuild?

This file, MSBuild. rsp, must be in the same directory as MSBuild.exe, otherwise it will not be found. You can edit this file to specify default command-line switches to MSBuild.exe. For example, if you use the same logger every time you build a project, you can add the -logger switch to MSBuild.


2 Answers

You can suppress the deletion of .rsp files by setting the environment variable MSBUILDPRESERVETOOLTEMPFILES to 1.

like image 161
avakar Avatar answered Sep 30 '22 05:09

avakar


My VS projects don't seem to use response files (maybe the projects are too small?), however getting nmake to generate and use a response file is pretty easy using nmake's 'inline files'. The following is a simple makefile that will compile hello.c using a response file to the cl command line:

PROJNAME=hello

all:
    cl @<<
-c $(PROJNAME).c
-Ox
<<

Basically, put a << on the command that you want to pass the inline to, then after the command simply put the contents of the file and end the inline file with another << token as a delimiter.

running nmake on that makefile results in:

C:\temp>nmake

Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl @C:\Users\mikeb\AppData\Local\Temp\nmAC77.tmp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cl -c hello.c
   -Ox

hello.c

You can see that nmake macros are expanded in the inline file.

See the MSDN docs for more details (though the docs are pretty sparse - they could use an example or two).


Update:

And if you really want or need to capture the response file the VS is using and can't find another way to do it, compile the following program and replace the program that VS is running, for example cl.exe, with it (obviously stashing the original program file somewhere so you can reverse the operation):

#include <stdio.h>

void dump(char const* fname)
{
    FILE* fp = NULL;
    char buf[1000];
    char* result = NULL;

    printf("Dumping response file \"%s\":\n\n", fname);

    fp = fopen(fname, "r");

    if (!fp) return;

    do {
        result = fgets(buf, sizeof(buf), fp);
        if (result) printf("%s", buf);
    } while (result);

    return;
}


int main(int argc, char** argv) 
{
    int i;
    for (i = 1; i < argc; ++i) {
        char* fname;
        if (argv[i][0] != '@') {
            // not a response file
            continue;
        }

        fname = &(argv[i][1]);

        dump(fname);
    }

    return 0;
}
like image 23
Michael Burr Avatar answered Sep 30 '22 05:09

Michael Burr