1 |
Project ERROR: Failed to run: 'lrelease.exe' |
64ビットWindowsを使っていて、32ビットのコマンドプロンプトやエクスプローラからqmake関係を起動するとおかしくなることがある。qmakeに限らず、64ビット環境での64ビットアプリと32ビットアプリでは環境変数などが一部異なるので、ビルド環境では64ビットの純正コマンドプロンプトやエクスプローラを使ったほうがよい。
1 |
Project ERROR: Failed to run: 'lrelease.exe' |
64ビットWindowsを使っていて、32ビットのコマンドプロンプトやエクスプローラからqmake関係を起動するとおかしくなることがある。qmakeに限らず、64ビット環境での64ビットアプリと32ビットアプリでは環境変数などが一部異なるので、ビルド環境では64ビットの純正コマンドプロンプトやエクスプローラを使ったほうがよい。
コモンコントロールとはWindowsOSによって提供される基本的な機能を持ったウインドウ。ツリーやリストなど。コモンコントロールはバージョンアップが重ねられており、バージョンの違いでヘッダファイルにも違いが出る。開発環境と実行環境で違うバージョンがインストールされている場合もある。コモンコントロールはIEのインストールでバージョンアップされる。
https://msdn.microsoft.com/en-us/library/windows/desktop/hh298349(v=vs.85).aspx
1 2 3 4 |
5.81 Microsoft Internet Explorer 5.01, Microsoft Internet Explorer 5.5, and Microsoft Internet Explorer 6 5.82 Windows Server 2003, Windows Vista, Windows Server 2008, and Windows 7 6.0 Windows Server 2003 6.10 Windows Vista, Windows Server 2008, and Windows 7 |
実体はComCtl32.dll。C:\Windows\System32\ComCtl32.dllにある。
C言語のヘッダファイルでは_WIN32_IEにより、構造体などの定義が変わる。多くの構造体はそのサイズを持ち、この値がどんどん増えていく。この定数は_WIN32_WINNTの設定によって自動で設定される。_WIN32_WINNTを設定しなければ0x0500(version 5.80)になるようだ。SDKによって変わる。参照
コモンコントロールのDLLがウインドウクラスを登録し、ユーザはこのクラスでCreateWindowExすることにより作成する。 InitCommonControlsEx()を呼ぶと、クラスの登録が行われるがDLLのロード時に行われるのかもしれない。
Visual Stylesはコモンコントロールの表示スタイル(見栄え)を変える。
コモンコントロールの言語を変えるにはInitMUILanguage()を呼ぶ。
ComCtrl32.dllはハードリンクされている。
1 2 3 4 5 6 7 8 9 10 |
>fsutil hardlink list c:\Windows\System32\comctl32.dll \Windows\WinSxS\amd64_microsoft-windows-shell-comctl32-v5_31bf3856ad364e35_10.0.16299.15_none_5c884af3491bf6a4\comctl32.dll \Windows\System32\comctl32.dll > >fsutil hardlink list c:\Windows\SysWOW64\comctl32.dll \Windows\SysWOW64\comctl32.dll \Windows\WinSxS\x86_microsoft-windows-shell-comctl32-v5_31bf3856ad364e35_10.0.16299.15_none_0069af6f90be856e\comctl32.dll > |
WinSxSはサイドバイサイドのアセンブリが置かれているところで長い名前はComCtrl32.dllのアセンブリアイデンティを表している。アプリケーションが特定のバージョンのdllを読み込みたい場合はマニフェストにこのアイデンティを指定する。
1 2 3 |
#pragma comment(linker,"\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") |
このpragmaのつけたexeを起動すると、C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.16299.371_none_5d75084fa7e1cb96\comctl32.dllが使われる。このファイルはハードリンクをこの1つしか持っていない。ver6のコモンコントロールを使うにはマニフェストで指定するしかないことになる。
1 |
$ explorer . |
これは普通に動くが、かなり特殊条件もあって動いている。explorerは起動されたプロセスが開くのではなかったり(開く場合もある)、”.”を理解してちゃんと開いてくれる。それにcygpath(cygwinの形態のパス変換)の問題もない。
TEはプロセスがなければ自分で開くのでcygwinシェルから普通に起動するとシェルがブロックする。&をつけてバックグラウンドで動かしてもシェルがプロセスを管理しているため、cygwinの終了と同時に終了してしまう。nohubを使う手もあるかもしれないがここではスルー。
プロセスの起動はコマンドプロンプトのstartコマンドで行えばプロセス起動後すぐに終了するので上記の問題はない。しかしstartはビルドインプロセスのようでcygwinからは起動できない。そこでcmd /C startで起動すればいい。
パスの返還はcygwinのcygpath -waコマンドで行う。-aはフルパス、-wはWindows形態に変える。
よってカレントディレクトリをTE32.exeで開くには以下のように行う。
1 |
$ cmd /C start '""' `cygpath -wa /cygdrive/C/pathto/TE32.exe` `cygpath -wa .` |
‘””‘はstartに””を送っている。startコマンドの性質上こうしている。
これでcygwinシェルから切り離されたプロセスと起動できたが何らかの環境変数などは継承しているかもしれない。
上記のコマンドはパスにスペースが含まれた場合を考慮していないので、その場合は””でくくらないとならないと思う。
qmakeのproファイルの書き方
hello.proを作成すると、プロジェクト名がhelloになり出来上がる実行ファイル名もhello.exeになる。
SOURCES変数にファイルを追加する。
1 2 |
SOURCES += main.cpp SOURCES += hello.cpp |
スペースで区切って複数指定してもいい、\ (バックスラッシュ)を行末につけて複数行にすることもできる。
1 2 |
SOURCES = main.cpp mainwindow.cpp \ paintwidget.cpp |
HEADERS変数にファイルを追加する。
1 |
HEADERS += header.h |
1 2 3 4 5 6 |
win32 { SOURCES += hellowin.cpp } unix { SOURCES += hellounix.cpp } |
{ は条件と同じラインに書かなければならない。
1 2 3 |
!exists( main.cpp ) { error( "No main.cpp file found" ) } |
CONFIG変数にdebugと設定する。
1 |
CONFIG += debug |
1 2 3 |
win32:debug { CONFIG += console } |
変数は自分で書いてもいい。参照するには $$ を用いる。
1 |
TEMP_SOURCES = $$SOURCES |
1 2 |
win32:INCLUDEPATH += "C:/mylibs/extra headers" unix:INCLUDEPATH += "/home/user/extra headers" |
# で始めるとコメントになる。
1 2 |
# Comments usually start at the beginning of a line, but they # can also follow other content on the same line. |
TEMPLATE変数を使う。
デフォルトはapp
QT変数を使う。
1 |
QT += network xml |
coreとguiはデフォルトで設定される。デフォルトから外したいときは += ではなく = を使う。あるいは -= を使う。
1 |
QT -= gui # Only the core module is used. |
Featureとは.prfで記述される特別な機能。CONFIGに機能を設定して使用する。
1 2 |
CONFIG += link_pkgconfig PKGCONFIG += ogg dbus-1 |
pkg-configを利用して、D-Busとoggライブラリを利用する。
1 |
LIBS += -L/usr/local/lib -lmath |
ライブラリをつくるにはTEMPLATE変数にlibを設定する。そのうえでCONFIG変数でライブラリのタイプを指定する。
$$(ENVVAL)を使う。
1 2 |
DESTDIR = $$(PWD) message(The project will be installed in $$DESTDIR) |
ヘッダファイルをダブルクリックしてリソースエディタで開こうとするとエラーになる。
これはヘッダーファイルの最初のクラスが当該フォームでないため。以下のソースのように前方参照(ref class)を使っていてもうまく動かない。
1 2 3 4 5 6 7 8 9 10 11 |
namespace Ambiesoft { using namespace System; ref class EncComboItem; ref class CSearchURL; ref class AddHttpDicDialog : public System::Windows::Forms::Form { ... } } |
これを回避するには前方参照の部分だけのヘッダーをつくり、それをインクルードすればよい。
前方参照だけのヘッダーheaderref.h
1 2 3 4 5 6 |
#pragma once namespace Ambiesoft { ref class EncComboItem; ref class CSearchURL; } |
もとのヘッダー
1 2 3 4 5 6 7 8 9 10 |
#include "headerref.h" namespace Ambiesoft { using namespace System; ref class AddHttpDicDialog : public System::Windows::Forms::Form { ... } } |
適当に書くので参考までに。
アプリのビルドの際にいろいろなターゲットを指定できる能力のこと。ターゲットには以下の内容が含まれる
ターゲットとコンパイラを合わせてToolsetと言う。ToolsVersionと同じ。
ツールセットで指定される。C:\Program Files\Reference Assemblies\Microsoft\Frameworkにあるアセンブリを参照する。ここにあるアセンブリは実装を持たず機能があるかだけを表す。
VSのプロジェクトファイルには以下の内容が含まれる。
1 |
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
15.0は使うMSBuildのバージョンだがVS2013以降はこの値は使われず、VSのバージョンに合ったバージョンが使われる。MSBuildは互換性が高いのでこの値は対して意味がない。
VSのバージョンとToolsVersionの対応は以下
14.0以前はレジストリにある以下のキーを参照する
1 |
HKLM\Software\Microsoft\MSBuild\ToolsVersions\14.0 |
15.0以降はレジストリは見ないで、以下のものを使う
C:\Program Files\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin
1 2 |
protected: virtual void WndProc(Message% m) override = Control::WndProc; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
void Form1::WndProc(Message% m) { switch (m.Msg) { case WM_CLIPBOARDUPDATE: { if (Clipboard::ContainsText()) { try { String^ text = Clipboard::GetText(); txtLog->AppendText("\n"); txtLog->AppendText(text); } catch (Exception^ ex) { MessageBox::Show(ex->Message); } } m.Result = (IntPtr)0; return; } } Form::WndProc(m); } |
Windowsで実験。python3.5でやった。
1 |
>set PATH=C:\path\ffmpeg\bin;%PATH% |
pythonのpipでffmpeg-normalizeをインストールする
1 |
>pip install ffmpeg-normalize |
ffprobeでaudioコーデックを見つける。
1 |
>ffprobe file.webm |
出力のストリームからaudioコーデックを見つける。aacやvorbisなどがある。
1 |
>ffmpeg-normalize a.webm -o o.webm -c:a libvorbis |
ffmpeg-normalizeが見つからない場合は、pythonフォルダのScriptsにパスを張る。
1 |
>ffmpeg -nostdin -y -i a.webm -filter_complex [0:1]loudnorm=lra=7.0:offset=0.0:i=-23.0:tp=-2.0:print_format=json -vn -sn -f null NUL |