开发者

Windows and *nix compilation detection

开发者 https://www.devze.com 2022-12-20 04:32 出处:网络
One project should be compiled for Windows, Linux and an embedded target. The application has behavior differences when running on host or embedded targets. To summarize my requirements, here is the t

One project should be compiled for Windows, Linux and an embedded target. The application has behavior differences when running on host or embedded targets. To summarize my requirements, here is the table:

   Target               Compiler      Behavior
   Windows              MSVC, gcc         A
   Host Linux           gcc               A
   Embedded Linux       cross pltf gcc    B

I wish to create a Makefile that would recognize the compiler and environmental differences automatically (without need to pass parameters/defines manually). Is it possible to resolve such problem by just using conditional compilation at C source file level?

I don'开发者_高级运维t use automake so far.


The autotools were made to solve this problem. A Makefile by itself can't do this.

As for conditional compilation, there are several macros available that these compilers define (e.g. _MSC_VER for MSVC++, _WIN32 for Windows and and __linux__ for Linux). Also, gcc provides assertions for handling different CPU targets.

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)

That should be sufficient for your purposes.


My answer is: probably. It depends on the differences between your environments.

I would generate a list of the macros pre-defined by the preprocessor in gcc for each of your environments. All you need to do is create an empty file, say foo.h, and run the following command: gcc -E -dM foo.h for each environment. I'd redirect the output to a different file for each environment.

Then, compare the predefined macros and look for one that fits the bill. In your question, you indicated that the embedded environment has different behavior from the Windows and Host Linux platforms. Assuming you're using a different chip architecture for the embedded environment, there should be a macro defined that indicates the architecture. For example, on my 64-bit linux box, __x86_64__ is defined.

Once you have that info, use that macro as your conditional value:

#ifdef MACRO_INDICATING_EMBEDDED
// Behavior B
#else
// Behavior A
#endif


gcc will define

 __linux__

when compiling on linux. MSVC defines something similar - I forget which but I am sure the docs will tell you

but really you need to learn how to use configure. Thats what its for. Its a pain to learn but highly useful (automake, autoconf etc)


You could try a combination of predefined macros for operating systems and architectures; perhaps also interesting: compiler ids.

If you don't want to use a more sophisticated build system, you can parse command line arguments within your makefile. A simple example would be the addition of .exe to executable names on windows. For this I have code like this within the makefile

ifeq ($(target),win32)
    foo_binary := $(foo_binary).exe
endif

and invoke make via a make.bat file containing

@make.exe target=win32 %*
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号