MSBuild.exe не принимает ни /p:DefineConstants, ни /p:PreprocessorDefinitions

Я прочитал довольно много статей о переполнении стека, которые отвечали на вопрос «Как мне передать определения препроцессора компилятору из командной строки MSBuild», и все они ответили с некоторыми вариантами:

MSBuild.exe /p:DefineConstants=THING_TO_BE_DEFINED

Я перепробовал все возможные варианты:

MSBuild.exe "/p:DefineConstants=THING_TO_BE_DEFINED"
MSBuild.exe /p:DefineConstants="THING_TO_BE_DEFINED"
MSBuild.exe "/p:DefineConstants=THING_TO_BE_DEFINED=1"
MSBuild.exe /p:DefineConstants="THING_TO_BE_DEFINED=1"

...и десятки других. Я также заигрывал с переопределением PreprocessorDefinitions аналогичным образом. Все они вызвали #error ниже:

#include "stdafx.h"

#if !defined(THING_TO_BE_DEFINED)
#error "THING_TO_BE_DEFINED is not defined"
#endif

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

Я пробовал это с помощью простого приложения командной строки выше, а также с огромным игровым проектом, который у меня есть здесь. Я могу только догадываться, что Visual Studio (я вижу это с 2005 и 2008 годами) имеет некоторый набор значений по умолчанию глубоко в своих недрах, который препятствует применению моего аргумента командной строки, но я не нашел никаких доказательств, подтверждающих эту гипотезу.

Любые идеи о том, как я могу заставить это работать? Почему, во имя FSM, они не остановились на старом добром -D THING_TO_BE_DEFINED?


person Sniggerfardimungus    schedule 06.01.2010    source источник


Ответы (4)


Если вы вызываете MSBuild из командной строки, вы не можете указать значение для DefineConstants. Но если вы создаете .csproj или другой скрипт MSBuild, вы можете указать его. Если вы создаете файл msbuild для «замены» вашего файла решения, вы можете использовать его, указав значение для этого при создании своих проектов. Например:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!-- Default value here -->
    <DefineConstants Condition=" '$(DefineConstants)'==''" >DEBUG;TRACE</DefineConstants>
  </PropertyGroup>

  <ItemGroup>
    <Projects Include="one.csproj" />
    <Projects Include="two.csproj" />
  </ItemGroup>

  <Target Name="Build">
    <MSBuild Projects="@(Projects)"
                 Properties="DefineConstants=$(DefineConstants)"/>
  </Target>
</Project>

Затем вы можете использовать msbuild.exe buid.proj /p:DefineConstants="YourValue;Debug;Trace"

Обратите внимание на использование кавычек в командной строке.

Недавно я написал сообщение в блоге о чем-то, связанном с этим, по адресу http://sedodream.com/2008/05/07/MSBuildBuildingTheSameProjectMultipleTimes.aspx.

person Sayed Ibrahim Hashimi    schedule 07.01.2010
comment
Я застрял с .vcproj, который мне вручает разработчик. Дох. - person Sniggerfardimungus; 05.02.2010

Если вы хотите определить константы TRACE & DEBUG, это должно работать:

msbuild mysln.sln /t:Rebuild /p:Configuration=Release /p:DefineConstants="DEBUG;TRACE"
person Robert Muehsig    schedule 29.12.2012
comment
Принятый ответ на самом деле неверен. Я обнаружил, что для моих собственных проектов DefineConstants игнорируется, если только я не использую параметр /t:Rebuild. - person A.R.; 26.03.2014
comment
Это работает, но перезаписывает существующую переменную $(DefineConstants) для КАЖДОГО ПРОЕКТА в решении! -- Я просто хочу добавить к этому! - person BrainSlugs83; 16.09.2014
comment
@ BrainSlugs83, так что бы вы отметили как принятый ответ? мне искренне любопытно - person knocte; 19.09.2020

Ниже приведены необходимые изменения в vcxproj для работы /p.

поместите ‹DefineConstants>‹ /DefineConstants>

в разделе ‹PropertyGroup Label=Globals >

Определения препроцессора>$(Определить константы);WIN32;_DEBUG;_CONSOLE;UNIT_TEST_SIM;%(Определения препроцессора)

Таким образом, MSBuild будет знать, что для препроцессора необходимо использовать значения из DefineConstants, которые поступают из Globals PropertyGroup, если только они не предоставлены из командной строки параметром /p:DefineConstants="MY_DEFINE"

person Moshe    schedule 26.04.2015

Для полноты, это то, что я обнаружил, работало, когда я хотел THING_TO_BE_DEFINED="VALUE WANTED" для VB.NET и msbuild версии 3.5.30729.1 в пакетном файле:

@msbuild /t:Rebuild /p:Configuration=Release;Platform="Any CPU";
DefineConstants="THING_TO_BE_DEFINED=\"VALUE WANTED\"" mysln.sln

(конечно, все в одной строке)

person Mark Hurd    schedule 07.02.2013
comment
+1 Большое спасибо! Вы единственный, кто упоминает, как избежать двойных кавычек для определения строк. - person Arnaud; 28.02.2015