Pytanie msbuild: ustaw konkretny preprocesor #define w wierszu poleceń


W pliku C ++ mam następujący kod:

#if ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif

Chcę ustawić to ACTIVE define na 1 za pomocą wiersza poleceń msbuild.

Próbowałem, ale to nie działa:

msbuild /p:DefineConstants="ACTIVATE=1"

Dowolny pomysł?


15
2017-10-03 11:47


pochodzenie




Odpowiedzi:


Jestem trochę spóźniony na imprezę (tylko 4 lata), ale musiałem po prostu obejść ten problem w projekcie i natknąłem się na to pytanie, szukając rozwiązania. Nasze rozwiązanie wykorzystało zmienną środowiskową połączoną z opcją Dodatkowe opcje w visual studio.

  1. W Visual Studio dodaj makro zmiennej środowiskowej $ (ExternalCompilerOptions) do Opcji dodatkowych w opcjach projektu-> C / C ++ -> Wiersz poleceń (pamiętaj zarówno o konfiguracji debugowania, jak i wydania)
  2. Ustaw zmienną środowiskową przed wywołaniem msbuild

    c:> ustaw ExternalCompilerOptions = / DFOO / DBAR
    c:> msbuild

Punkt # 1 kończy się wyglądać tak w pliku vcxproj:

<ClCompile>
  <AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
</ClCompile>

Działa to dla mnie z VS 2010. Napędzamy msbuild z różnych skryptów kompilacji, więc brzydota jest trochę ukryta. Zauważ, że nie przetestowałem, czy to działa, gdy musisz ustawić definicję na konkretną wartość (/ DACTIVATE = 1). Myślę, że to zadziała, ale martwię się, że mam tam wiele "=".

H ^ 2


24
2018-01-07 23:51



Dzięki za spóźnioną odpowiedź :) - acemtp
Aby ustawić definicje podczas budowania plików zasobów, ustaw również Opcje dodatkowe w oknie Właściwości konfiguracji -> Zasoby -> Wiersz poleceń - Rado


Projekty C ++ (i rozwiązania) nie są (jeszcze?) Zintegrowane w środowisku MSBuild. W ramach procesu budowania Zadanie VCBuild jest wywoływana, co jest po prostu opakowaniem vcbuild.exe.

Mógłbyś :

  • stworzyć konkretną konfigurację rozwiązania tam, gdzie ACTIVATE=1 zostałby zdefiniowany i skompilowany devenv.exe (z / ProjectConfig przełącznik).
  • utwórz własny plik docelowy, aby zawinąć własne połączenie do Zadanie VCBuild (patrz parametr Override) ...
  • użyj vcbuild.exe zamiast msbuild.exe. (vcbuild.exe nie ma odpowiednika parametru Override).

Zauważ, że twoje rozwiązanie nie zadziałałoby również dla projektów C #, chyba że trochę zmodyfikowałeś pliki projektu. Dla odniesienia, oto jak ja bym to zrobił:

  • Dodaj następujący kod przed wywołaniem <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> :
<PropertyGroup Condition = "'$ (MyConstants)"! =' '">
  <Definicje Stężenia> $ (DefineConstants); $ (MyConstants) </ DefineConstants>
</ PropertyGroup>
  • Zadzwoń do MSBuild w ten sposób:
msbuild / p: MyConstants = "ACTIVATE = 1"

9
2017-10-03 12:22



Mogę użyć vcbuild.exe zamiast msbuild.exe, ale pytanie jest takie samo. Jak ustawić określony preprocesor w linii komend vcbuild? - acemtp
Masz rację: błędnie założyłem, że vcbuild.exe miał taki sam zestaw parametrów jak zadanie VCBuild. Odpowiedź zaktualizowana. - Mac
+1 dla poprawki skryptu projektu - quetzalcoatl
Dobry strzał, <DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants>, to jest to, czego chcę. - JasonMing


Myślę, że chcesz:

/p:DefineConstants=ACTIVATE

8
2017-10-03 12:03



@Matt, zasugerowałem tę samą odpowiedź i dwóch komentujących powiedziało mi, że to nie działa. Dlatego usunąłem odpowiedź, aby inni z większym doświadczeniem w MSBuild mogli oferować pomysły. - Onorio Catenacci
Aha i acemtp powiedzieli mi, że już próbował tego i to nie działało. - Onorio Catenacci
Cóż, to działa dobrze w C # i tak ... - Matt Howells
Działa to również dla mnie. Złożyłem cytaty na liście zdefiniowanych stałych, ale to prawdopodobnie nie ma znaczenia. - blak3r


Jeśli chcesz zdefiniować pewne stałe (nie tylko true / false), możesz zrobić to w następujący sposób:

W wierszu poleceń:

MSBuild /p:MyDefine=MyValue

W pliku vcxproj (w sekcji <ClCompile> i / lub <ResourceCompile>, w zależności od tego, gdzie jest to potrzebne):

<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>

8
2018-04-01 15:23



Czy można to dodać? MY_DEFINE=$(MyDefine) w nieruchomościach projektowych? - s4eed
@ s4eed Tak, otwórz okno dialogowe właściwości projektu, wybierz określoną konfigurację (np. Debugowanie) i platformę (na przykład Win32), przejdź do sekcji C / C ++ -> Preprocessor i dodaj "MY_DEFINE = $ (MyDefine);" przed innymi definicjami w polu Definicje preprocesora. Na przykład, jeśli w tym polu masz "a = b; $ (PreprocessorDefinitions)", ustaw go jako "MY_DEFINE = $ (MyDefine); a = b; $ (PreprocessorDefinitions)". Zrób to samo w Zasobach -> Sekcja ogólna w razie potrzeby. - 4LegsDrivenCat
Powtórz to dla innych konfiguracji i platform. - 4LegsDrivenCat


Potrzebowałem tego również - potrzebowałem, aby móc budować dwie różne wersje mojej aplikacji i chciałem móc napisać skrypt za pomocą VCBUILD. VCBUILD ma przełącznik linii poleceń / override, ale nie jestem pewien, czy można go użyć do modyfikacji symboli #define, które można następnie przetestować przy użyciu kompilacji warunkowej #if.

Rozwiązaniem, które mi się podoba było napisanie prostego narzędzia do utworzenia pliku nagłówkowego, który # zdefiniował symbol na podstawie stanu zmiennej środowiskowej i uruchomił narzędzie z etapu wstępnej kompilacji. Przed każdym wykonaniem kroku VCBUILD skrypt ustawia zmienną środowiskową i "dotyka" pliku w aplikacji, aby zapewnić wykonanie etapu prebuild.

Tak, to brzydki hack, ale to było najlepsze, co mogłem wymyślić!


0
2018-02-20 00:04





Dla VS2010 i nowszych zobacz moją odpowiedź tutaj dla rozwiązania, które nie wymaga modyfikacji oryginalnego pliku projektu.


0
2017-07-03 11:25





Jak wspomniał @ bigh_29, używając zmiennych środowiskowych do zdefiniowania lub niezdefiniowania preprocesora.

To, co zasugerował sposób na niezdefiniowanie preprocesora, jest w rzeczywistości / UAKTYWUJ.

W ten sposób każdy preprocesor pasujący do ACTIVATE zostanie zanegowany, a kompilator nie przejdzie przez twoją klauzulę #if ACTIVATE #endif.


0
2017-08-23 10:23





Być może to zły pomysł, aby odpowiedzieć na tak stare pytanie, ale ostatnio podałem podobny problem i znalazłem ten temat. Napisałem skrypt cmd dla jakiegoś systemu kompilacji i udało mi się znaleźć rozwiązanie. Zostawiam to tutaj dla przyszłych pokoleń (:

Zgodnie z problemem @ acemtp, moje rozwiązanie wyglądałoby tak:

@echo off

:: it is considered that Visual Studio tools are in the PATH
if "%1"=="USE_ACTIVATE_MACRO" (
    :: if parameter USE_ACTIVATE_MACRO is passed to script
    :: the macro ACTIVATE will be defined for the project
    set CL=/DACTIVATE#1
)
call msbuild /t:Rebuild /p:Configuration=Release

UPD: Próbowałem użyć set CL=/DACTIVATE=1 i zadziałało, ale oficjalna dokumentacja zaleca użycie znak liczbowy


0
2018-03-05 17:01





Zmienna środowiskowa CL służy do definiowania makr preprocesorów

Przed wywołaniem MSBUILD, po prostu ustaw zmienną środowiskową "CL" za pomocą opcji "/ D", jak na przykład:

set CL=/DACTIVATE aby zdefiniować AKTYWUJ

Możesz użyć symbolu "#", aby zastąpić znak "="

set CL=/DACTIVATE#1 zdefiniuje ACTIVATE = 1

Następnie zadzwoń do MSBUILD

Więcej dokumentacji na temat zmiennych środowiskowych CL można znaleźć pod adresem: https://msdn.microsoft.com/en-us/library/kezkeayy(v=vs.140).aspx


0
2018-04-03 12:45





Prawdopodobnie powinno to być:

#ifdef ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif

-1
2017-10-03 12:07



@ rdeml - dobry pomysł. - Onorio Catenacci
Nie, to nie #ifdef, to jest #if. W każdym razie nie działa też z #ifdef - acemtp


Odpowiedź brzmi: NIE MOŻESZ


-3
2017-10-07 10:48



Wzruszenie ramionami, być może nie w C ++, ale odpowiedź Matta Howellsa zadziałała dla mnie z projektem C #. Nie mogę wymyślić żadnego powodu, dla którego nie byłoby to możliwe w C ++. - blak3r
Ta zaakceptowana odpowiedź jest tak głęboka, że ​​nawet jej nie widzę. - Sergio Basurco
Odpowiedź @ blak3r Matts nie działa w C ++, a to pytanie dotyczy konkretnie języka C ++. I wydaje się, że nie ma sposobu, aby to zrobić, dodając tylko flagi w wierszu poleceń bez dodatkowych zmian do pliku projektu lub innego pliku zewnętrznego. - Zitrax