acemtp
En un archivo C++, tengo un código como este:
#if ACTIVATE
# pragma message( "Activated" )
#else
# pragma message( "Not Activated")
#endif
Quiero establecer esta definición ACTIVA en 1 con la línea de comandos de msbuild.
Intentó esto pero no funciona:
msbuild /p:DefineConstants="ACTIVATE=1"
¿Alguna idea?
grande_29
Llegué un poco tarde a la fiesta (solo 4 años más o menos), pero tuve que solucionar este problema en un proyecto y me encontré con esta pregunta mientras buscaba una solución. Nuestra solución fue usar una variable de entorno con /D
define en él, combinado con el cuadro Opciones adicionales en Visual Studio.
- En Visual Studio, agregue una macro de variable de entorno,
$(ExternalCompilerOptions)
a las Opciones adicionales en las opciones del proyecto->C/C++->Línea de comandos (recuerde las configuraciones de depuración y liberación) - Establezca la variable de entorno antes de llamar a msbuild. Utilizar el
/D
opción del compilador para definir sus macros
c:\> set ExternalCompilerOptions=/DFOO /DBAR
c:\> msbuild
El elemento n. ° 1 termina luciendo así en el archivo vcxproj:
<ClCompile>
<AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
</ClCompile>
Esto funciona para mí con VS 2010. Manejamos msbuild desde varios scripts de compilación, por lo que la variable de entorno ugliness está un poco oculta. Tenga en cuenta que no he probado si esto funciona cuando necesita establecer la definición en un valor específico ( /DACTIVATE=1
). Creo que funcionaría, pero me preocupa tener múltiples ‘=’ allí.
H ^ 2
-
Gracias por la respuesta tardía 🙂
– Acemtp
8 de enero de 2013 a las 6:42
-
Para configurar las definiciones al crear archivos de recursos, configure también las Opciones adicionales en Propiedades de configuración -> Recursos -> Línea de comando
– Radó
13 de abril de 2016 a las 16:27
-
¡Me salvas el día!
– l2m2
17 de marzo a las 1:38
Mac
Los proyectos (y soluciones) de C++ no están (¿aún?) integrados en el entorno de MSBuild. Como parte del proceso de construcción, el tarea VCBuild se llama, que es solo un envoltorio vcbuild.exe.
Tú podrías :
- cree una configuración específica para su solución donde
ACTIVATE=1
sería definido, y compilarlo con devenv.exe (con el /ProyectoConfig cambiar). - cree su propio archivo de destino para envolver su propia llamada al tarea VCBuild (ver el parámetro Override)…
use vcbuild.exe en lugar de msbuild.exe.(vcbuild.exe no parece tener el equivalente de un parámetro Override).
Tenga en cuenta que su solución tampoco funcionaría para proyectos de C# a menos que modificara un poco los archivos de su proyecto. Como referencia, así es como haría esto:
- Agregue el siguiente código antes de la llamada a
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
:
<PropertyGroup Condition=" '$(MyConstants)' != '' "> <DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants> </PropertyGroup>
- Llame a MSBuild así:
msbuild /p:MyConstants="ACTIVATE=1"
-
Puedo usar vcbuild.exe en lugar de msbuild.exe pero la pregunta es la misma. ¿Cómo configurar un preprocesador específico en la línea de comandos de vcbuild?
– Acemtp
3 de octubre de 2008 a las 12:31
-
Tiene razón: asumí erróneamente que vcbuild.exe tenía el mismo conjunto de parámetros que la tarea VCBuild. Respuesta actualizada.
– Mac
3 de octubre de 2008 a las 12:49
-
Buen tiro,
<DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants>
eso es lo que quiero.– JasonMing
29 de septiembre de 2014 a las 3:31
4PiernasImpulsadoGato
Si necesita definir alguna constante (no solo true
/false
), puedes hacerlo de la siguiente manera:
En línea de comando:
MSBuild /p:MyDefine=MyValue
En el archivo vcxproj (en la sección <ClCompile>
; y/o <ResourceCompile>
dependiendo de dónde lo necesites):
<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>
Tenga en cuenta que si no especifica /p:MyDefine=MyValue
en una llamada a MSBuild
entonces se asignará una cadena vacía a MY_DEFINE
macro. Si está bien para ti, eso es todo. Si no, sigue leyendo.
Cómo hacer que una macro no esté definida si no se especifica el parámetro correspondiente de MSBuild
Tener MY_DEFINE
macro indefinida en lugar de una cadena vacía, puede usar el siguiente truco:
<ClCompile>
....
<PreprocessorDefinitions>_DEBUG;_CONSOLE;OTHER_UNCONDITIONAL_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(MyDefine)'!=''">MY_DEFINE=$(MyDefine);%(PreprocessorDefinitions)</PreprocessorDefinitions>
....
</ClCompile>
Primero PreprocessorDefinitions
define macros incondicionales. Segundo PreprocessorDefinitions
además define MY_DEFINE
macro cuando MyDefine
no es una cadena vacía. Puede probar esto colocando el siguiente fragmento de código en su archivo cpp:
#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)
#ifndef MY_DEFINE
#pragma message("MY_DEFINE is not defined.")
#else
#pragma message("MY_DEFINE is defined to: [" STRINGIZE(MY_DEFINE) "]")
#endif
y corriendo:
> MSBuild SandBox.sln /p:Configuration=Debug /p:MyDefine=test /t:Rebuild
...
MY_DEFINE is defined to: [test]
...
> MSBuild SandBox.sln /p:Configuration=Debug /p:MyDefine= /t:Rebuild
...
MY_DEFINE is not defined.
...
> MSBuild SandBox.sln /p:Configuration=Debug /t:Rebuild
...
MY_DEFINE is not defined.
...
-
¿Es posible agregar
MY_DEFINE=$(MyDefine)
en proyectos propiedades?– s4eed
18 de mayo de 2018 a las 10:48
-
@s4eed Sí, abra el cuadro de diálogo de propiedades del proyecto, seleccione Configuración específica (por ejemplo, Depuración) y Plataforma (por ejemplo, Win32), vaya a C/C++ -> Sección de preprocesador y agregue “MY_DEFINE=$(MyDefine);” delante de otras definiciones en el campo Definiciones de preprocesador. Por ejemplo, si tenía “a=b;$(PreprocessorDefinitions)” en ese campo, conviértalo en “MY_DEFINE=$(MyDefine);a=b;$(PreprocessorDefinitions)”. Haga lo mismo en la sección Recursos -> General si es necesario.
– 4LegsDrivenCat
19 de julio de 2018 a las 13:56
-
Repita esto para otras configuraciones y plataformas.
– 4LegsDrivenCat
19 de julio de 2018 a las 14:02
-
Esto parece más limpio que la respuesta principal, que establece variables de entorno y funciona en MSBuild 16.1.76. Es posible que desee agregar
#ifndef
guardias a las constantes para silenciar las advertencias.– MakotoE
2 de julio de 2019 a las 1:15
-
El desafío con esta solución es que MY_DEFINE siempre está definido, al menos hasta la cadena vacía. Esto es difícil de probar. La sugerencia de @MakotoE con #ifndef no funciona.
– Troels Blum
13 de noviembre de 2019 a las 14:59
Creo que quieres:
/p:DefineConstants=ACTIVATE
Use la variable de entorno CL para definir macros de preprocesador
Antes de llamar a MSBUILD, simplemente configure la variable de entorno ‘CL’ con las opciones ‘/D’ así:
set CL=/DACTIVATE
para definir ACTIVAR
Puede usar el símbolo ‘#’ para reemplazar el signo ‘=’
set CL=/DACTIVATE#1
definirá ACTIVATE=1
Luego haga la llamada a MSBUILD
Se puede encontrar más documentación sobre las variables de entorno CL en:
https://msdn.microsoft.com/en-us/library/kezkeayy(v=vs.140).aspx
Tal vez sea una mala idea responder una pregunta tan antigua, pero recientemente busqué en Google un problema similar y encontré este tema. Escribí un script cmd para algún sistema de compilación y logré encontrar una solución. Lo dejo aquí para las futuras generaciones (:
Según el problema de @acemtp, mi solución se vería así:
@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: Traté de usar set CL=/DACTIVATE=1
y también funcionó, pero el documentación oficial recomienda usar símbolo de número
bruce ikin
También necesitaba hacer esto: necesitaba poder compilar dos versiones diferentes de mi aplicación y quería poder programar la compilación con VCBUILD. VCBUILD tiene el interruptor de línea de comando /override, pero no estoy seguro de que se pueda usar para modificar los símbolos #define que luego se pueden probar usando la compilación condicional #if.
La solución que se me ocurrió fue escribir una utilidad simple para crear un archivo de encabezado que #definiera el símbolo en función del estado de una variable de entorno y ejecutar la utilidad desde un paso previo a la compilación. Antes de cada ejecución del paso VCBUILD, el script establece la variable de entorno y “toca” un archivo en la aplicación para garantizar que se ejecute el paso de precompilación.
Sí, es un truco feo, ¡pero fue lo mejor que se me ocurrió!