Windows y * nix detección de compilación
-
20-09-2019 - |
Pregunta
Uno de los proyectos debe ser compilado para Windows, Linux y un blanco incrustado. La aplicación cuenta las diferencias de comportamiento cuando se ejecuta en el host o objetivos embebidos. Para resumir mis necesidades, aquí está la tabla:
Target Compiler Behavior
Windows MSVC, gcc A
Host Linux gcc A
Embedded Linux cross pltf gcc B
Deseo crear un Makefile que reconozca las diferencias compilador y ambientales de forma automática (sin necesidad de pasar parámetros / define de forma manual). ¿Es posible resolver ese problema con sólo usar compilación condicional al nivel de archivo de origen C?
No consumo automake hasta ahora.
Solución
Las autotools rel="noreferrer"> se hicieron para resolver este problema. Un Makefile por sí sola no puede hacer esto.
En cuanto a la compilación condicional, hay varias macros disponibles que definen estos compiladores (por ejemplo _MSC_VER
para MSVC ++, _WIN32
para Windows y para Linux y __linux__
). También, gcc proporciona afirmaciones para el manejo de diferentes objetivos de CPU .
Target Compiler Conditional
Windows MSVC++ #ifdef _MSC_VER
Windows gcc #if defined(_WIN32) && defined(__GNUC__)
Linux gcc #if defined(__linux__) && defined(__GNUC__)
Platform (x86) gcc #if #cpu(i386)
Platform (arm) gcc #if #cpu(arm)
Esto debería ser suficiente para sus propósitos.
Otros consejos
Mi respuesta es: probablemente. Depende de las diferencias entre los entornos.
Me generar una lista de las macros pre-definidos por el preprocesador de gcc para cada uno de sus ambientes. Todo lo que necesita hacer es crear un archivo vacío, dicen foo.h
, y ejecute el siguiente comando: gcc -E -dM foo.h
para cada entorno. Me redirigir la salida a un archivo distinto para cada entorno.
A continuación, comparar las macros predefinidas y buscar uno que encaja a la perfección. En su pregunta, se indica que el entorno incorporado tiene un comportamiento diferente de las plataformas Windows y Linux Host. Suponiendo que usted está utilizando una arquitectura de chip diferente para el entorno incorporado, debe haber una macro definida que indica la arquitectura. Por ejemplo, en mi máquina Linux de 64 bits, se define __x86_64__
.
Una vez que tenga esa información, utilizar esa macro como su valor condicional:
#ifdef MACRO_INDICATING_EMBEDDED
// Behavior B
#else
// Behavior A
#endif
gcc definirá
__linux__
al compilar en Linux. MSVC define algo similar - no recuerdo cuál, pero estoy seguro de que los documentos le dirán
pero realmente necesita aprender cómo utilizar Configurar. Eso es lo que es para. Es un dolor de aprender pero muy útil (automake, autoconf, etc)
Usted podría tratar de una combinación de macros predefinidas para sistemas operativos y noreferrer arquitecturas ; quizás también interesante:. compilador identificadores de
Si no desea utilizar un sistema de construcción más sofisticado, puede analizar los argumentos de línea de comandos dentro de su makefile. Un ejemplo sencillo sería la adición de .exe
a nombres de los ejecutables en las ventanas. Para esto tengo código como este en el archivo make
ifeq ($(target),win32)
foo_binary := $(foo_binary).exe
endif
e invocar hacer a través de un archivo que contiene make.bat
@make.exe target=win32 %*