Mikhail
Mikhail

Reputation: 57

Why for gcc 'UNIX' and 'unix' macros are not the same thing?

I have a weird problem with gcc in Ubuntu Mate.

I need to write a golang program which uses a third-party C library, but i'v run a problem.

When I try to connect the third-party library in this code:

package main

// #cgo CFLAGS: -I /opt/cprocsp/include/interfaces/
// #cgo CFLAGS: -I /opt/cprocsp/include/
// #cgo CFLAGS: -I /opt/cprocsp/include/cpcsp/
// #include <stddef.h>
// #include "wincspc.h"
// #include "wincspc_int.h"
import "C"

func main() {
  var CSPConfig C.CPC_CONFIG
  C.CPCGetDefaultConfig(&CSPConfig, nil)
  CSPConfig.logConfig.name = string(C.MODNAME)
}

I get a compile error:

In file included from /opt/cprocsp/include/cpcsp/wincspc.h:28:0,
                 from ./gost.go:7:
/opt/cprocsp/include/cpcsp/WinCryptEx.h:35:10: fatal error: wincrypt.h: No such file or directory
 #include <wincrypt.h>
          ^~~~~~~~~~~~
compilation terminated.

I didn't know what this error meant. Next I decided to open WinCryptEx.h and I found these lines there:

#if defined UNIX || defined CSP_LITE
#include "CSP_WinCrypt.h"
#else // UNIX
#include <wincrypt.h>
#endif // UNIX

So I realized that the compiler runs else statement (but I want it runs if statement because my OS is Linux). To confirm the problem I decided to write a C sample.

#if defined UNIX
#include "CSP_WinCrypt.h"
#else 
#include <wincrypt.h>
#endif 

int main()
{
    printf("Hello world");
}

When I try to run this sample, I get the same error. But then I decided to try to run the next code:

#if defined unix
#include "CSP_WinCrypt.h"
#else 
#include <wincrypt.h>
#endif 

int main()
{
    printf("Hello world");
}

And it works fine!! The compiler runs if statement as I need. I don't understand why.

I can't change the third-party library. So I need the compiler work correctly with 'UNIX' macro.

Does anyone have a solution? Thanks in advance.

Upvotes: 1

Views: 627

Answers (1)

kostix
kostix

Reputation: 55523

This query to a popular Internet search engine brings only a single page matching the word "unix" in the proper context: it's this page on system-specific macros.

That page hints at two things:

  • GCC does not guarantee that UNIX macro is defined.

  • The unix macro is described as being "common" but nothing is stated about the fact it has to be present:

    However, historically system-specific macros have had names with no special prefix; for instance, it is common to find unix defined on Unix systems. For all such macros, GCC provides a parallel macro with two underscores added at the beginning and the end. If unix is defined, __unix__ will be defined too.

In either case, identifiers in C are case-sensitive, and so are the symbols handled by its preprocessor, so unix and UNIX are two unrelated symbols.

In your case, I would supposedly reverse the logic and test for Windows, not the other way.
There, the symbol _WIN32 should be defined by both MinGW and MSVC.

Upvotes: 3

Related Questions