Where is '$OutDir' defined in the script file in Visual Studio?

10,977

Solution 1

In Visual Studio 2010, the main project settings will define an output folder, the macro that is set from this folder assignment is $(OutDir). There are other predefined macros that you cannot modify, but this one you can.

If I understand what you're trying to do, then follow these steps:

  1. Open your project's properties dialog.
  2. At the top of the dialog are two drop-lists, one for "Configuration" and one for "Platform". Select the "All" option for the Configuration list.
  3. On the General settings page at the top is a folder designated the "Output Directory". Change it to the following (quotes optional) "$(SolutionDir)$(Configuration)\" . The trailing backslash is important. This is the setting that $(OutDir) eventually picks by the way.
  4. Open the "Linker" item in the left-tree. then select "General" settings.
  5. In the right-pane at the top of the list is the "Output File" option. It should default to "$(OutDir)$(TargetName)$(TargetExt)". If it isn't, then set it as such.
  6. Rebuild the world.

Note: If you have multiple platform targets (win32 and x64 for example) this is a little more involved, but not that bad. Hope this helps.


EDIT OP also would like the PDB and incremental link files not to be published in the same folder, but does want the import library published there. So.....

To change the location where the PDB file is created:

  1. Open the project file, Once again select the "All" option to change all build configuration targets (see #2 above).
  2. Select the Linker/Debugging settings in the left-tree.
  3. Second item from the top should be the "Generate Program Database File" setting. Change it to "$(IntDir)$(TargetName).pdb"

The incremental link file must be (to my knowledge) in the same folder as the final target. You can disable incremental linking if you want, however. This is done at the following location:

  1. Open the project file, Once again select the "All" option to change all build configuration targets (see #1 above).
  2. Select the Linker/General settings of the project.
  3. Fourth item down should be "Enable Incremental Linking". Set it to No.
  4. If you do disable incremental linking, you cannot use the Edit & Continue PDB debug format feature of Visual Studio, but the UI is too dumb to fix this for you when you disable incremental linking, so.. Select C++/General in the project pane. then, if it is set to "Program Database for Edit/Continue" switch it to Program Database /Zi.

To move where the import library is built.

  1. Open the project file, Once again select the "All" option to change all build configuration targets (see #2 above).
  2. Select Linker/Advanced
  3. In the right pane will be an item about halfway down, Import Library. Change it to "$(OutDir)$(TargetName).lib"

Don't ask me how to get rid of the export-list file (.exp) because I honestly don't know.

Solution 2

The majority of those macros are defined in the MSBuild targets file that is included in every VS2010 project. Somewhere in your project file, probably near the bottom, you will find a line like this:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

If you follow the chain of path variables back you will eventually find the folder that contains Microsoft.Cpp.targets, which itself will contain:

    <Import Project="Microsoft.Common.targets" />

In this file you'll find the following note:

Several properties must be set in the main project file, before using this .TARGETS file. However, if the properties are not set, we pick some defaults.

OutDir: Indicates the final output location for the project or solution. When building a solution,

The defaults that MSBuild picks is to default $(OutDir) to $(OutputPath) if it's not explicitly set. $(OutputPath) is defined in your project file, so changing that property before the targets file gets included will change the default value of $(OutDir). You can also just specify a value for $(OutDir) on the msbuild command line using /p:OutDir=bin\DebugElsewhere or whatever and that will override whatever defaults MSBuild wants to use. (This is what TFSBuild does, for example, to get everything in a solution dumped into the same folder.)

Also, for possible future reference, most of the remaining macros are also defined in this file, somewhat further down:

<PropertyGroup>
  <TargetDir Condition="'$(OutDir)' != ''">$([MSBuild]::Escape($([System.IO.Path]::GetFullPath(`$([System.IO.Path]::Combine(`$(MSBuildProjectDirectory)`, `$(OutDir)`))`))))</TargetDir>
  <TargetPath Condition=" '$(TargetPath)' == '' ">$(TargetDir)$(TargetFileName)</TargetPath>
  <ProjectDir Condition=" '$(ProjectDir)' == '' ">$(MSBuildProjectDirectory)\</ProjectDir>
  <ProjectPath Condition=" '$(ProjectPath)' == '' ">$(ProjectDir)$(ProjectFileName)</ProjectPath>
      .
      .
      .
</PropertyGroup>
Share:
10,977
zar
Author by

zar

Updated on July 19, 2022

Comments

  • zar
    zar almost 2 years

    There are bunch of macros that Visual Studio uses in project settings which are listed here. I am unable to locate where are these macros or identifiers defined in the actual script file (not in project settings).

    In my case I am trying to change the output folder for a project to that of the solution debug or release folder (one level up) but changing 'Output Directory' in project settings has no effect.

    There is no mention of these macros in .vcxproj file either so I really don't know where they defined? I am most interested in the $(OutDir) that I want to change to solution debug/release folder. Does anyone knows where these are defined?

  • zar
    zar about 11 years
    I followed your steps (have to say #2 is not very clear but I understand it's change in configuration). My project is a dll project and it does pushes .dll file to the solution debug folder but it also create .ilk and .pdb file there which it should create in the regular debug folder. Also I would like to push .lib file to this folder as well but it still get created in the original debug folder.
  • WhozCraig
    WhozCraig about 11 years
    @zadane I can update the answer for that as well. I prefer to push the PDB file into a sub-folder of the build output folder called "pdb" (original, I know =P) Pushing the import library is not too difficult. Give me a minute.
  • zar
    zar about 11 years
    The .pdb is still created in the solution debug and there are the .exp, ilk files also there like you pointed out but I created a dummy dll project and they also create these files there so I guess that's how much we can go for now, Thanks!
  • zar
    zar about 11 years
    A side question I thought maybe you know. Since the libaraires are now in solution\debug folder, my other project can't find it. I thought this fold is automatically updated to the project paths. Do I need to change that in Linker > Input > Additional Dependencies explicitly or there is a way to include solution\debug folder in the path to search the library? That would seem better to me!
  • WhozCraig
    WhozCraig about 11 years
    @zadane Sorry I was away for awhile there. The other projects should just pick up the import library new locations provide you (a) have Link Library Dependencies" enabled in the Project/Link/General settings configuration page of each consuming project, and have your projects properly configured in Project Dependencies (.i.e. this DLL is dependent on that DLL, this EXE is dependent on both those DLLs, etc.). If you set that up correctly, you don't even need to list the import libs on the Additional Libraries line of the consumer projects. msbuild will wire them up for you free of charge.
  • zar
    zar about 11 years
    Unfortunately I did that and it's still gives a linker error. I made sure project is dependent on it and set the Link Library Dependencies to Yes. It comes with an error message LINK : fatal error LNK1104: cannot open file 'USBDLL.lib' If I copy the lib/dll at old location (project root) than it builds fine. This would be pretty awesome if it had worked by linking the projects.
  • WhozCraig
    WhozCraig about 11 years
    If that is the case then you still have your DLL's import library in your Additional Libraries link-config settings of whatever project is complaining about this (most likely your exe by your description). As I said, if you setup the projects dependencies correctly and establish the link-setting for "Link Library Dependencies" to true, you do NOT need the import library on your lib list. msbuild will put it there for you at build time. Double check and make sure it is NOT in your lib list on your Link settings, and make sure dependencies are linked and your Proj Deps are setup correctly.
  • zar
    zar about 11 years
    What you are saying makes sense but it's just not working. I did had the dll library listed in additional libraries of my exe project so I removed it per your suggestion but now I get linker error for functions that are in the library. I had to add solution's debug directory path but I know that's a bad idea 'cz I for release version it will be in release folder instead.
  • WhozCraig
    WhozCraig about 11 years
    I can't explain it if you have the proper project dependencies put together. If Project MyEXE is dependent on Project MyDLL (and you can verify this in the Project Dependencies... configuration dialog from the Project menu and you have definitely set MyEXE's Link config to Link Library Dependencies as enabled, the linker should be fed any generated import library created from MyDLL, including its specific location. based on the current build config (debug or release). I just tried it and it worked on a local test project here. So something still doesn't smell right.
  • WhozCraig
    WhozCraig about 11 years
    You can also turn on verbose output of the linker listing in Link options and see in the output window everything the linker is fed (which will be a hella-lot of info, so you may want to tone it done to just what you're looking for).
  • zar
    zar about 11 years
    I just create whole new solution with two new test projects in it. Calculator.exe uses a function from MathLib.Lib (dll project) to sqr a number. I made the exe dependent on the exe and Link Libraries Dependencies is already selected to Yes in exe's project settings. I of course included the dll's header file in exe and I was hoping I don't have to add anything else and it should pick it up. I do get similar error like in the other project. CalculatorDlg.obj : error LNK2019: unresolved external symbol "int __cdecl MakeDouble(int)
  • zar
    zar about 11 years
    Maybe if I can fix this in my simple test project, that should give me the clue!
  • WhozCraig
    WhozCraig about 11 years
    @zadane OK, this will sound a little odd, but open your EXE project settings. Above the Configuration properties is a node called "Common Properties" In that there should be only one thing, "Frameworks and References". Add your DLL project as a reference for your EXE project. Then apply, save, etc. Then rebuild. Note: this is supposed to be for .NET, no idea why it is needed for C/C++ projects. I assume your DLL project is properly exporting its goods, you sound like you know your way around devstudio by now, so give that a shot.
  • zar
    zar about 11 years
  • zar
    zar about 11 years
    That last trick - adding reference in Frameworks and References fixed the issue. Thank you!
  • WhozCraig
    WhozCraig about 11 years
    @zadane Very glad to hear it.