MinGW」タグアーカイブ

ディレクティブ

クロスプラットフォーム対応コードを書くときにプラットフォーム依存部分を切り分けるプリプロセッサディレクティブのメモ。

  • Compiler
    • GCC
      • #ifdef __GNUC__
        • #if __GNUC__ >= 3 // GCC3.0以上
    • Borland C++
      • #ifdef __BORLANDC__
    • intel Compiler
      • #ifdef __INTEL_COMPILER
    • Microsoft Compiler
      • #ifdef _MSC_VER
        • #if _MSC_VER >=600 // C Compiler 6.0以降 VC++含む
        • #if _MSC_VER >=700 // C/C++ Compiler 7.0以降 VC++含む
        • #if _MSC_VER >=800 // VC++1.0以降
        • #if _MSC_VER >=900 // VC++2.0以降
        • #if _MSC_VER >=1000 // VC++4.0以降
        • #if _MSC_VER >=1010 // VC++4.1以降
        • #if _MSC_VER >=1020 // VC++4.2以降
        • #if _MSC_VER >=1100 // VC++5.0以降
        • #if _MSC_VER >=1200 // VC++6.0以降
        • #if _MSC_VER >=1300 // VC2002(VC7.0)以降
        • #if _MSC_VER >=1310 // VC2003(VC7.1)以降
        • #if _MSC_VER >=1400 // VC2005(VC8.0)以降
        • #if _MSC_VER >=1500 // VC2008(VC9.0)以降
        • #if _MSC_VER >=1600 // VC2010(VC10.0)以降
  • UNIX system
    • UNIX
      • #ifdef __unix
      • #ifdef __unix__
    • Linux
      • #ifdef __linux
      • #ifdef __linux__
    • FreeBSD
      • #ifdef __FreeBSD__
    • NetBSD
      • #ifdef __NetBSD__
    • Cygwin
      • #ifdef __CYGWIN__
      • #ifdef __CYGWIN32__ // 32bit版Cygwin
    • MinGW (-mno-cygwin)
      • #ifdef __MINGW32__
  • Windows system
    • CUI
      • #ifdef _CONSOLE
    • GUI
      • #ifdef _WINDOWS
    • 32bit Windows
      • #ifdef WIN32
      • #ifdef _WIN32
    • 64bit Windows
      • #ifdef _WIN64
    • Windows version
      • #ifdef WINVER
        • #if (WINVER >= 0x030a) // Windows 3.1以降
        • #if (WINVER >= 0x0400) // Windows 95/ NT4.0以降
        • #if (WINVER >= 0x0410) // Windows 98以降
        • #if (WINVER >= 0x0500) // Windows Me/ 2000以降
        • #if (WINVER >= 0x0501) // Windows XP/ Server 2003以降
        • #if (WINVER >= 0x0502) // Windows XP SP2/ Server 2003 SP1以降
        • #if (WINVER >= 0x0600) // Windows Vista/ Server 2008以降
        • #if (WINVER >= 0x0601) // Windows 7以降
      • #ifdef _WIN32_WINDOWS // Windows9x
        • #if (_WIN32_WINDOWS >= 0x0400) // Windows 95以降
        • #if (_WIN32_WINDOWS >= 0x0410) // Windows 98以降
        • #if (_WIN32_WINDOWS >= 0x0500) // Windows Me以降
      • #ifdef _WIN32_WINNT // WindowsNTx
        • // Windows 2000以降(0x0500)
          #if (_WIN32_WINNT >= _WIN32_WINNT_WIN2K)
        • // Windows XP/ Server 2003以降(0x0501)
          #if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
        • // Windows XP SP2/ Server 2003 SP1以降(0x0502)
          #if (_WIN32_WINNT >= _WIN32_WINNT_WS03)
        • // Windows Vista以降(0x0600)
          #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
        • // Windows Server 2008以降(0x0600)
          #if (_WIN32_WINNT >= _WIN32_WINNT_WS08)
        • // Windows 7以降(0x0601)
          #if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
      • #ifdef _WIN32_WCE // WindowsCE
        • #if (_WIN32_WCE >= 0x0420) // Windows Mobile 2003(PPC2003)
        • #if (_WIN32_WCE >= 0x0421) // Windows Mobile 2003 SE(PPC2003SE)
        • #if (_WIN32_WCE >= 0x0501) // Windows Mobile 5.0
        • #if (_WIN32_WCE >= 0x0502) // Windows Mobile 6 Professional / Classic
        • #if (WINCEOSVER >= 0x0300) // WindowsCE3.0(PPC2002)以降
        • #if (WINCEOSVER >= 0x0420) // WindowsCE4.2(PPC2003)以降
        • #if (WINCEOSVER >= 0x0500) // WindowsCE5.0(WM5.0)以降
    • Internet Explorer version
      • #ifdef _WIN32_IE
        • #if (_WIN32_IE>=0x0200) // Windows 95/NT 4.0(Comctl32.dll 4.00, Shell32.dll 4.00)
        • #if (_WIN32_IE>=0x0300) // Internet Explorer 3.0, 3.01, 3.02
        • #if (_WIN32_IE>=0x0400) // Internet Explorer 4.0
        • #if (_WIN32_IE>=0x0401) // Internet Explorer 4.01
        • #if (_WIN32_IE>=0x0500) // Internet Explorer 5.0, 5.0a, 5.0b
        • #if (_WIN32_IE>=0x0501) // Internet Explorer 5.01
        • #if (_WIN32_IE>=0x0550) // Internet Explorer 5.5
        • #if (_WIN32_IE>=0x0600) // Internet Explorer 6.0
        • #if (_WIN32_IE>=0x0601) // Internet Explorer 6.0 SP1
        • #if (_WIN32_IE>=0x0603) // Internet Explorer 6.0 SP2
        • #if (_WIN32_IE>=0x0700) // Internet Explorer 7.0
        • #if (_WIN32_IE>=0x0800) // Internet Explorer 8.0

注意
プリプロセッサは、未定義の識別子を0として扱うため、#if __GNUC__ >= 3はGCC3以上として使えるが、
GCC2系かどうかを#if __GNUC__ < 3で判定しようとすると、GCCでないものも含まれる。
参考

Windowsのバージョン取得

使うことなんてないと思うけれど、一応メモ。
Windows系コンパイラなら問題なくコンパイルできると思う。
一応、MinGWでコンパイル、動作確認は行った。


#include <windows.h>
#include <stdio.h>

int main(void)
{
  unsigned int GV = GetVersion();

  printf("GetVersion API(GV)                        = %08X\n\n", GV);
  printf("_winver                                   = %08X\n", _winver);
  printf("_winmajor                                 = %08X\n", _winmajor);
  printf("_winminor                                 = %08X\n", _winminor);
  printf("_osver                                    = %08X\n\n", _osver);
  printf("(( GV << 8 ) | (( GV >> 8 ) & 0XFF)) & 0XFFFF = %08X (= _winver)\n",
                  (( GV << 8 ) | (( GV >> 8 ) & 0XFF)) & 0XFFFF );
  printf("GV & 0XFF                                 = %08X (= _winmajor)\n",
                  GV & 0XFF );
  printf("( GV >> 8 ) & 0XFF                          = %08X (= _winminor)\n",
                  (( GV >> 8 ) & 0XFF));
  printf("GV >> 16                                  = %08X (= _osver)\n\n\n",
                  (GV >> 16) );

  // Windows version(_winmajor, _winminor, _osver)
  printf("This system is [");
  if ( _osver < 0X8000 ) {
    // NT Group (_osver LowWORD MSB = 0)
    switch (_winmajor) {
      case 3:
      case 4:
        printf ("Windows NT %u.%u Build %u",
                         _winmajor, _winminor, _osver);
        break;
      case 5:
        switch (_winminor) {
          case 0:
            printf ("Windows 2000 Build %u", _osver);
            break;
          case 1:
            printf ("Windows XP Build %u", _osver);
            break;
          case 2:
            printf ("Windows Server 2003 family Build %u",
                                    _osver);
            break;
          default:
            printf ("NT Group Windows Build %u", _osver);
        }
        break;
      case 6:
        switch (_winminor) {
          case 0:
            printf ("Windows Vista or Windows Server 2008 Build %u", _osver);
            break;
          case 1:
            printf ("Windows 7 Build %u", _osver);
            break;
          default:
            printf ("NT Group Windows Build %u", _osver);
        }
        break;
      default:
        printf ("NTGroup Windows Build %u", _osver);
    }
  }
  else {
    switch (_winmajor ) {
      case 0: //Win32s Group
      case 1:
      case 2:
      case 3:
        printf ("Win32s Build %u", _osver & 0X7FFF);
        break;
      case 4: // 9X Group (_osver is invalid.)
        switch (_winminor) {
          case 0:
            printf ("Windows 95 Build ----");
            break;
          case 10:
            printf ("Windows 98 Build ----");
            break;
          case 90:
            printf ("Windows Me Build ----");
            break;
          default: // To make sure
            printf ("Newer than Windows Me");
        }
        break;
      default: // To make sure
        printf ("Newer than Windows Me");
    }
  }
  printf("]");

  return 0;
}

JpegopitmをMinGWでコンパイルその2

Jpegoptim.cの変更なんだけど下記の変更のほうが修正個所が1か所にまとまるしいいかも。

@@ -53,6 +53,39 @@
 #define ICC_IDENT_STRING  "ICC_PROFILE\0"
 #define ICC_IDENT_STRING_SIZE 12

+#ifdef WIN32
+#define uid_t   int
+#define gid_t   int
+#define ROOT_UID	0
+#define ROOT_GID	0
+#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
+uid_t getuid(void)
+{
+	return ROOT_UID;
+}
+uid_t geteuid(void)
+{
+	return ROOT_UID;
+}
+gid_t getgid(void)
+{
+	return ROOT_GID;
+}
+gid_t getegid(void)
+{
+	return ROOT_GID;
+}
+int setuid(uid_t uid)
+{
+	return (uid == ROOT_UID ? 0 : -1);
+}
+int setgid(gid_t gid)
+{
+	return (gid == ROOT_GID ? 0 : -1);
+}
+
+#endif
+
 void fatal(const char *msg);

 struct my_error_mgr {

JpegopitmをMinGWでコンパイル

Jpegoptimのコンパイルにちょっと躓いたのでメモ。

  1. msys/src/配下にjpegoptim-1.2.3を解凍して配置
  2. msysを起動して、下記のコマンドを入力
    $ cd /src/jpegoptim-1.2.3/
    $ autoconf
    $ configure
    
  3. configureが通らず、下記のエラーが出る
    configure: error: cannot find install-sh, install.sh, or shtool in aux "."/aux
    
  4. configure.inを下記のように修正する
    @@ -3,7 +3,7 @@
     dnl Process this file with autoconf to produce a configure script.
     AC_INIT(jpegoptim.c)
     AC_CONFIG_HEADER(config.h)
    -AC_CONFIG_AUX_DIR(aux)
    +AC_CONFIG_AUX_DIR(sub)
    
     AC_CANONICAL_HOST
    
  5. subフォルダを作成し、install-sh等を適当な場所から持ってくる(例ではJpeglibから)
    $ mkdir sub
    $ cp ../jpeg-6bx/install-sh ../jpeg-6bx/config.sub ../jpeg-6bx/config.guess ./sub
    
  6. 再度、configureファイルを生成して、configureを実行
    $ autoconf
    $ configure
    
  7. configureが通ったら、makeを実行する。すると下記のエラーが出る
    jpegoptim.c:354: undefined reference to 'realpath'
    jpegoptim.c:354: undefined reference to 'realpath'
    
  8. jpegoptim.cを下記のように修正する
    @@ -351,7 +351,11 @@
           }
           break;
         case 'd':
    -      if (realpath(optarg,dest_path)==NULL || !is_directory(dest_path)) {
    +#ifdef WIN32
    +	if (_fullpath(dest_path,optarg,MAXPATHLEN)==NULL || !is_directory(dest_path)) {
    +#else
    +	if (realpath(optarg,dest_path)==NULL || !is_directory(dest_path)) {
    +#endif
     	fatal("invalid argument for option -d, --dest");
           }
           if (verbose_mode)
    @@ -441,8 +445,13 @@
     	 fatal("splitdir() failed!");
            strncpy(newname,argv[i],sizeof(newname));
          }
    -     snprintf(tmpfilename,sizeof(tmpfilename),
    +#ifdef WIN32
    +	 snprintf(tmpfilename,sizeof(tmpfilename),
    +	      "%sjpegoptim-%d.tmp", tmpdir, (int)getpid());
    +#else
    +	 snprintf(tmpfilename,sizeof(tmpfilename),
     	      "%sjpegoptim-%d-%d.tmp", tmpdir, (int)getuid(), (int)getpid());
    +#endif
        }
    
       retry_point:
    
  9. 再度、makeでコンパイルが通った。

auxというのはBSD系の名残でinstall-shなどの補助スクリプトが各のされているフォルダなのだが、
WindowsではauxというフォルダはDOSの特殊フォルダの名残で作成できない。
そこで、参照先を”sub”に変更し、新たに”sub”フォルダを作成し、GNU系ソフトに同梱されている補助スクリプト類を格納した。
また、コンパイル時にエラーになったrealpathやgetuidはPOSIX系の関数で
Windowsには存在しないため同様の動作するものに置き換えたり削除したりしている。
今回の例ではコンパイルを通すためにrealpathを_fullpathに置き換えたけれどもっときれいに書き直した方がいいな