LoginSignup
9
10

More than 1 year has passed since last update.

MSYS2 にある複数環境、C++ アプリ開発

Posted at

MSYS2 の構成が大きく変更

最近(最近でもないか・・)、MSYS2 の構成が大きく変更になり、昔の環境と大きく様変わりしています。

自分は、主に MSYS2 の下で clang や gcc コンパイラを使って、OpenGL、GLFW、などを利用したアプリを実装していました。

最近、RXマイコン関係の作業を継続して行っていて PC 環境用アプリを触らない状況が長く続いていました。

そんな折 PC 環境用アプリを作ろうと思い、そーいえば、MSYS2 のアップデートをしてないなぁーと思い、MSYS2 の環境整備から始めました。

ところが、MSYS2 のアップデートが上手く出来ないのです・・・

どうやら、システムが大きく変更になり、昔の環境は廃止になったようで、コンフリクトを起こしているようです。

そこで、MSYS2 の古い環境を一応保持して、新規に MSYS2 をインストールして、最初から環境を作り直す事にしました。

MSYS2 の本体は、C:/msys64 なので、それを単純に、リネームして残してあります。


新しい MSYS2 には、複数のショートカットが増えている。

msys2.png

新規に、「MSYS2 CLANG64」、「MSYS2 UCRT64」が増えています。
※ショートカットには無いですが、実際には「CLANG32」もあります。

今まで、「clang」は、「MINGW64」と同居していましたが、分離したようです。
「UCRT64」は何でしょうか?

ここで、MSYS2 の解説を観に行きました。

Overview

Name Prefix Toolchain Architecture C Library C++ Library
msys MSYS /usr gcc x86_64 cygwin
ucrt64 UCRT64 /ucrt64 gcc x86_64 ucrt
clang64 CLANG64 /clang64 llvm x86_64 ucrt
clangarm64 CLANGARM64 /clangarm64 llvm aarch64 ucrt
clang32 CLANG32 /clang32 llvm i686 ucrt
mingw64 MINGW64 /mingw64 gcc x86_64 msvcrt
mingw32 MINGW32 /mingw32 gcc i686 msvcrt

どうやら上記のような違いがあるようです。

MSYS2 のパッケージは一般的な Linux ディストリビューションのパッケージのように動作します。
それに加えて、Windows 依存のツールキットライブラリで API を叩く事が出来るので、プログラミングの幅が広がります。

自分は、この環境が非常に心地よく、色々な事をやるのに便利なので長らく使い続けています。
良く、C++ なら VisualStudio を使えば良いのにと言われる事がありますが、オープンソースのコードをコンパイルして組み込むのに適しているし。
Linux や Mac 環境にも親和性が高いので、当分この環境を離れられません。


CLANG64 環境に色々パッケージをインストール

MSYS2 のパッケージマネージャーは、「Arch Linux」で知られる「pacman」が使われています。
最近の実装では、マルチスレッドで複数パッケージをインストールするなど、かなり便利に使えるようになっています。

キーワードでパッケージを探す:

% pacman -Ss xxxxx

パッケージのインストール:

% pacman -S xxxxx

CLANG64 環境のパッケージをインストール:
pacman は、どの環境で動かしても、良く、各環境毎にプレフィックスを追加するだけです。

たとえば、libpng は、環境毎に以下のような名称になっています。

 % pacman -Ss libpng
clangarm64/mingw-w64-clang-aarch64-libpng 1.6.39-1
    A collection of routines used to create PNG format graphics (mingw-w64)
mingw32/mingw-w64-i686-libpng 1.6.39-1
    A collection of routines used to create PNG format graphics (mingw-w64)
mingw64/mingw-w64-x86_64-libpng 1.6.39-1 [インストール済み: 1.6.38-1]
    A collection of routines used to create PNG format graphics (mingw-w64)
ucrt64/mingw-w64-ucrt-x86_64-libpng 1.6.39-1 [インストール済み: 1.6.38-1]
    A collection of routines used to create PNG format graphics (mingw-w64)
clang32/mingw-w64-clang-i686-libpng 1.6.39-1
    A collection of routines used to create PNG format graphics (mingw-w64)
clang64/mingw-w64-clang-x86_64-libpng 1.6.39-1 [インストール済み: 1.6.38-1]
    A collection of routines used to create PNG format graphics (mingw-w64)

CLANG64 用パッケージは「mingw-w64-clang-x86_64-libpng」となります。


俺俺アプリケーションのビルド

自分のアプリケーションビルドに必要な各種パッケージをインストールします。

   pacman -S mingw-w64-clang-x86_64-clang
   pacman -S mingw-w64-clang-x86_64-boost
   pacman -S mingw-w64-clang-x86_64-glfw
   pacman -S mingw-w64-clang-x86_64-freetype
   pacman -S mingw-w64-clang-x86_64-glew
   pacman -S mingw-w64-clang-x86_64-libjpeg-turbo
   pacman -S mingw-w64-clang-x86_64-openjpeg2
   pacman -S mingw-w64-clang-x86_64-libpng
   pacman -S mingw-w64-clang-x86_64-faad2
   pacman -S mingw-w64-clang-x86_64-libmad
   pacman -S mingw-w64-clang-x86_64-ffmpeg

次に、自分のアプリをビルドしようとしますが、意味不明のエラーで先に進みません・・・

In file included from C:/msys64/clang64/include/c++/v1/__type_traits/apply_cv.h:16:
In file included from C:/msys64/clang64/include/c++/v1/__type_traits/remove_reference.h:13:
C:/msys64/clang64/include/c++/v1/cstddef:50:9: error: no member named 'nullptr_t' in the global namespace
using ::nullptr_t;
      ~~^
In file included from main.cpp:7:

これは、単に、Makefile で与えているインクルードパスが余計な為でした・・・

clang++ -c -O2 -std=c++17 -DWIN32 -DBOOST_USE_WINDOWS_H -DHAVE_STDINT_H -DNDEBUG -isystem /clang64/include -isystem /clang64/include/freetype2 -isystem /clang64/include/openjpeg-2.5 -isystem /clang64/include/openjpeg-1.5  -I. -I../common -Wall -Werror -Wno-unused-private-field -Wno-unused-variable -Wno-unused-function -Wno-unused-but-set-variable -o release/main.o main.cpp

※「-isystem /clang64/include」が不必要
clang コンパイラは、起動すると、自身の環境に適した順序で、標準的なインクルードパスを内部で設定します。
この仕組みは結構複雑で、このような指定は、それを阻害するようです。
取り除いたら、素直にコンパイル出来ました。
以前の、mingw64 の時は、この指定が無いと、逆に正しくコンパイル出来なかった覚えがあります。

「freetype」や「openjpeg」では、ルートのディレクトリーを追加で指定する必要があるので、以下のように「Makefile」に記述しています。

LOCAL_INC_PATH := /clang64/include

INC_SYS		=	$(LOCAL_INC_PATH)/freetype2 $(OPENJPEG_PATH) \
				$(INC_USR)

openjpeg はバージョンがあるので、簡易的に、バージョン番号を取り込むようにしています。

OPENJPEG_PATH := $(shell ls -r -d $(LOCAL_INC_PATH)/openjpeg*)

これらは CMake などを使うと、もっとスマートに出来るものと思いますが、自分のアプリ環境はそこまで複雑では無いので、Makefileだけで何とかしています。

この Makefile には、従属規則の生成も自動化してあります。
※タイムスタンプを評価してコンパイルを自動化する。

ちなみに、Makefile には、マルチプラットホーム環境に対応したスクリプトを入れてあります。

# platform switcher (Windows, Linux, OS-X)
ifeq ($(OS),Windows_NT)
    FEXT	= .exe
    SYSTEM := WIN
	CPP_VER := -std=c++17
    LOCAL_INC_PATH := /clang64/include
    LOCAL_LIB_PATH :=
	OPTLIBS = opengl32 glu32 glew32 openal glfw3 \
			  comdlg32 hid setupapi ksguid
	CPMM	=	g++
	CCMM	=	gcc
	CFLAGS  += -DWIN32
	PFLAGS  += -DWIN32 -DBOOST_USE_WINDOWS_H
	LFLAGS	+=
else
  FEXT	=
  UNAME := $(shell uname -s)
  ifeq ($(UNAME),Linux)
    SYSTEM := LINUX
	CPP_VER := -std=c++17
	CFLAGS +=
	PFLAGS +=
	LFLAGS +=
  endif
  ifeq ($(UNAME),Darwin)
    SYSTEM := OSX
	OSX_VER := $(shell sw_vers -productVersion | sed 's/^\([0-9]*.[0-9]*\).[0-9]*/\1/')
	CPP_VER := -std=c++17
	CFLAGS +=
	PFLAGS +=
	LFLAGS += -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \
		-Wl,-search_paths_first -Wl,-headerpad_max_install_names \
		-framework AGL -framework Cocoa -framework OpenGL -framework IOKit \
		-framework CoreFoundation -framework CoreVideo -framework OpenAL
    LOCAL_INC_PATH := /opt/local/include
    LOCAL_LIB_PATH := /opt/local/lib
    OPTLIBS = glfw GLEW
  else
    LOCAL_INC_PATH := /usr/local/include
    LOCAL_LIB_PATH := /usr/local/lib
  endif
  CPMM	=	clang++
  CCMM	=	clang
endif

mintty の設定

最近の MSYS2 コンソールは、mintty が標準になっています。

ただ、何もしないと、多少見ずらいので、自分は以下の設定を、ホームディレクトリ以下に「.minttyrc」でセーブしてあります。

# mintty Settings
BoldAsFont=no
FontHeight=11

Columns=110
Rows=40
Locale=ja_JP
Charset=UTF-8
Term=xterm-256color

CopyOnSelect=yes
BackspaceSendsBS=yes

IMECursorColour=255,0,0

VSCode を使う

テキストエディタは、emacs を昔から使ってきました。
今でも使いますが、最近では、VSCode を使っています。
※emacsのキーバインドがあるのが大きいです。

MSYS2 環境で clang を使う場合、「c_cpp_properties.json」に設定を追加します。
※ネットで拾った記述に自分用の物を追加しています。
インテリセンスを正しく動作させるには、パスが重要なのですが、良く判っていません・・

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceRoot}",
                "C:/msys64/clang64/include",
                "C:/msys64/clang64/include/**",
                "C:/msys64/clang64",
                "C:/msys64/clang64/include/c++/v1",
                "C:/msys64/clang64/lib/clang/15.0.4/include",
                "C:/msys64/clang64/lib/clang/15.0.4/include/**",
                "${workspaceFolder}/**",
                "C:/msys64/clang64/bin",
                "C:/msys64",
                "D:/Git/glfw_app/glfw_app/common"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "windowsSdkVersion": "10.0.19041.0",
            "compilerPath": "C:/msys64/clang64/bin/clang++.exe",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64",
            "browse": {
                "path": [
                    "C:/msys64/clang64/include",
                    "C:/msys64/clang64/include/**",
                    "C:/msys64/clang64/include/c++/v1",
                    "C:/msys64/clang64/lib/clang/15.0.4/include",
                    "C:/msys64/clang64/lib/clang/15.0.4/include/**",
                    "${workspaceRoot}",
                    "C:/msys64/clang64/bin",
                    "C:/msys64",
                    "D:/Git/glfw_app/glfw_app/common"
                ],"limitSymbolsToIncludedHeaders": true,
                "databaseFilename": ""
            }
        }
    ],
    "version": 4
}

GLFW OpenAL などを使ったアプリ開発

GLFW、OpenAL などを使う事で、マルチプラットホームで、2D/3Dグラフィックス、オーディオを使ったアプリを開発出来ます。
まぁ、そのようなフレームワークは、沢山ありますが、自分は、初期の頃から、自分用フレームワークを構築していて、小回りが利き自分には使いやすいです。

全ソースコードは github に上げてあり、MIT ライセンスで公開してあります。

元々、GLFW が出る以前に OpenGL,OpenAL のみを使って実装していたので、「gl_fw」と言うネーミングになっています。(現在は、glfw3_app)

中途な物や、実験的な物など色々ありますが、参考として、MMD のファイルをプレビューする為に作った物のスクリーンショットを載せておきます。
※MMDのファイルを読んで、レンダリングするだけの物で、アニメーションとかは実装中です・・・

pmdv.png

機能的に、イマイチな部分もありますが、GUI など、何かアプリを作る場合に必要な機能は、大体あります。

このフレームワークの特殊性として、描画は全て OpenGL によって行っており、リアルタイムで表示しています。
最近のマシンは、描画性能が極めて高いので、リッチな物でもビクともしません。
漢字や日本語も、freetype でビットマップを生成して、それをテクスチャに登録して管理しています。
このような特異な手法は、ゲームのような場面に向いていて、ダブルバッファで描画するので応答が良く、リアルタイムに何か操作するような用途に向いていると思います。

9
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10