この前の記事で、cmake のプロジェクトで cocoa の framework を作成するオプションを見つけたので試してみる。
framework の生成
必ずしも info.plist は必須ではないようだ。
サンプルのうち、以下のように info.plist と CODE_SIGN の部分を潰しても framework は生成される。
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(TestFramework C)
add_libraryFr(TestFamework SHARED
TestFramework.h
TestFramework.c)
set_target_properties(TestFramework PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION C
MACOSX_FRAMEWORK_IDENTIFIER com.akiba.TestFramework
#MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
# "current version" in semantic format in Mach-O binary file
#VERSION 16.4.0
# "compatibility version" in semantic format in Mach-O binary file
#SOVERSION 1.0.0
PUBLIC_HEADER TestFramework.h
#XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Developer ID Application: Taro Akiba(123xxx789)"
)
この状態で
cmake -S . -B build
としても Makefile は生成される。もちろん make で TestFramework.framework も生成される。生成するだけならば
FRAMEWORK TRUE
とするだけでいいようだ。
生成された framework を使ってみる
とりあえずお試しなので TestFramework.h と TestFramework.c は以下のような簡単なものにした。
TestFramework.h
#ifndef TESTFRAMEWORK_H
#define TESTFRAMEWORK_H
int twice(int);
#endif
TestFramework.c
#include <stdio.h>
#include "TestFramework.h"
int twice(int n) {
return 2*n;
}
これで、cmake を走らせると確かに TestFramework.framework はできている。
次に Xcode で別のプロジェクトを作成して TestFramework.framework を取り込む。
main.m から以下のように使う。
#import <Foundation/Foundation.h>
#import <TestFramework/TestFramework.h>
int main(int argc, const char * argv[]) {
NSLog(@"%2d",twice(3));
return 0;
}
走らせてみると・・
予想通り 6 と表示してくれました。
成功、成功。
rpath の設定
なお、設定にもよるのだが、こうして作成されたコマンドラインプログラムを(Xcode 上ではなくて)ターミナルから実行すると
Library not loaded: @rpath
というエラーが出る時がある。
このエラーは、コンパイル時の @rpath の設定が実際に生成されたプログラムが参照すべきライブラリ(今回は TestFramework)の path と一致していない時に発生する。
その場合は、Xcode の Runpath Search Paths あたりの設定を見直してください。
ここ、指定しておかないと framework の所定の置き場所しか見に行かないようです。
正しく設定できていれば、ターミナル上からも
と Xcode 環境で走らせた時と同様の結果になります。