月別アーカイブ: 2021年2月

macOS Big Sur 11.2.1

M1 Mac の Big Sur を 11.2.1 にアップデート。
やっぱりか、また Command Line Tools が削除されてしまった。

Command Line Tools reinstall | Paepoi Blog

dmg を残しておいて良かった。
多分 Xcode のほうに入っている奴しか見ていないんだろうな。
JXA の NSMakeRect バグについてはもうあきらめているよ。

Clang を再びインストールした所で、前回の続き。

起動すると林檎メニューにもアクセスできないじゃん。
多分 activateIgnoringOtherApps がずっと働いているっぽい。
PyObjC はインタプリタのおかげでメソッドを抜けているのかな。
main 関数内じゃだめだ、デリゲートのハンドラ内に移動する。

#import <Cocoa/Cocoa.h>

// clang app.m -framework Cocoa

@interface AppMenu : NSMenu
@end

@interface AppDelegate : NSObject<NSApplicationDelegate>
@end

@implementation AppDelegate
- (id) init {
    [super init];
    return self;
}
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification{
    NSLog(@"applicationDidFinishLaunching");
    id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200)
        styleMask:NSWindowStyleMaskTitled
        backing:NSBackingStoreBuffered
        defer:NO] autorelease];
    [window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
    [window setTitle:@"日本語"];
    [window makeKeyAndOrderFront:nil];
    //
    // App Active
    //
    [NSApp activateIgnoringOtherApps:YES];
}
@end

@implementation AppMenu
- (id) init {
    [super init];
    id item_app = [[NSMenuItem new] autorelease];
    [self addItem:item_app];
    id menu_app = [[NSMenu new] autorelease];
    [item_app setSubmenu:menu_app];
    id item_quit = [[NSMenuItem new] autorelease];
    [item_quit initWithTitle:@"Quit App" action:@selector(terminate:) keyEquivalent:@"q"];
    [menu_app addItem:item_quit];
    return self;
}
@end

int main(int argc, char *argv[]) {
    // ガベージコレクションではないのでコレを利用
    [NSAutoreleasePool new];
    // NSApp を作る
    [NSApplication sharedApplication];
    // C ではコレが必須だった
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    // command+Q で終了するメニューを入れる
    id main_menu = [[AppMenu new] autorelease];
    [NSApp setMainMenu:main_menu];
    // Delegate に activateIgnoringOtherApps を移動
    id delegate = [[AppDelegate new] autorelease];
    [NSApp setDelegate:delegate];
    // No!!!
    //[NSApp activateIgnoringOtherApps:YES];
    // メインループを回す
    [NSApp run];
    //
    return 0;
}

app

上手くいったのでウインドウも追加。
前回みたいなコードは世界中で見つかるけど誰もこのこと書いていない。

それにしても。
PyObjC や PyGObject って本当に簡単だなって。

NSApp

Objective-c のコードだけで NSApp を作るソースを作成。
って以前 PyObjC で作ったんだから Objective-c に書き戻すだけだ。

NSApplication – Paepoi

と思ったんだけど動かない、何故だ?
検索しまくって以下のページを見つけた。

Minimalist Cocoa programming

setActivationPolicy を追加したらなんとか動くようになった。
逆に PyObjC は何故いらないんだ?
それとガベージコレクションではないので破棄が必要なんだなこれが。
NSAutoreleasePool という便利なものはこう使うみたい。

#import <Cocoa/Cocoa.h>

// clang app.m -framework Cocoa

@interface AppMenu : NSMenu
//- (id) init; // いらない
@end

@implementation AppMenu
- (id) init {
    [super init];
    id item_app = [[NSMenuItem new] autorelease];
    [self addItem:item_app];
    id menu_app = [[NSMenu new] autorelease];
    [item_app setSubmenu:menu_app];
    id item_quit = [[NSMenuItem new] autorelease];
    [item_quit initWithTitle:@"Quit App" action:@selector(terminate:) keyEquivalent:@"q"];
    [menu_app addItem:item_quit];
    return self;
}
@end

int main(int argc, char *argv[]) {
    // ガベージコレクションではないのでコレを利用
    [NSAutoreleasePool new];
    // NSApp を作る
    [NSApplication sharedApplication];
    // C ではコレが必須だった
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    // command+Q で終了するメニューを入れる
    id main_menu = [[AppMenu new] autorelease];
    [NSApp setMainMenu:main_menu];
    // コレをしないと最前面に出てこない
    [NSApp activateIgnoringOtherApps:YES];
    // メインループを回す
    [NSApp run];
    //
    return 0;
}

a.out

動いたんだけど。。。。。

command+Q は使えるんだけどメニューが選択できない。
一度非アクティブにして再度アクティブ化すればイケるんだけど。
てかリンク元のコードも同じジャン。
PyObjC 版はそんな必要なんて無いのに何故だろう?

どうでもいかもしれないけれど、M1 Mac でビルドしたんだけど。
Silicon Info で確認したらこの a.out は arm64 で動いていた。

ついでに。
SyntaxHighlighter は objective-c ハイライトが無いのね。

BloggerのSyntaxHighlighterでObjective-Cを表示する方法 – menXpon

作っている人がいるってのが有名アプリのいいところ。
筆者の WordPress は自前設置なので scripts に放り込むだけ。
後は Add Code to Head プラグインの設定で以下を追加。

<script type="text/javascript" src="/sh2/scripts/shBrushObjectiveC.js"></script>

プレビュー、よしハイライトできた。
ただ Objective-c なんて今後そんなに使うか疑問なんだけど。

C++14

unary_function は C++11 から非推奨だったのね。
functional – cpprefjp C++日本語リファレンス

std::cout を覚えただけで C++ を簡単みたく書く初心者ブログが多いよね。
筆者の Tips ページはそいつらが見たら絶望するように STL を使っていたり。
なのでワケワカメの代表 unary_function が使えないのは困ったなぁ。
と思ったけどコメントアウトしただけで動くじゃん。

それと auto で便利になったとかも見かける。
いや、class で this を戻すのに auto 指定できるレベルでないとそれほど。
…できるジャン!

// stl.cc
#include <iostream>
#include <vector>
#include <algorithm>

/**
 * Fedora 33
 * g++ stl.cc
 *
 * macOS Big Sur
 * clang++ -std=c++14 stl.cc
 */

/*
 * みんな大好き C++ のテンプレート
 * C++11 より unary_function は非推奨
 * なんだけど、継承する必要が無くなっただけだったり
 */
template <class T>
struct outputfunc { // : public std::unary_function<T, void> {
    void operator()(T obj) {
        std::cout << obj << " ♪♪♪ ";
    }
};

class App {
public:
    App() {
        std::vector<std::string> vec = {"SUZUKIの", "バイクは", "カッコイイ"};
        // 関数オブジェクトにしたけど今は範囲ベース for のほうがいい
        std::for_each(vec.begin(), vec.end(), outputfunc<std::string>());
    }
    ~App() {
        std::cout << std::endl << "今日も元気でね!" << std::endl;
    }
    static auto init() {
        // auto で this を戻せる
        return new App();
    }
};

int
main(int argc, char* argv[]) {
    // イヂワルな初期化
    auto app = App::init();
    delete app;
    return 0;
}

cpp14

macOS ではオプションが必要なのね、c++17 指定でもいい。
for も Python と同じようにできるし、使わない間に随分進化していた。
後は :: と -> が全部ドットになれば、って今更無理だろうな。
たまにしか C++ を触らないとどうしてもソコがね。

C11

C 言語って C99 の後に C11 というのがあるんだね。

C11 (C言語) – Wikipedia

gets を排除なんてどのコンパイラもやらないだろうな。
gets_s なんて Clang も gcc も使えないぞ、cc.exe ただ一つじゃねーの?

しかし gets で検索するとみんな色々書いているけど。。。
GNU Readline ってそんなに無名なんだろうか?

GNU readline | Paepoi Blog

標準入力では一番の選択肢だと思うんだけど、まあ人それぞれ。

char16_t と char32_t 型か、今までどおり wchar_t で問題ないような。
UTF-16 と UTF-32(UCS-4) が混在する場合なんてありえる?

てか

#include <uchar.h>

が macOS では CLang でも gcc でもエラーなんだけど?

macos – OS Xでuchar.hが見つからない – スタック・オーバーフロー

古い質問だけど今もそうなの?
Fedora の gcc だと普通にコンパイルできるんですけど。
U の接頭子ならイケたのでそっちでやってみる。

#include <stdio.h>

int main (int argc, char const* argv[]) {
    printf("wchar size: %lu byte\n", sizeof(L'a'));
    printf("UTF-32(UCS-4) size: %lu byte\n", sizeof(U'a'));
    return 0;
}

utf32

うん、Fedora の gcc も macOS の Clang もオプション無しでイケる。
全部 UTF-32 なのよね、NSString が UTF-16 なのが少し困る。
あっ混在あった、ってそれ相互利用なんてしないと思うけど。

Command Line Tools reinstall

M1 Mac で Clang なんてページを追加する。
って以前書いたけど全然進んでいない、だって。

/Library/Developer/CommandLineTools/usr/bin

が無くなっているって何だよ、clang コマンドはココにあったはず。

usr

記憶が違っているかと色々探したけど見つからない。
同一症状は無いかと検索しまくっても見つからない。

てゆーか macOS Big Sur って本当にバグ多いな。
って、GNOME3 を最初期から使っていた筆者が言うことじゃないな。
よくあることだと開き直って再インストールすりゃいいんだよ。

xcode-select --install

コマンドで最インストールするダイアログが出るけど。。。。。
又消えても困るのでパッケージでダウンロードしておきたい。

Mac OS mojaveに更新したら、xcode-selectが動かなくなったので解決した。 – Qiita

上記を試したら dmg が見つかった。
Command Line Tools for Xcode というのでいいのかな。
12.5 はベータなので今回は 12.4 をダウンロードする。

dl

落とした dmg で command+O すると中身に pkg がある。
pkg を W クリックするとインストーラが立ち上がる。

dialog

m1 Mac なら一分くらいでインストール完了。
親切に dmg をゴミ箱に捨てるか聞いてくるので残す。
dmg をアンマウントして、最初に書いたパスの確認。

bin

やはり筆者の勘違いじゃなくてココに clang があったのね。
又消えてしまっても dmg が残っているからすぐ元通りにできる。

さて問題は Python 3.8 もココに入っていることだ。
以前は Python を公式から最新にしていても巻き戻しされていたのよ。
でも 3.9 のインストーラだと ~/.zprofile で以下のように。

# Setting PATH for Python 3.9
# The original version is saved in .zprofile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.9/bin:${PATH}"
export PATH

/usr/bin の前に Python 3.9 のパスを指定という方法にしたようだ。
UNIX 系では $PATH の順番どおりにコマンドを探すんです。
このおかげで python3 コマンドは Python 3.9 のままになります。