For example you can check if Windows is used by checking if "WIN32" macro is defined. And i would like to get the same behaviour but to check if Xlib is used. But i don't know what Xlib defines to know it's defined.
If you don't know what i mean here is an example:
#ifdef WIN32 //Check if WIN32 is defined
//Do something
#endif
And i would like to change this in a way that it does something when Xlib used.
I'm sorry if there are some grammatical errors but i'm not a native english speaker.
The macro WIN32 is only defined, if you included #include <windows.h> before or set the macro in your compiler flags (-DWIN32). For Xlib you could use the macro X_PROTOCOL very similar if you included #include <X11/X.h> before.
#ifdef X_PROTOCOL //Check if X_PROTOCOL is defined
//Do something
#endif
Another way would be to use _XLIB_H_ if you included #include <X11/Xlib.h> before, but I wouldn't because identifiers beginning with an underscore are reserved to the implementation and there is no guarantee that this identifiers won't change.
you can check if Windows is used by checking if "WIN32" macro is defined
The WIN32 macro is defined by default by compilers that target Windows OS. Its purpose is to let the program detect Windows OS API, not necessarily any graphic subsystem.
X11 is not and OS. It's optional userland software that installs and runs under many operating systems, including Windows. When compiling an X11 programs for Windows, WIN32 will be defined, just like for any other Windows program.
No compiler defines anything by default on a system where X11 is installed.
If you want to detect X11 at build time, your best bet is probably a meta-build tool like GNU autotools or CMake.
Related
I am developing a piece of software in C++ using Visual Studio on Windows. From the beginning, I would like to have it run on both Windows and Linux. Obviously, I won't compile the Linux binary on a Windows machine, but I still want to use Visual Studio to write the code.
When it comes to headers, I am selecting while file to use based on pre-processor definitions.
A very rudimentary and simple example:
#pragma once
#ifndef PLATFORM_TIMER_H
#define PLATFORM_TIMER_H
#ifdef _WIN32
#include "win32\win32_timer.h"
#elif __linux__
#include "linux\linux_timer.h"
#endif
#endif // PLATFORM_TIMER_H
For the header it works just fine. But the .cpp-file for the Linux implementation breaks the build on Windows. That's because the Linux .cpp-file will get compiled no matter what, even on Windows. And because the Windows machine is missing Linux-headers, the function it uses will be undefined.
Question 1: What is the "industry standard" to deal with this?
Question 2: Is it reasonable to wrap both the .h and .cpp-files in "#ifdef PLATFORM" so that the code will only be enabled on the correct OS?
But the .cpp-file for the Linux implementation breaks the build on Windows. That's because the Linux .cpp-file will get compiled no matter what, even on Windows.
Why are you compiling the Linux-specific file for a Windows build?
Question 1: What is the "industry standard" to deal with this?
If you're going to create separate source files for Windows-specific and Linux-specific code, then the whole point would be that you use only the appropriate one for the current platform when you build.
An alternative approach would be to have both implementations in the same source file, using conditional compilation to choose which parts to use. That's pretty conventional, too, especially where the parts that vary are smaller than whole functions.
Question 2: Is it reasonable to wrap both the .h and .cpp-files in "#ifdef PLATFORM" so that the code will only be enabled on the correct OS?
It would be strange to go to the trouble of creating separate, platform-specific source files and then use conditional compilation to include them all in every build. It could work, but it would not fall within my personal definition of "reasonable".
Any code specific to one operating system needs to have the proper #ifdef's set up, whether in header files or source files.
Its the first time I'm using WINAPI and with functions like SleepConditionVariableCS , WakeConditionVariable , WaitForMultipleObjects and InitializeConditionVariable Eclipse IDE told me that they were not declared in this scope.
All of them are supposedly included in the same lib windows.h so i dont know what's failings because other functions like ExitThread , ReleaseSemaphore and WaitForSingleObject are running without any problem.
It can be some problem with my c++ version? Or it exist any other library to include?
Thanks
The documentation for SleepConditionVariableCS (or any other WIndows API call) tells you the minimum supported client and server OS. The API calls are conditionally declared, based on your target platform setting.
You can control your target platform by setting certain preprocessor macros (see Using the Windows Headers for information). In your case you need to add
#define WINVER 0x0600
before including Windows.h, to target Windows Vista and later. It is common practice to define the preprocessor macro on the command line, to use a consistent environment across all compilation units.
This question already has answers here:
How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor? [duplicate]
(3 answers)
Closed 5 years ago.
I was asked in an interview to how would you identify the platform only by providing runnable C code?
The code must be runnable in both platform(i.e no special header files function used to check)?
a quick google search shows this
#if defined(_WIN64)
/* Microsoft Windows (64-bit). ------------------------------ */
#elif defined(_WIN32)
/* Microsoft Windows (32-bit). ------------------------------ */
#endif
OS identification macros are predefined by all C/C++ compilers to enable #if/#endif sets to wrap OS-specific code. This is often necessary in cross-platform code that must use low-level library functions for fast disk I/O, inter-process communications, or threads. While differences between Windows and other OSes are acute, even differences among UNIX-style OSes can require #if/#endif constructs. This article surveys common compilers and shows how to use predefined macros to detect common OSes at compile time.
http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
The question is wierd. You can't provide an executable which
can run on multiple platforms. So the obvious answer is:
compile it on one platform: if it runs, that's the platform
you're on; if it doesn't you're on some other platform.
Supposing that you do have separate executables, there's really
no real answer. For starters, what do you consider "a different
platform"? Are Linux on a Sparc and Linux on a PC different
platforms? What about two different versions of Linux? What
about running under CygWin? Regardless of how you define it,
though, you'll probably need a separate test for each platform.
But the question is silly, because, except for considering
different versions different platforms, you'll need a distinct
executable for each platform, which means that you have to
distinguish at compile time anyway
Just for the record: for starters, I'd use boost::filesystem,
and try to read directories "c:\\" and "/usr". In theory,
you could have a directory named "c:\\" in the current
directory under Unix, or a directory named "/usr" in C: under
Windows, but the odds are definitely against it. Otherwise, try
various files in "/proc/myPID". The
directory will almost certainly not exist under Windows, and
even if it does, it won't have the dynamic structure it has
under various Unix. And the structure varies from one Unix to
the next, so you should even be able to distinguish between
Solaris and Linux.
If the comparison is just between Windows and Linux on a PC, of
course, the simplest is to compile in 32 bit mode, and take the
address of a local variable. If it's greater than 0x8000000,
you're under Linux; if it's less, Windows.
That's a bit vague. A binary won't run in both systems unless you run under Wine (then see http://wiki.winehq.org/DeveloperFaq#detect-wine ).
At compile time you can check for #defines specific to Windows or Linux, but arguably that's compiler- and supported-Standards-specific, so I'm not sure if you're "allowed" to do that for the purposes of the interview question (i.e. it's arguably in there with your "no special header files function used to check" restriction).
In general I don't think it makes any sense to do in preference to compile-time checks, and it might not work under Wine, but you could use dlsym() to check yourself for symbols known to be present on only one of the Operating Systems, or look at your own executable image to see what it is.
Practically, it's also very likely you can inspect your environment variables and make a pretty good determination based on that, though someone might be able to deliberately fool your program into an incorrect assessment, or your determination method might break in future versions of the Operating Systems, under different shells etc..
At run-time, you could e.g. stat("/dev", &buf), which should only work on Linux. Trying to popen(3) say uname is another plausible approach: you'll be able to read "linux\n" iff you're on Linux, while a cygwin-like environment apparently reports NT, see here too.
Most of the common methods make the determination at compile time.
If you really insist on making the determination at run time, you could attempt to use a device (for one possibility) that exists on one but not the other (e.g., attempting to open a file named /dev/null should work on Linux but normally fail on Windows).
Aside from the usual MACRO invocations:
#ifdef _WIN32
...
#if defined (_MSC_VER)
...
#ifdef __unix__
...
You could simply use the getenv() function and test for some variables set like SHELL or WINDIR. Interesting cases to decide:
mingw 32/64 under windows 32/64
cygwin 32/64 under windows 32/64
wine under linux 32/64
Of course, "Windows" environment variables can be set in Linux too - and vice-versa.
If you considering only the Linux platform or the Windows platform, this code will be work as needed to you on C and C++.
#include <stdio.h>
#if defined(__linux__) // any linux distribution
#define PLATFORM "linux"
#elif defined(_WIN32) // any windows system
#define PLATFORM "windows"
#else
#define PLATFORM "Is not linux or windows"
#endif
int main(int argc, char *argv[]) {
puts(PLATFORM);
return 0;
}
A full answer with an example see there https://stackoverflow.com/a/42040445/6003870
Every platform has own pre processor directive defined. You have to write the codes within it it.
How do I check OS with a preprocessor directive?
Please follow above link. It may be repeated question.
I am usign DevC++ on Windows 7 Ultimate 32 bit and have included windows.h and psapi.h in my program. All the Windows APIs I've used so far ar working except for GetProcessId and DebugActiveProcessStop. The compiler returns in both cases that the specified function is undeclared. However, when I look in winbase.h, I can clearly see that GetProcessId is declared. Even when I hover the mouse over the function, information on the structure is displayed. So, why can't the compiler seem to recognize either function?
When using the Win32 API headers you need to specify what version of the operating system you are targeting. This is documented in the MSDN library.
Nowadays, you are supposed to do this by defining NTDDI_VERSION. If you check the documentation for GetProcessId you'll note that it requires Windows XP SP1, so you need to specify at least NTDDI_WINXPSP1 as the target operating system version. In fact since SP1 is no longer supported you're probably better off with SP2:
#define NTDDI_VERSION 0x05010200
In the past I've found that defining NTDDI_VERSION doesn't always work as expected, though hopefully most of the glitches have been ironed out by now. If it doesn't work, try using the older macro _WIN32_WINNT instead, which is also documented at the link given above. In this case you want:
#define _WIN32_WINNT 0x0502
If you later need to use functions that were introduced in Vista or Windows 7, change the value of NTDDI_VERSION or _WIN32_WINNT appropriately. The MSDN library documentation for each function says which version of the operating system it was introduced in.
This problem sometimes pops up when you're coding in the windows api. You can see that the function is in the header file, but for some reason, your compiler disagrees. When you come across this problem, find the function in the header file, and look for pre-processor directives around it. You may need to define something in order to use that function.
In this case, here's what i found for the functions you're having problems with:
#if (_WIN32_WINNT >= 0x0501)
WINBASEAPI DWORD WINAPI GetProcessId(HANDLE);
#endif
and
#if (_WIN32_WINNT >= 0x0501)
WINBASEAPI BOOL WINAPI DebugActiveProcessStop(DWORD);
#endif
So, in your main code file, where you include the windows header, put this definition BEFORE your include of the windows header:
#define _WIN32_WINNT 0x0501
This should solve your problem. Good luck ^_^
I am writing an application that I would like to release binaries for on Mac, Windows, and Linux. I have code that compiles under Mac and Linux, but under Windows, it does not.
This is because of Windows lack of a strcasecmp. I've read a little bit about how I can create some sort of header to wrap my code, but I don't really understand this concept too well. I've worked on the code on my Mac with just vim and make, but now I'm trying to switch it all over to Visual Studio.
Is there some way I can set my project up to include Windows wrapper headers when I'm building on Windows, but omit them when I'm building on my Mac or Linux box?
This problem is really giving me a headache and I'd appreciate any suggestions!
You could do
#ifdef WIN32
#include <windows_specific_header.h>
#else
#include <other_header.h>
There is also an MS Visual Studio-specific macro: _MSC_VER, so
#ifdef _MSC_VER
would also work here.
There is also WINVER define in windows.h.
configure my project to generate platform independent code
That is a bit of an odd phase, so I'm not sure that I'm aswering the right question, but here goes:
You have to write platform independent code.
Do one of these:
Write to a cross-platform framework (i.e. QT)
Only use library functions that are available on all your targets
or
provide wrappers to fill up any gaps in the library for on (or more) targets
Boost libraries are designed to be cross-platform. In particular, if you need to manipulate strings, you'll probably find what you need. And it will be cross-platform without having to deal with it yourself. See there to get a glimpse of what's available.
maybe you can consider compiling your code with MINGW32 on windows.