「オープンソースのビルド ffftp」の版間の差分
編集の要約なし |
|||
| (同じ利用者による、間の5版が非表示) | |||
| 1行目: | 1行目: | ||
<yjavascript></script> | |||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/vs2015.css"> | |||
<link rel="stylesheet" href="https://wiki.yo-net.jp/custom.css"> | |||
<script src="https://wiki.yo-net.jp/highlight/highlight.js"></script> | |||
<script src="https://wiki.yo-net.jp/custom.js"></script> | |||
<script type="text/javascript" charset="UTF-8" src="https://wiki.yo-net.jp/highlight/highlightjs-vba/dist/vba.min.js"></script> | |||
<script type="text/javascript">hljs.initHighlightingOnLoad();</script> | |||
<script></yjavascript> | |||
[[メインページ#言語と開発環境|言語と開発環境]]に戻る。 | [[メインページ#言語と開発環境|言語と開発環境]]に戻る。 | ||
== '''概要''' == | == '''概要''' == | ||
ffftpはftp通信を行う国産のオープンソースのフリーソフトウェアです。この記事はとにかくオープンソースソフトウェアをビルドしてみようとする記事です。 | |||
ソースは以下から入手できます。 | |||
*[https://github.com/ffftp/ffftp https://github.com/ffftp/ffftp] | |||
公式にもビルド方法の概要がありますが、初学者にはコレだけでは無理なレベルの説明です。 | |||
== '''詳細な手順''' == | |||
ffftp-5.8.zipを解凍して、自分の開発用ディレクトリにコピペします。コピペした先ディレクトリをC:\(ffftpのルートパス)と以降表現します。できれば、ffftpで使うライブラリをまとめておくために、C:\(ffftpのルートパス)のひとつ上のディレクトもffftpWorkSpaceのようなディレクトリにしておくとよいと思います。一つ上のディレクトリをC:\(ffftpのワークスペースルートパス)と以降表現します。 | |||
このままフォルダ内に含まれるソリューションを起動してビルドしてみたいところですが、公式のビルド方法にもあるとおり、Boost.RegexとMicrosoft GSL(Guidelines Support Library)とWiX v3 Microsoft Visual Studio 2022 Extensionが必要で、別途ヘルプ開発にはMicrosoft HTLM Help Workshopが必要だそうです。Microsoft HTLM Help Workshopは既に配布が終わっており入手は困難なはずですが[https://www.helpandmanual.com/downloads_mscomp.html https://www.helpandmanual.com/downloads_mscomp.html]ここから入手できました。まぁHTMLでヘルプを作成するための古くから存在する地味なツールです。 | |||
=== '''Boost Regexを導入する''' === | |||
Boost.Regexの導入方法については別記事として[[Boost.Regex ライブラリの導入]]に詳細な手順が記述してありますので、やってみて下さい。ffftpではICU関連の正規表現関数は使いませんが、ICUライブラリをスタティックライブラリとして生成して、ランタイム設定は/MTや/MTdにして生成した後、b2コマンドでlink=static runtime-link=staticとして生成したライブラリを使います。別記事の手順に従えば、デバッグ版としてlibboost_regex-vc143-mt-sgd-x64-1_89.libが生成されます。リリース版はlibboost_regex-vc143-mt-s-x64-1_89.libですね。ICUのビルドで生成したsicudt.lib, sicuuc.lib, sicuin.lib, sicuio.lib, sicutu.lib, sicutest.lib, stestplug.libとsicuucd.lib, sicuind.lib, sicuiod.lib, sicutud.lib, sicutestd.lib, stestplugd.libも必要になります。ffftpのランタイム設定は/MTとか/MTdです。ランタイム設定/MDや/MDdのライブラリと混在して利用することはできません。以下のライブラリ名は同じですが、 | |||
sicuuc.lib, sicuin.lib, sicuio.lib, sicutu.lib, sicutest.lib, stestplug.libとsicuucd.lib, sicuind.lib, sicuiod.lib, sicutud.lib, sicutestd.lib, stestplugd.libはランタイム設定を/MTあるいは/MTdである必要があります。 | |||
C:\(ffftpのワークスペースルートパス)の下にboost1_89_0のような名前のディレクトリを作り、その中にインクルードファイルが保持されたC:\(Boost.Regexのルートパス)\boostのディレクトリごとをコピーC:\(ffftpのワークスペースルートパス)\boost1_89_0にコピーします。 | |||
つまり | |||
*C:\(Boost.Regexのルートパス)\boost | |||
:→C:\(ffftpのワークスペースルートパス)\boost1_89_0\boostが出来上がる。 | |||
さらにC:\(Boost.Regexのルートパス)\stageのディレクトリごとをコピーC:\(ffftpのワークスペースルートパス)\boost1_89_0にコピーします。stageの中にはlibというフォルダがあってその中にデバッグ版としてlibboost_regex-vc143-mt-sgd-x64-1_89.libが生成されます。リリース版はlibboost_regex-vc143-mt-s-x64-1_89.libが存在してます。 | |||
つまり | |||
*C:\(Boost.Regexのルートパス)\stage | |||
:→C:\(ffftpのワークスペースルートパス)\boost1_89_0\stageが出来上がる。 | |||
ICUのライブラリとインクルードファイルも同じようにC:\(ffftpのワークスペースルートパス)の中にICU77ようなフォルダを作ってその中にコピーします。 | |||
つまり | |||
*C:\(ICUのルートパス)\icu4c\lib64 | |||
:→C:\(ffftpのワークスペースルートパス)\ICU77\lib64が出来上がる。 | |||
*C:\(ICUのルートパス)\icu4c\Include | |||
:→C:\(ffftpのワークスペースルートパス)\ICU77\Includeが出来上がる。 | |||
上記のようなファイルの再配置をせずに、きちんと相対パスとか絶対パスとかを管理しきれる人で自分で整理する術を持っている人はファイル配置の手順については省略することができ、以下の説明をうまく読み替えて下さい。よくわからない人は上記のようにファイルを配置できたら | |||
C:\(ffftpのルートパス)\ffftp.slnをVisual Studioで開きましょう。 | |||
Visual Studioのソリューションエクスプローラからffftpプロジェクトを選択してメニュー[プロジェクト(P)]-[プロパティ]を開きます。構成の[Debug]と[Release]の選択に留意して、 | |||
構成のDebugを選択した状態の場合は以下のように設定します。 | |||
[構成プロパティ]-[VC++ディレクトリ]の項目[インクルードディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。フォルダ名は各自で調整していいんだよ。ただしく設定できるならね。TESTプロジェクトはffftpプロジェクトのあるフォルダの中にtestフォルダがあってその中にあるからtestプロジェクトから見ると二つ上にあがらなきゃいけないから..\が一つ多いんだよ。 | |||
*ffftpプロジェクト→..\boost1_89_0;..\GSL-main\include; | |||
*testプロジェクト→..\..\boost1_89_0;..\..\GSL-main\include; | |||
[構成プロパティ]-[VC++ディレクトリ]の項目[ライブラリディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。 | |||
*ffftpプロジェクト→..\boost1_89_0\stage\lib;..\ICU77\lib64\ | |||
*testプロジェクト→..\..\boost1_89_0\stage\lib;..\..\ICU77\lib64\; | |||
次に[構成プロパティ]-[リンカー]-[入力]の項目[追加の依存ファイル]に以下を追記 | |||
*ffftp/testプロジェクト共通→libboost_regex-vc143-mt-sgd-x64-1_89.lib;sicudt.lib;sicuind.lib;sicuucd.lib;Advapi32.lib; | |||
構成のReleaseを選択した状態の場合は以下のように設定します。 | |||
[構成プロパティ]-[VC++ディレクトリ]の項目[インクルードディレクトリ]に以下を追加。 | |||
*ffftpプロジェクト→..\boost1_89_0;..\GSL-main\include; | |||
*testプロジェクト→..\..\boost1_89_0;..\..\GSL-main\include; | |||
[構成プロパティ]-[VC++ディレクトリ]の項目[ライブラリディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。 | |||
*ffftpプロジェクト→..\boost1_89_0\stage\lib;..\ICU77\lib64\ | |||
*testプロジェクト→..\..\boost1_89_0\stage\lib;..\..\ICU77\lib64\; | |||
次に[構成プロパティ]-[リンカー]-[入力]の項目[追加の依存ファイル]に以下を追記 | |||
*ffftp/testプロジェクト共通→libboost_regex-vc143-mt-s-x64-1_89.lib;sicudt.lib;sicuin.lib;sicuuc.lib;Advapi32.lib; | |||
これでBoost.Regexの設定は完了です。 | |||
=== '''Microsoft GSL(Guidelines Support Library)を導入する''' === | |||
詳細は[[Microsoft GSL(Guidelines Support Library) ライブラリの導入]]のとおりのやり方なんですけど、C:\(GSLのルートパス)全体をC:\(ffftpのワークスペースルートパス)の下にコピーしましょう。 | |||
*C:\(GSLのルートパス) | |||
:→C:\(ffftpのワークスペースルートパス)\GSL-mainが出来上がる。 | |||
GSL-mainという名前はGSLのルートパスの末尾のフォルダの名前です。2025年10月現在の規定値と同じにしています。 | |||
配置したらOK。BoostRegexの導入手順の中でインクルードディレクトリへの追加作業はしてありましたので、設定は不要です。 | |||
GSLの設定は以上で完了です。 | |||
=== '''WiX v3 Microsoft Visual Studio 2022 Extensionを導入する''' === | |||
WiX v3は簡単なプログラムインストーラーを作るための拡張機能です。 | |||
Visual Studioを起動します。スタートアップウィンドウが表示されたら、コードなしで続行っていう部分をクリックしてスタートアップウィンドウを閉じます。スタートアップウィンドウはメニューの[ファイル]-[スタートアップウィンドウ]を選択するとまた表示できます。 | |||
メニュー[拡張機能]-[拡張機能の管理]を選択します。メインウィンドウに拡張機能マネージャーというタブが表示されます。このタブの中にある[参照]が選択されている状態で検索の文字を入力するエディットボックスに[WiX]と入力するとトップに表示されますので、[インストール]を押しましょう。 | |||
その後しばらくするとインストール処理は完了するので、VisualStudioを再起動しましょう。 | |||
以上でWiX v3 Microsoft Visual Studio 2022 Extensionの導入作業は完了です。 | |||
=== '''ffftpとtestプロジェクトをビルドする''' === | |||
2025年10月現在ではビルドするとエラーがぶわっとたくさん表示されます。参照渡しがうまく変換できないエラーばかりのようです。 | |||
例えば、 | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="Boost_Regex_ICU.cpp" class="pre-wrap"> | |||
<code class="cpp">template<int captionId = IDS_APP> static inline auto Message(HWND owner, int textId, DWORD style) noexcept { MSGBOXPARAMSW msgBoxParams{ sizeof MSGBOXPARAMSW, owner, GetFtpInst(), MAKEINTRESOURCEW(textId), MAKEINTRESOURCEW(captionId), style, nullptr, 0, nullptr, LANG_NEUTRAL }; return MessageBoxIndirectW(&msgBoxParams); }</code></pre></div> | |||
<script></yjavascript> | |||
のsizeof MSGBOXPARAMSWをsizeof(MSGBOXPARAMSW)にして | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="Boost_Regex_ICU.cpp" class="pre-wrap"> | |||
<code class="cpp">template<int captionId = IDS_APP> static inline auto Message(HWND owner, int textId, DWORD style) noexcept { MSGBOXPARAMSW msgBoxParams{ sizeof(MSGBOXPARAMSW), owner, GetFtpInst(), MAKEINTRESOURCEW(textId), MAKEINTRESOURCEW(captionId), style, nullptr, 0, nullptr, LANG_NEUTRAL }; return MessageBoxIndirectW(&msgBoxParams); }</code></pre></div> | |||
<script></yjavascript> | |||
としなきゃだめだったりしましたし、 | |||
例えばconnect.cppの場合は以下のような修正が必要でした。 | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="connect.cpp" class="pre-wrap"> | |||
<code class="cpp">std::make_wformat_args(User, (wchar_t)FwallDelimiter, Host, Port)</code></pre></div> | |||
<script></yjavascript> | |||
という関数が引数として与えられている箇所では、いったんFwallDelimiterをwchar_t型の変数に格納して、 | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="connect.cpp" class="pre-wrap"> | |||
<code class="cpp">wchar_t delim = gsl::narrow_cast<wchar_t>(FwallDelimiter);</code></pre></div> | |||
<script></yjavascript> | |||
として | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="connect.cpp" class="pre-wrap"> | |||
<code class="cpp">std::make_wformat_args(User, delim, Host, Port)</code></pre></div> | |||
<script></yjavascript> | |||
のようにするといいです。gsl関連のキャストエラーも出るので、上記のようにキャストしておくといいです。 | |||
他にもtoolmenu.cppでは | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="toolmenu.cpp" class="pre-wrap"> | |||
<code class="cpp">auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(MakeSizeString(Size))) : L""s;</code></pre></div> | |||
<script></yjavascript> | |||
という部分のMakeSizeString(Size)が参照渡しエラーになっていて | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="toolmenu.cpp" class="pre-wrap"> | |||
<code class="cpp">std::wstring tmptext2 = MakeSizeString(Size);</code></pre></div> | |||
<script></yjavascript> | |||
のように同じように、いったんstd::wstring型の変数に格納してあげたりします。 | |||
statuswin.cppでは | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="statuswin.cpp" class="pre-wrap"> | |||
<code class="cpp"> //2025/10/10 修正 | |||
std::wstring tmptext; | |||
if (GetDiskFreeSpaceExW(directory.c_str(), &a, nullptr, nullptr) != 0) { | |||
tmptext = MakeSizeString(a.QuadPart); | |||
} | |||
else { | |||
tmptext = L"??"; | |||
} | |||
auto const text = std::vformat(format, std::make_wformat_args(tmptext)); | |||
</br> | |||
//auto const text = std::vformat(format, std::make_wformat_args(GetDiskFreeSpaceExW(directory.c_str(), &a, nullptr, nullptr) != 0 ? MakeSizeString(a.QuadPart) : L"??"s));</code></pre></div> | |||
<script></yjavascript> | |||
だったり | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="statuswin.cpp" class="pre-wrap"> | |||
<code class="cpp"> //2025/10/10 修正 | |||
int num = AskTransferFileNum(); | |||
auto const text = std::vformat(format, std::make_wformat_args(num)); | |||
//auto const text = std::vformat(format, std::make_wformat_args(AskTransferFileNum()));</code></pre></div> | |||
<script></yjavascript> | |||
だったり | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="statuswin.cpp" class="pre-wrap"> | |||
<code class="cpp"> //2025/10/10 修正 | |||
std::wstring tmptext2 = MakeSizeString(Size); | |||
auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(tmptext2)) : L""s; | |||
//auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(MakeSizeString(Size))) : L""s; | |||
</code></pre></div> | |||
<script></yjavascript> | |||
といった修正をしました。 | |||
toolmenu.cppでは | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="toolmenu.cpp" class="pre-wrap"> | |||
<code class="cpp"> //2025/10/10 修正 | |||
int num = i + 1; | |||
auto text = std::vformat(format, std::make_wformat_args(fs::path{ ViewerName[i] }.filename().native(), num)); | |||
//auto text = std::vformat(format, std::make_wformat_args(fs::path{ ViewerName[i] }.filename().native(), i + 1));</code></pre></div> | |||
<script></yjavascript> | |||
という修正をしました。いったん何らかの変数に代入しないと解決できない感じのが多かったな。 | |||
ftpproc.cppでは無意味になっているコードがあって | |||
<yjavascript></script> | |||
<!-- | |||
data-line-num-start="1" | |||
data-line-highlight="3, 10-" | |||
data-max-lines="10" | |||
--> | |||
<div class="hljs-wrap"><pre data-label="ftpproc.cpp" class="pre-wrap"> | |||
<code class="cpp">if (f.InfoExist & FINFO_SIZE) { // サイズ情報がある場合のみ | |||
CalcExtentSize(&Pkt, f.Size); | |||
} | |||
// int const a = f.InfoExist && FINFO_SIZE; | |||
// CalcExtentSize(&Pkt, f.Size);</code></pre></div> | |||
<script></yjavascript> | |||
という修正も必要だったりしました。これはうっかりバグの類でのこっていたので、管理人のSayuri氏に報告しておきました。やりたっかことはこうじゃないか?っていう予想です。TANDEM(現 HPE NonStop シリーズ)は、銀行や証券などの高信頼性向けサーバでOSにOpen System ServicesというOSSを使っているときの、ファイルサイズ再計算処理をしたいときの処理で、ほとんどの人には関係しない部分の動作です。関係者が仕事でそういうサーバと向き合ったりしたときに要望があったり、自分で発見したりして、追加したコードなのかもしれませんね。 | |||
そんなところでした。また時間が経過すると修正されたり、動かなくなる部分が増えたりするのかもしれません。 | |||
=== '''総括''' === | |||
問題なくビルドできました。またひとつ制覇したことになります。自分にできたということは誰にでもできる指標になります。是非、暇な人はトライしてみて欲しいですね。動かしてソースを理解し、知識を習得しましょう。 | |||
== ''' 時事情報''' == | |||
やってみたらうまくいかないことはよくあります。ここで注意すべき事で気づいた点を勝手に記述して残しておくという非協力的な記事です。 | |||
*[[オープンソースのビルド ffftp 2024年11月頃 std::make_wformat_argsなどの標準関数の定義変更によるコンパイルエラー]] | |||
2025年10月12日 (日) 00:41時点における最新版
言語と開発環境に戻る。
概要
ffftpはftp通信を行う国産のオープンソースのフリーソフトウェアです。この記事はとにかくオープンソースソフトウェアをビルドしてみようとする記事です。
ソースは以下から入手できます。
公式にもビルド方法の概要がありますが、初学者にはコレだけでは無理なレベルの説明です。
詳細な手順
ffftp-5.8.zipを解凍して、自分の開発用ディレクトリにコピペします。コピペした先ディレクトリをC:\(ffftpのルートパス)と以降表現します。できれば、ffftpで使うライブラリをまとめておくために、C:\(ffftpのルートパス)のひとつ上のディレクトもffftpWorkSpaceのようなディレクトリにしておくとよいと思います。一つ上のディレクトリをC:\(ffftpのワークスペースルートパス)と以降表現します。
このままフォルダ内に含まれるソリューションを起動してビルドしてみたいところですが、公式のビルド方法にもあるとおり、Boost.RegexとMicrosoft GSL(Guidelines Support Library)とWiX v3 Microsoft Visual Studio 2022 Extensionが必要で、別途ヘルプ開発にはMicrosoft HTLM Help Workshopが必要だそうです。Microsoft HTLM Help Workshopは既に配布が終わっており入手は困難なはずですがhttps://www.helpandmanual.com/downloads_mscomp.htmlここから入手できました。まぁHTMLでヘルプを作成するための古くから存在する地味なツールです。
Boost Regexを導入する
Boost.Regexの導入方法については別記事としてBoost.Regex ライブラリの導入に詳細な手順が記述してありますので、やってみて下さい。ffftpではICU関連の正規表現関数は使いませんが、ICUライブラリをスタティックライブラリとして生成して、ランタイム設定は/MTや/MTdにして生成した後、b2コマンドでlink=static runtime-link=staticとして生成したライブラリを使います。別記事の手順に従えば、デバッグ版としてlibboost_regex-vc143-mt-sgd-x64-1_89.libが生成されます。リリース版はlibboost_regex-vc143-mt-s-x64-1_89.libですね。ICUのビルドで生成したsicudt.lib, sicuuc.lib, sicuin.lib, sicuio.lib, sicutu.lib, sicutest.lib, stestplug.libとsicuucd.lib, sicuind.lib, sicuiod.lib, sicutud.lib, sicutestd.lib, stestplugd.libも必要になります。ffftpのランタイム設定は/MTとか/MTdです。ランタイム設定/MDや/MDdのライブラリと混在して利用することはできません。以下のライブラリ名は同じですが、
sicuuc.lib, sicuin.lib, sicuio.lib, sicutu.lib, sicutest.lib, stestplug.libとsicuucd.lib, sicuind.lib, sicuiod.lib, sicutud.lib, sicutestd.lib, stestplugd.libはランタイム設定を/MTあるいは/MTdである必要があります。
C:\(ffftpのワークスペースルートパス)の下にboost1_89_0のような名前のディレクトリを作り、その中にインクルードファイルが保持されたC:\(Boost.Regexのルートパス)\boostのディレクトリごとをコピーC:\(ffftpのワークスペースルートパス)\boost1_89_0にコピーします。
つまり
- C:\(Boost.Regexのルートパス)\boost
- →C:\(ffftpのワークスペースルートパス)\boost1_89_0\boostが出来上がる。
さらにC:\(Boost.Regexのルートパス)\stageのディレクトリごとをコピーC:\(ffftpのワークスペースルートパス)\boost1_89_0にコピーします。stageの中にはlibというフォルダがあってその中にデバッグ版としてlibboost_regex-vc143-mt-sgd-x64-1_89.libが生成されます。リリース版はlibboost_regex-vc143-mt-s-x64-1_89.libが存在してます。
つまり
- C:\(Boost.Regexのルートパス)\stage
- →C:\(ffftpのワークスペースルートパス)\boost1_89_0\stageが出来上がる。
ICUのライブラリとインクルードファイルも同じようにC:\(ffftpのワークスペースルートパス)の中にICU77ようなフォルダを作ってその中にコピーします。
つまり
- C:\(ICUのルートパス)\icu4c\lib64
- →C:\(ffftpのワークスペースルートパス)\ICU77\lib64が出来上がる。
- C:\(ICUのルートパス)\icu4c\Include
- →C:\(ffftpのワークスペースルートパス)\ICU77\Includeが出来上がる。
上記のようなファイルの再配置をせずに、きちんと相対パスとか絶対パスとかを管理しきれる人で自分で整理する術を持っている人はファイル配置の手順については省略することができ、以下の説明をうまく読み替えて下さい。よくわからない人は上記のようにファイルを配置できたら
C:\(ffftpのルートパス)\ffftp.slnをVisual Studioで開きましょう。
Visual Studioのソリューションエクスプローラからffftpプロジェクトを選択してメニュー[プロジェクト(P)]-[プロパティ]を開きます。構成の[Debug]と[Release]の選択に留意して、
構成のDebugを選択した状態の場合は以下のように設定します。
[構成プロパティ]-[VC++ディレクトリ]の項目[インクルードディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。フォルダ名は各自で調整していいんだよ。ただしく設定できるならね。TESTプロジェクトはffftpプロジェクトのあるフォルダの中にtestフォルダがあってその中にあるからtestプロジェクトから見ると二つ上にあがらなきゃいけないから..\が一つ多いんだよ。
- ffftpプロジェクト→..\boost1_89_0;..\GSL-main\include;
- testプロジェクト→..\..\boost1_89_0;..\..\GSL-main\include;
[構成プロパティ]-[VC++ディレクトリ]の項目[ライブラリディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。
- ffftpプロジェクト→..\boost1_89_0\stage\lib;..\ICU77\lib64\
- testプロジェクト→..\..\boost1_89_0\stage\lib;..\..\ICU77\lib64\;
次に[構成プロパティ]-[リンカー]-[入力]の項目[追加の依存ファイル]に以下を追記
- ffftp/testプロジェクト共通→libboost_regex-vc143-mt-sgd-x64-1_89.lib;sicudt.lib;sicuind.lib;sicuucd.lib;Advapi32.lib;
構成のReleaseを選択した状態の場合は以下のように設定します。
[構成プロパティ]-[VC++ディレクトリ]の項目[インクルードディレクトリ]に以下を追加。
- ffftpプロジェクト→..\boost1_89_0;..\GSL-main\include;
- testプロジェクト→..\..\boost1_89_0;..\..\GSL-main\include;
[構成プロパティ]-[VC++ディレクトリ]の項目[ライブラリディレクトリ]に以下を追加。あとで作業するMicrosoftGSLの分も追加しちゃってます。
- ffftpプロジェクト→..\boost1_89_0\stage\lib;..\ICU77\lib64\
- testプロジェクト→..\..\boost1_89_0\stage\lib;..\..\ICU77\lib64\;
次に[構成プロパティ]-[リンカー]-[入力]の項目[追加の依存ファイル]に以下を追記
- ffftp/testプロジェクト共通→libboost_regex-vc143-mt-s-x64-1_89.lib;sicudt.lib;sicuin.lib;sicuuc.lib;Advapi32.lib;
これでBoost.Regexの設定は完了です。
Microsoft GSL(Guidelines Support Library)を導入する
詳細はMicrosoft GSL(Guidelines Support Library) ライブラリの導入のとおりのやり方なんですけど、C:\(GSLのルートパス)全体をC:\(ffftpのワークスペースルートパス)の下にコピーしましょう。
- C:\(GSLのルートパス)
- →C:\(ffftpのワークスペースルートパス)\GSL-mainが出来上がる。
GSL-mainという名前はGSLのルートパスの末尾のフォルダの名前です。2025年10月現在の規定値と同じにしています。
配置したらOK。BoostRegexの導入手順の中でインクルードディレクトリへの追加作業はしてありましたので、設定は不要です。
GSLの設定は以上で完了です。
WiX v3 Microsoft Visual Studio 2022 Extensionを導入する
WiX v3は簡単なプログラムインストーラーを作るための拡張機能です。
Visual Studioを起動します。スタートアップウィンドウが表示されたら、コードなしで続行っていう部分をクリックしてスタートアップウィンドウを閉じます。スタートアップウィンドウはメニューの[ファイル]-[スタートアップウィンドウ]を選択するとまた表示できます。
メニュー[拡張機能]-[拡張機能の管理]を選択します。メインウィンドウに拡張機能マネージャーというタブが表示されます。このタブの中にある[参照]が選択されている状態で検索の文字を入力するエディットボックスに[WiX]と入力するとトップに表示されますので、[インストール]を押しましょう。
その後しばらくするとインストール処理は完了するので、VisualStudioを再起動しましょう。
以上でWiX v3 Microsoft Visual Studio 2022 Extensionの導入作業は完了です。
ffftpとtestプロジェクトをビルドする
2025年10月現在ではビルドするとエラーがぶわっとたくさん表示されます。参照渡しがうまく変換できないエラーばかりのようです。
例えば、
template static inline auto Message(HWND owner, int textId, DWORD style) noexcept { MSGBOXPARAMSW msgBoxParams{ sizeof MSGBOXPARAMSW, owner, GetFtpInst(), MAKEINTRESOURCEW(textId), MAKEINTRESOURCEW(captionId), style, nullptr, 0, nullptr, LANG_NEUTRAL }; return MessageBoxIndirectW(&msgBoxParams); }
のsizeof MSGBOXPARAMSWをsizeof(MSGBOXPARAMSW)にして
template static inline auto Message(HWND owner, int textId, DWORD style) noexcept { MSGBOXPARAMSW msgBoxParams{ sizeof(MSGBOXPARAMSW), owner, GetFtpInst(), MAKEINTRESOURCEW(textId), MAKEINTRESOURCEW(captionId), style, nullptr, 0, nullptr, LANG_NEUTRAL }; return MessageBoxIndirectW(&msgBoxParams); }
としなきゃだめだったりしましたし、
例えばconnect.cppの場合は以下のような修正が必要でした。
std::make_wformat_args(User, (wchar_t)FwallDelimiter, Host, Port)
という関数が引数として与えられている箇所では、いったんFwallDelimiterをwchar_t型の変数に格納して、
wchar_t delim = gsl::narrow_cast(FwallDelimiter);
として
std::make_wformat_args(User, delim, Host, Port)
のようにするといいです。gsl関連のキャストエラーも出るので、上記のようにキャストしておくといいです。
他にもtoolmenu.cppでは
auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(MakeSizeString(Size))) : L""s;
という部分のMakeSizeString(Size)が参照渡しエラーになっていて
std::wstring tmptext2 = MakeSizeString(Size);
のように同じように、いったんstd::wstring型の変数に格納してあげたりします。
statuswin.cppでは
//2025/10/10 修正
std::wstring tmptext;
if (GetDiskFreeSpaceExW(directory.c_str(), &a, nullptr, nullptr) != 0) {
tmptext = MakeSizeString(a.QuadPart);
}
else {
tmptext = L"??";
}
auto const text = std::vformat(format, std::make_wformat_args(tmptext));
//auto const text = std::vformat(format, std::make_wformat_args(GetDiskFreeSpaceExW(directory.c_str(), &a, nullptr, nullptr) != 0 ? MakeSizeString(a.QuadPart) : L"??"s));
だったり
//2025/10/10 修正
int num = AskTransferFileNum();
auto const text = std::vformat(format, std::make_wformat_args(num));
//auto const text = std::vformat(format, std::make_wformat_args(AskTransferFileNum()));
だったり
//2025/10/10 修正
std::wstring tmptext2 = MakeSizeString(Size);
auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(tmptext2)) : L""s;
//auto const text = 0 <= Size ? std::vformat(format, std::make_wformat_args(MakeSizeString(Size))) : L""s;
といった修正をしました。
toolmenu.cppでは
//2025/10/10 修正
int num = i + 1;
auto text = std::vformat(format, std::make_wformat_args(fs::path{ ViewerName[i] }.filename().native(), num));
//auto text = std::vformat(format, std::make_wformat_args(fs::path{ ViewerName[i] }.filename().native(), i + 1));
という修正をしました。いったん何らかの変数に代入しないと解決できない感じのが多かったな。
ftpproc.cppでは無意味になっているコードがあって
if (f.InfoExist & FINFO_SIZE) { // サイズ情報がある場合のみ
CalcExtentSize(&Pkt, f.Size);
}
// int const a = f.InfoExist && FINFO_SIZE;
// CalcExtentSize(&Pkt, f.Size);
という修正も必要だったりしました。これはうっかりバグの類でのこっていたので、管理人のSayuri氏に報告しておきました。やりたっかことはこうじゃないか?っていう予想です。TANDEM(現 HPE NonStop シリーズ)は、銀行や証券などの高信頼性向けサーバでOSにOpen System ServicesというOSSを使っているときの、ファイルサイズ再計算処理をしたいときの処理で、ほとんどの人には関係しない部分の動作です。関係者が仕事でそういうサーバと向き合ったりしたときに要望があったり、自分で発見したりして、追加したコードなのかもしれませんね。
そんなところでした。また時間が経過すると修正されたり、動かなくなる部分が増えたりするのかもしれません。
総括
問題なくビルドできました。またひとつ制覇したことになります。自分にできたということは誰にでもできる指標になります。是非、暇な人はトライしてみて欲しいですね。動かしてソースを理解し、知識を習得しましょう。
時事情報
やってみたらうまくいかないことはよくあります。ここで注意すべき事で気づいた点を勝手に記述して残しておくという非協力的な記事です。
言語と開発環境に戻る。