例によってまた需要があるか分からない記事を.
某氏にoFでC++17のビルドが通らない, と聞かれやってみた次第.
環境は
- macOS 10.13.6
- Xcode 10.1
- oF 0.10.1 osx release
LinuxとかWinでは確認してないので悪しからず.
後述するけど特にwinはパッチを無視したりするので(多分大丈夫な気はするけど)ちょっと怪しい.
TL;DR
取り敢えずビルド通ったけどまだ要検証.
イントロ
oF自体C++11以降のことはそんなに考えられてなくてでも filesystem
を使いたいからとC++17以前の場合は boost::filesystem
を std::filesystem
のエイリアスにする, とかという本当にそれ大丈夫なのかっていうことやってるわけですが, そういうこと書いてあるからC++17は大丈夫だろうと思ってました.
で, ビルド通らないと聞いてそこらへんで boost:filesystem
と std::filesystem
の微妙なAPIの違いが出てるのかと思ったけどそうでも無かった.
oFのデフォのboostのバージョン
oFの libs/boost/include/boost/version.hpp
を見てみると
# define BOOST_VERSION 106400
...
# define BOOST_LIB_VERSION "1_64"
とある. つまり1.64. これはoF0.10.0も同じ.
ちなみに0.9.8は1.58だからまったくアップデートされてないわけではない.
boostの1.64のリリースっていつなのかと言うと リリースノート によると, 2017/04/19らしい.
oF0.10.0のリリースは2018/05/07だったらしい. (CHANGELOGのアップデート日より)
その頃にはboostの1.65(2017/08/21), 1.66(2017/12/18)は出てたはずだけど差し変えたらまた検証要るしoFもそこまで最新を求めてるフレームワークではないので仕方ないですね.
色々書いたけど本題に.
結局何が問題だったかというと, boost 1.64ではまだ内部的に std::auto_ptr
が使われてるんですね.
多分問題点はそれだけ. (ちゃんとエラーログ大量に出すぎてたので全部見たわけでは無い)
で, 自分で std::auto_ptr
を差し替えるのも嫌だし2019/02/19現在で最新のboost 1.69(2018/12/12) に差し替えようと.
差し替え準備
そうなると今までよく分からない気がして避けて来た apothecary を使うのが多分正攻法なので使ってみた.
- 取り敢えず最新のzipをダウンロード.
- 差し替えるのも怖いのでoF0.10.1環境をもう一個別で作ってそこのscriptsに.
- gitのmasterブランチ使ってる場合と揃えた
これで OF_DIR/scripts/apothecary
という状態に.
apothecaryレポジトリのトップのREADME見ても使い方がいまいちピンと来ないんだけど, apothecary/apothecary/README.md
はちゃんと書いてあったので結構すんなり出来た.
依存パッケージのインストール
apothecary/scripts/osx/install.sh
があるのでこれ叩けば良いはず.
(昔試したのか普通に必要で入れてるのか分からないけど今回は何もせずに動いたので動かしてない)
boostのバージョン指定からのビルド
boostのバージョンは1.64に指定されてるのでまずはそれを編集.
apothecary/apothecary/formulas/boost/boost.sh
の 11行目の VERSION=1.64.0
を VERSION=1.69.0
に修正.
ビルド
cd OF_DIR/scripts/apothecary/apothecary
./apothecary update boost
を実行するとboostのソースをダウンロードしてきてビルドが始まるので待つ.
失敗
なんかパッチ出来ないって怒られた. visualc.hpp.patch
のせいなので今回はwindowsは知らないので無視する.
もっかい boost.sh
を開いて 45行目,
...
function prepare() {
patch -p0 -u < $FORMULA_DIR/visualc.hpp.patch
...
をコメントアウト.
...
function prepare() {
# patch -p0 -u < $FORMULA_DIR/visualc.hpp.patch
...
もっかいビルドをやり直し.
cd OF_DIR/scripts/apothecary/apothecary
./apothecary update boost
成功
出来た.
これだけだと差し変わってないので出来上がった scripts/apothecary/boost
を libs/boost
と差し替え.
意気揚々と libs/openFrameworksCompiled/project/osx/openFrameworksLib
プロジェクトを開いて C++ Language Dialect
を C++17に設定してビルド.
そして失敗.
エラーは何かと見ると std::ptr_fun
とか無いよ, と.
ということで,
-
ofLog.cpp
-
std::ptr_fun(noopDeleter)
をstd::function<void(ofBaseLoggerChannel*)>(noopDeleter)
-
-
ofAppRunner.h
-
std::ptr_fun(noopDeleter)
をstd::function<void(Window*)>(noopDeleter<Window>)
-
に修正. もっかいビルド.
追記 (2019/02/25)
上の修正を本家にPR投げてマージされたので恐らく0.10.2からは ptr_fun
は無くなるはず.
成功
ということで適当なプロジェクトを作って
# include "ofMain.h"
class ofApp : public ofBaseApp {
public:
void setup() {
std::string str = "hoge";
auto p = std::make_pair(1, str);
auto [x, y] = p;
std::cout << x << ", " << y << std::endl;
ofExit();
}
};
int main() {
ofGLFWWindowSettings setting;
# if 10 <= OF_VERSION_MINOR
setting.setSize(1280, 720);
# else
setting.width = 1280;
setting.height = 720;
# endif
auto window = ofCreateWindow(setting);
auto app = std::make_shared<ofApp>();
ofRunApp(window, app);
ofRunMainLoop();
}
こんなコードをビルド.
成功!と思いきや.
やったー!と思ってちゃんと見るとプロジェクトの C++ Language Dialect
が C++11
のままじゃん?このくらいなら Decomposition declarations are a C++17 extension
って警告吐いて動くのね... あと他の警告も無茶出てる.
ということで一旦他の警告は無視して C++17
に設定してビルド.
無事成功.
1, hoge
って出力された.
他のwarning
direct access in function 'boost::system::detail::system_error_category::default_error_condition(int) const' from file '../../../libs/boost/lib/osx/boost_filesystem.a(operations.o)' to global weak symbol 'boost::system::detail::is_generic_value(int)::gen' from file '(中略)/Build/Intermediates.noindex/Cpp17_test_0_10_1.build/Debug/Cpp17_test_0_10_1.build/Objects-normal/x86_64/ofApp.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
色々調べてみると Build Settings の Symbol Hidden by Default
がboostのビルド時と違うらしい.
ので Symbol Hidden by Default
を YES
にしてみたら消えた.
この警告の意味がまだよく理解出来てないのでboostのビルド時の設定を変えるべきか上の修正をすべきか分からない.
ので要調査.
締め
ちゃんと使うには最後の Symbol Hidden by Default
の問題を理解するまでお預けかな...