diff options
| author | ruki <[email protected]> | 2026-04-05 17:21:30 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-05 17:21:30 +0800 |
| commit | 4a13e671f0ba99feca8daf4a1706e9bcb4ccfa67 (patch) | |
| tree | 24c57eb099605c9b10e322fdf648f2ba96d4886e | |
| parent | 95e7d1658cb820accdc1bea5c79562331be9baf7 (diff) | |
| parent | 9b189a6f1098e55c4ea6d1928644bed4acf5a412 (diff) | |
Merge pull request #7451 from Akaps316/codex/fix-ios-framework-rpath
fix(xcode.application): use the correct framework rpath for iOS apps
8 files changed, 102 insertions, 0 deletions
diff --git a/tests/projects/objc/iosapp_framework_rpath/src/app/Info.plist b/tests/projects/objc/iosapp_framework_rpath/src/app/Info.plist new file mode 100644 index 000000000..64e1f01a8 --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/src/app/Info.plist @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>demo</string> + <key>CFBundleIdentifier</key> + <string>io.xmake.demo.ios</string> + <key>CFBundleName</key> + <string>demo</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>UIApplicationSceneManifest</key> + <dict/> +</dict> +</plist> diff --git a/tests/projects/objc/iosapp_framework_rpath/src/app/main.m b/tests/projects/objc/iosapp_framework_rpath/src/app/main.m new file mode 100644 index 000000000..44183e7aa --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/src/app/main.m @@ -0,0 +1,13 @@ +#import <UIKit/UIKit.h> +#import <test/test.h> + +@interface AppDelegate : UIResponder <UIApplicationDelegate> +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation AppDelegate +@end + +int main(int argc, char *argv[]) { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])) + test_value(); +} diff --git a/tests/projects/objc/iosapp_framework_rpath/src/framework/Info.plist b/tests/projects/objc/iosapp_framework_rpath/src/framework/Info.plist new file mode 100644 index 000000000..0f3689457 --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/src/framework/Info.plist @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>test</string> + <key>CFBundleIdentifier</key> + <string>io.xmake.test.framework</string> + <key>CFBundleName</key> + <string>test</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> +</dict> +</plist> diff --git a/tests/projects/objc/iosapp_framework_rpath/src/framework/test.h b/tests/projects/objc/iosapp_framework_rpath/src/framework/test.h new file mode 100644 index 000000000..91434eb54 --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/src/framework/test.h @@ -0,0 +1,3 @@ +#import <Foundation/Foundation.h> + +FOUNDATION_EXPORT int test_value(void); diff --git a/tests/projects/objc/iosapp_framework_rpath/src/framework/test.m b/tests/projects/objc/iosapp_framework_rpath/src/framework/test.m new file mode 100644 index 000000000..7b8c414be --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/src/framework/test.m @@ -0,0 +1,3 @@ +int test_value(void) { + return 7; +} diff --git a/tests/projects/objc/iosapp_framework_rpath/test.lua b/tests/projects/objc/iosapp_framework_rpath/test.lua new file mode 100644 index 000000000..efc69dbea --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/test.lua @@ -0,0 +1,30 @@ +import("utils.binary.rpath") + +function main(t) + if not is_host("macosx") then + return t:skip("wrong host platform") + end + + os.execv("xmake", {"f", "-p", "iphoneos", "-a", "arm64", "--appledev=simulator", "-c"}) + os.execv("xmake", {"-vD"}) + local appfile = "build/iphoneos/arm64/release/demo.app/demo" + local rpaths = rpath.list(appfile) + local found_ios = false + local found_macos = false + if rpaths then + for _, p in ipairs(rpaths) do + if p == "@executable_path/Frameworks" then + found_ios = true + end + if p == "@executable_path/../Frameworks" then + found_macos = true + end + end + end + if not found_ios then + raise("missing iOS framework rpath @executable_path/Frameworks") + end + if found_macos then + raise("found macOS-style framework rpath in iOS app") + end +end diff --git a/tests/projects/objc/iosapp_framework_rpath/xmake.lua b/tests/projects/objc/iosapp_framework_rpath/xmake.lua new file mode 100644 index 000000000..68d0d7db1 --- /dev/null +++ b/tests/projects/objc/iosapp_framework_rpath/xmake.lua @@ -0,0 +1,13 @@ +add_rules("mode.release", "mode.debug") + +target("test") + add_rules("xcode.framework") + add_files("src/framework/test.m") + add_files("src/framework/Info.plist") + add_headerfiles("src/framework/test.h") + +target("demo") + add_rules("xcode.application") + add_deps("test") + add_files("src/app/*.m") + add_files("src/app/Info.plist") diff --git a/xmake/rules/xcode/application/build.lua b/xmake/rules/xcode/application/build.lua index a393ed76b..d55d71a9c 100644 --- a/xmake/rules/xcode/application/build.lua +++ b/xmake/rules/xcode/application/build.lua @@ -50,6 +50,8 @@ function main (target, opt) -- @see https://github.com/xmake-io/xmake/issues/2679#issuecomment-1221839215 local targetfile = path.join(binarydir, path.filename(target:targetfile())) try { function () os.vrunv("install_name_tool", {"-delete_rpath", "@loader_path", targetfile}) end } + -- macOS uses @executable_path/../Frameworks due to Contents/MacOS/ layout + -- iOS/watchOS/tvOS/visionOS use flat bundle layout where frameworks are in the same directory as the executable local rpath = target:is_plat("macosx") and "@executable_path/../Frameworks" or "@executable_path/Frameworks" local rpathdirs = rpath_utils.list(targetfile, {plat = target:plat(), arch = target:arch()}) or {} if not table.contains(rpathdirs, rpath) then |
