build_apps: Add support for iOS using the existing build_apps infrastructure.

This commit is contained in:
Donny Lawrence
2020-11-27 12:50:36 -06:00
parent 29b178e07e
commit 4051fe6d36
26 changed files with 293 additions and 659 deletions

View File

@@ -124,6 +124,7 @@ option(BUILD_DTOOL "Build the dtool source tree." ON)
option(BUILD_PANDA "Build the panda source tree." ON)
option(BUILD_DIRECT "Build the direct source tree." ON)
option(BUILD_PANDATOOL "Build the pandatool source tree." ON)
option(BUILD_DEPLOYSTUB "Build deploy-stub. Will also be built if BUILD_PANDATOOL is true." ON)
option(BUILD_CONTRIB "Build the contrib source tree." ON)
option(BUILD_MODELS "Build/install the built-in models." ON)
@@ -144,7 +145,7 @@ if(BUILD_DIRECT)
add_subdirectory(direct "${CMAKE_BINARY_DIR}/direct")
endif()
if(BUILD_PANDATOOL)
if(BUILD_PANDATOOL OR BUILD_DEPLOYSTUB)
add_subdirectory(pandatool "${CMAKE_BINARY_DIR}/pandatool")
endif()

View File

@@ -1,3 +1,6 @@
if (IS_IOS)
return()
endif()
add_executable(p3dcparse dcparse.cxx)
target_link_libraries(p3dcparse p3direct)
install(TARGETS p3dcparse EXPORT Direct COMPONENT Direct DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@@ -677,7 +677,7 @@ lc_layouts = {
lc_indices_to_slide = {
b'__PANDA': [4, 6],
b'__LINKEDIT': [3, 5],
LC_DYLD_INFO_ONLY: [2, 4, 8, 10],
LC_DYLD_INFO_ONLY: [2, 4, 6, 8, 10],
LC_SYMTAB: [2, 4],
LC_DYSYMTAB: [14],
LC_FUNCTION_STARTS: [2],
@@ -1801,7 +1801,7 @@ class Freezer:
# trouble importing it as a builtin module. Synthesize a frozen
# module that loads it dynamically.
if '.' in moduleName:
if self.platform.startswith("macosx") and not use_console:
if self.platform.startswith("macosx") or self.platform.startswith("ios") and not use_console:
# We write the Frameworks directory to sys.path[0].
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(sys.path[0], "%s%s"))' % (moduleName, moduleName, moduleName, modext)
else:
@@ -1840,8 +1840,10 @@ class Freezer:
if self.platform.startswith('win'):
# We don't use mmap on Windows. Align just for good measure.
blob_align = 32
elif self.platform.startswith('ios'):
# Align to page size, so that it can be mmapped. Page size is 16KB on iOS, 4KB everywhere else.
blob_align = 16384
else:
# Align to page size, so that it can be mmapped.
blob_align = 4096
# Also determine the total blob size now. Add padding to the end.
@@ -1852,14 +1854,14 @@ class Freezer:
# TODO: Support creating custom sections in universal binaries.
append_blob = True
if self.platform.startswith('macosx') and len(bitnesses) == 1:
if self.platform.startswith('macosx') or self.platform.startswith('ios') and len(bitnesses) == 1:
# If our deploy-stub has a __PANDA segment, we know we're meant to
# put our blob there rather than attach it to the end.
load_commands = self._parse_macho_load_commands(stub_data)
if b'__PANDA' in load_commands.keys():
append_blob = False
if self.platform.startswith("macosx") and not append_blob:
if self.platform.startswith("macosx") or self.platform.startswith('ios') and not append_blob:
# Take this time to shift any Mach-O structures around to fit our
# blob. We don't need to worry about aligning the offset since the
# compiler already took care of that when creating the segment.

View File

@@ -169,6 +169,26 @@ if os.path.isdir(tcl_dir):
del os
"""
# As of April 2020, this is required for apps to be submitted to the App Store.
IOS_LAUNCH_STORYBOARD = u"""
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17700" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
</dependencies>
<scenes>
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
"""
class build_apps(setuptools.Command):
description = 'build Panda3D applications'
@@ -421,6 +441,46 @@ class build_apps(setuptools.Command):
pef.write_changes()
pef.close()
def bundle_ios_app(self, builddir):
appname = '{}.app'.format(self.macos_main_app)
appdir = os.path.join(builddir, appname)
self.announce('Bundling iOS app into {}'.format(appdir),
distutils.log.INFO)
os.makedirs(appdir)
for fname in os.listdir(builddir):
src = os.path.join(builddir, fname)
if appdir in src:
continue
dst = appdir
shutil.move(src, dst)
# Write out Info.plist
plist = {
'CFBundleName': appname,
'CFBundleDisplayName': appname,
# TODO use name from setup.py/cfg
'CFBundleIdentifier': 'com.panda3d.app', # TODO
'CFBundleVersion': '0.0.0', # TODO get from setup.py
'CFBundlePackageType': 'APPL',
'CFBundleSignature': '', # TODO
'CFBundleExecutable': self.macos_main_app,
'UILaunchStoryboardName': 'LaunchScreen'
}
with open(os.path.join(appdir, 'Info.plist'), 'wb') as f:
if hasattr(plistlib, 'dump'):
plistlib.dump(plist, f)
else:
plistlib.writePlist(plist, f)
# Write out the launch screen storyboard.
with open(os.path.join(appdir, 'LaunchScreen.storyboard'), 'w') as f:
f.write(IOS_LAUNCH_STORYBOARD)
def bundle_macos_app(self, builddir):
"""Bundle built runtime into a .app for macOS"""
@@ -650,7 +710,7 @@ class build_apps(setuptools.Command):
target_path = os.path.join(builddir, appname)
stub_name = 'deploy-stub'
if platform.startswith('win') or 'macosx' in platform:
if platform.startswith('win') or platform.startswith('macosx') or platform.startswith('ios'):
if not use_console:
stub_name = 'deploy-stubw'
@@ -699,6 +759,7 @@ class build_apps(setuptools.Command):
search_path = [builddir]
if use_wheels:
search_path.append(os.path.join(p3dwhlfn, 'deploy_libs'))
search_path.append(os.path.join(p3dwhlfn, 'panda3d'))
self.copy_dependencies(target_path, builddir, search_path, stub_name)
freezer_extras.update(freezer.extras)
@@ -921,6 +982,9 @@ class build_apps(setuptools.Command):
if self.macos_main_app and 'macosx' in platform:
self.bundle_macos_app(builddir)
if self.macos_main_app and 'ios' in platform:
self.bundle_ios_app(builddir)
def add_dependency(self, name, target_dir, search_path, referenced_by):
""" Searches for the given DLL on the search path. If it exists,
copies it to the target_dir. """

View File

@@ -1,8 +0,0 @@
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -1,21 +0,0 @@
#import "AppDelegate.h"
#include "PandaViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
PandaViewController *vc = [[PandaViewController alloc] init];
self.window.rootViewController = vc;
[vc startPythonApp:@"${py_module_main}"];
[self.window makeKeyAndVisible];
return YES;
}
@end

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@@ -1,43 +0,0 @@
<?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>CFBundleDevelopmentRegion</key>
<string>$$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -1,8 +0,0 @@
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@@ -1,297 +0,0 @@
// !$$*UTF8*$$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
F1E315CB22DE3C1D009AC9E9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E315CA22DE3C1D009AC9E9 /* AppDelegate.m */; };
F1E315D622DE3C1F009AC9E9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F1E315D422DE3C1F009AC9E9 /* LaunchScreen.storyboard */; };
F1E315D922DE3C1F009AC9E9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E315D822DE3C1F009AC9E9 /* main.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F1E315C622DE3C1D009AC9E9 /* ${app_name}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${app_name}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
F1E315C922DE3C1D009AC9E9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
F1E315CA22DE3C1D009AC9E9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
F1E315D522DE3C1F009AC9E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F1E315D722DE3C1F009AC9E9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F1E315D822DE3C1F009AC9E9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F1E315C322DE3C1D009AC9E9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F1E315BB22DE3B81009AC9E9 = {
isa = PBXGroup;
children = (
F1E315C822DE3C1D009AC9E9 /* ${app_name} */,
F1E315C722DE3C1D009AC9E9 /* Products */,
);
sourceTree = "<group>";
};
F1E315C722DE3C1D009AC9E9 /* Products */ = {
isa = PBXGroup;
children = (
F1E315C622DE3C1D009AC9E9 /* ${app_name}.app */,
);
name = Products;
sourceTree = "<group>";
};
F1E315C822DE3C1D009AC9E9 /* ${app_name} */ = {
isa = PBXGroup;
children = (
F1E315C922DE3C1D009AC9E9 /* AppDelegate.h */,
F1E315CA22DE3C1D009AC9E9 /* AppDelegate.m */,
F1E315D422DE3C1F009AC9E9 /* LaunchScreen.storyboard */,
F1E315D722DE3C1F009AC9E9 /* Info.plist */,
F1E315D822DE3C1F009AC9E9 /* main.m */,
);
path = "${app_name}";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F1E315C522DE3C1D009AC9E9 /* ${app_name} */ = {
isa = PBXNativeTarget;
buildConfigurationList = F1E315DA22DE3C1F009AC9E9 /* Build configuration list for PBXNativeTarget "${app_name}" */;
buildPhases = (
F1E315C222DE3C1D009AC9E9 /* Sources */,
F1E315C322DE3C1D009AC9E9 /* Frameworks */,
F1E315C422DE3C1D009AC9E9 /* Resources */,
F113D35A22EE18EF00640DC0 /* ShellScript */,
F113D38822EE795200640DC0 /* Copy Game Files */,
);
buildRules = (
);
dependencies = (
);
name = "${app_name}";
productName = "${app_name}";
productReference = F1E315C622DE3C1D009AC9E9 /* ${app_name}.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F1E315BC22DE3B81009AC9E9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
TargetAttributes = {
F1E315C522DE3C1D009AC9E9 = {
CreatedOnToolsVersion = 10.2.1;
};
};
};
buildConfigurationList = F1E315BF22DE3B81009AC9E9 /* Build configuration list for PBXProject "panda-app-template" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F1E315BB22DE3B81009AC9E9;
productRefGroup = F1E315C722DE3C1D009AC9E9 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F1E315C522DE3C1D009AC9E9 /* ${app_name} */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F1E315C422DE3C1D009AC9E9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F1E315D622DE3C1F009AC9E9 /* LaunchScreen.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F1E315C222DE3C1D009AC9E9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F1E315D922DE3C1F009AC9E9 /* main.m in Sources */,
F1E315CB22DE3C1D009AC9E9 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F1E315D422DE3C1F009AC9E9 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F1E315D522DE3C1F009AC9E9 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin PBXShellScriptBuildPhase section */
F113D35A22EE18EF00640DC0 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Copy and Sign Library Files";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cp -R \"$$PROJECT_DIR/$$PROJECT_NAME/deploy$$EFFECTIVE_PLATFORM_NAME/\" \"$$BUILT_PRODUCTS_DIR/$$FRAMEWORKS_FOLDER_PATH\"\nfor f in `find -s \"$$BUILT_PRODUCTS_DIR/$$FRAMEWORKS_FOLDER_PATH\" -name \"*.so\" -o -name \"*.dylib\"`; do codesign -s \"$$CODE_SIGN_IDENTITY\" $$f; done\n";
};
F113D38822EE795200640DC0 /* Copy Game Files */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Copy Game Files";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cp -r \"${game_dir}/\" \"$$BUILT_PRODUCTS_DIR/$$WRAPPER_NAME\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin XCBuildConfiguration section */
F1E315C122DE3B81009AC9E9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
F1E315DC22DE3C1F009AC9E9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_BITCODE = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
"HEADER_SEARCH_PATHS[sdk=iphoneos*]" = "$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphoneos/include";
"HEADER_SEARCH_PATHS[sdk=iphonesimulator*]" = "$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphonesimulator/include";
INFOPLIST_FILE = "${app_name}/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = ${deploy_target};
LD_RUNPATH_SEARCH_PATHS = (
"$$(inherited)",
"@executable_path/Frameworks",
"@executable_path/Frameworks/python/lib",
"@executable_path/Frameworks/${sitepackages_dir}/panda3d",
);
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = (
"$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphoneos/python/lib",
"$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphoneos/${sitepackages_dir}/panda3d",
);
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = (
"$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphonesimulator/python/lib",
"$$(PROJECT_DIR)/$$(PROJECT_NAME)/deploy-iphonesimulator/${sitepackages_dir}/panda3d",
);
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_LDFLAGS = "-lpandagles2 -lpython${py_ver}m";
PRODUCT_NAME = "$$(TARGET_NAME)";
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = ${supported_platforms};
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VALID_ARCHS = (
${archs_list},
);
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F1E315BF22DE3B81009AC9E9 /* Build configuration list for PBXProject "panda-app-template" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F1E315C122DE3B81009AC9E9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F1E315DA22DE3C1F009AC9E9 /* Build configuration list for PBXNativeTarget "${app_name}" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F1E315DC22DE3C1F009AC9E9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F1E315BC22DE3B81009AC9E9 /* Project object */;
}

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F1E315C522DE3C1D009AC9E9"
BuildableName = "${app_name}.app"
BlueprintName = "${app_name}"
ReferencedContainer = "container:${app_name}.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F1E315C522DE3C1D009AC9E9"
BuildableName = "${app_name}.app"
BlueprintName = "${app_name}"
ReferencedContainer = "container:${app_name}.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F1E315C522DE3C1D009AC9E9"
BuildableName = "${app_name}.app"
BlueprintName = "${app_name}"
ReferencedContainer = "container:${app_name}.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F1E315C522DE3C1D009AC9E9"
BuildableName = "${app_name}.app"
BlueprintName = "${app_name}"
ReferencedContainer = "container:${app_name}.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -338,10 +338,7 @@ mark_as_advanced(USE_MEMORY_DLMALLOC USE_MEMORY_PTMALLOC2
if(IS_IOS)
set(CMAKE_MACOSX_BUNDLE OFF)
# A bug in CMake (https://gitlab.kitware.com/cmake/cmake/issues/19375) causes
# MACOSX_RPATH to not be respected on iOS.
set(CMAKE_INSTALL_NAME_DIR "@rpath")
set(CMAKE_MACOSX_RPATH ON)
# Check if THIRDPARTY_DIRECTORY is defined, and warn the user if it isn't.
if(NOT THIRDPARTY_DIRECTORY)

View File

@@ -195,8 +195,8 @@ endif()
get_directory_property(_old_cache_vars CACHE_VARIABLES)
if(CMAKE_SYSTEM_NAME MATCHES "iOS")
set(Python_LIBRARY ${Python_ROOT}/Python.framework/libPython.a)
set(Python_INCLUDE_DIR ${Python_ROOT}/Python.framework/Headers)
set(Python_LIBRARY ${Python_ROOT}/lib/libpython3.8.a)
set(Python_INCLUDE_DIR ${Python_ROOT}/include/python3.8)
find_package(Python ${WANT_PYTHON_VERSION} QUIET COMPONENTS Development)
else()
find_package(Python ${WANT_PYTHON_VERSION} QUIET COMPONENTS Interpreter Development)

View File

@@ -1131,7 +1131,7 @@ to_os_specific() const {
Filename standard(*this);
standard.standardize();
#ifdef IS_OSX
#if defined(IS_OSX) || defined(IS_IOS)
if (get_type() == T_dso) {
std::string workname = standard.get_fullpath();
size_t dot = workname.rfind('.');

View File

@@ -124,10 +124,13 @@ reload_implicit_pages() {
const BlobInfo *blobinfo = (const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), "blobinfo");
#elif defined(RTLD_MAIN_ONLY)
const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_MAIN_ONLY, "blobinfo");
void (*load_blobinfo_pointers)() = (void (*)())dlsym(RTLD_MAIN_ONLY, "load_blobinfo_pointers");
//#elif defined(RTLD_SELF)
// const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_SELF, "blobinfo");
#else
const BlobInfo *blobinfo = (const BlobInfo *)dlsym(dlopen(NULL, RTLD_NOW), "blobinfo");
void *handle = dlopen(NULL, RTLD_NOW);
const BlobInfo *blobinfo = (const BlobInfo *)dlsym(handle, "blobinfo");
const void (*load_blobinfo_pointers)() = dlsym(handle, "load_blobinfo_pointers");
#endif
if (blobinfo == nullptr) {
#ifndef _WIN32
@@ -139,6 +142,9 @@ reload_implicit_pages() {
}
if (blobinfo != nullptr) {
if (blobinfo->module_table == nullptr) {
load_blobinfo_pointers();
}
if (blobinfo->num_pointers >= 11 && blobinfo->main_dir != nullptr) {
ExecutionEnvironment::set_environment_variable("MAIN_DIR", blobinfo->main_dir);
} else {

View File

@@ -144,7 +144,8 @@ class TargetInfo:
soabi='',
python_version=None,
python_root=sys.exec_prefix,
sys_platform=get_host()):
sys_platform=get_host(),
static_panda=False):
"""
With no arguments, it will be assumed that the target is the same as the
host (which will be most cases).
@@ -174,6 +175,7 @@ class TargetInfo:
self.python_version = python_version
self.python_root = python_root
self.sys_platform = sys_platform
self.static_panda = static_panda
self.platform_tag = self.platform_tag.replace('-', '_').replace('.', '_')
@@ -234,7 +236,7 @@ class TargetInfo:
@property
def extension_suffix(self):
if 'ios' in self.platform_tag:
return '.so'
return '.a' if self.static_panda else '.so'
if self.soabi != '':
ext = '.pyd' if self.sys_platform == 'win32' else '.so'
return '.' + self.soabi + ext
@@ -698,6 +700,8 @@ def makewheel(version, output_dir, target_info):
if sys.version_info < (3, 5):
raise Exception("Python 3.5 is required to produce a wheel.")
platform = target_info.platform_tag
if platform is None:
# Determine the platform from the build.
platform_dat = os.path.join(output_dir, 'tmp', 'platform.dat')
@@ -794,11 +798,12 @@ if __debug__:
ext_suffix = target_info.extension_suffix
for file in os.listdir(panda3d_dir):
module_dir = libs_dir if target_info.static_panda else panda3d_dir
for file in os.listdir(module_dir):
if file == '__init__.py':
pass
elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]):
source_path = os.path.join(panda3d_dir, file)
elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]) or file.startswith('libpy'):
source_path = os.path.join(module_dir, file)
if file.endswith('.pyd') and target_info.sys_platform == 'cygwin':
# Rename it to .dll for cygwin Python to be able to load it.
@@ -810,7 +815,11 @@ if __debug__:
# And copy the extension modules from the Python installation into the
# deploy_libs directory, for use by deploy-ng.
ext_suffix = '.pyd' if target_info.sys_platform in ('win32', 'cygwin') else '.so'
if target_info.static_panda:
ext_suffix = '.lib' if target_info.sys_platform in ('win32', 'cygwin') else '.a'
else:
ext_suffix = '.pyd' if target_info.sys_platform in ('win32', 'cygwin') else '.so'
ext_mod_dir = target_info.python_ext_module_dir
if not 'ios' in target_info.platform_tag:
@@ -826,20 +835,15 @@ if __debug__:
whl.write_file(target_path, source_path)
if 'ios' in target_info.platform_tag:
# Copy over the PandaViewController.h header file.
include_dir = join(output_dir, 'include/panda3d')
whl.write_file('deploy_libs/include/PandaViewController.h', join(include_dir, 'PandaViewController.h'))
# Add plug-ins.
for lib in PLUGIN_LIBS:
plugin_name = 'lib' + lib
if target_info.sys_platform in ('win32', 'cygwin'):
plugin_name += '.dll'
plugin_name += '.lib' if target_info.static_panda else '.dll'
elif target_info.sys_platform in ('darwin', 'ios'):
plugin_name += '.dylib'
plugin_name += '.a' if target_info.static_panda else '.dylib'
else:
plugin_name += '.so'
plugin_name += '.a' if target_info.static_panda else '.so'
plugin_path = os.path.join(libs_dir, plugin_name)
if os.path.isfile(plugin_path):
whl.write_file('panda3d/' + plugin_name, plugin_path)
@@ -924,10 +928,10 @@ if __debug__:
else:
raise Exception('Platform string does not specify one of ' + archs)
python_dir = os.path.abspath(join('thirdparty', 'ios-libs-%s' % arch, 'python', 'lib'))
python_dir = target_info.python_root
pylib_name = ''
for filename in os.listdir(python_dir):
if os.path.isfile(os.path.join(python_dir, filename)) and 'libpython' in filename and filename.endswith('dylib'):
if os.path.isfile(os.path.join(python_dir, filename)) and 'libpython' in filename:
pylib_name = filename
pylib_path = join(python_dir, pylib_name)
else:
@@ -958,9 +962,10 @@ if __name__ == "__main__":
parser.add_option('', '--pyver', dest = 'python_version', help = 'Custom Python version we\'re making the wheel for.')
parser.add_option('', '--pyroot', dest = 'python_root', help = 'Custom root of Python installation.', default = sys.exec_prefix)
parser.add_option('', '--sysplatform', dest = 'sys_platform', help = 'Output of "sys.platform" on the target', default = get_host())
parser.add_option('', '--static', dest = 'static_panda', help = 'If the Panda libraries we\'re packaging are statically linked', action = 'store_true', default = False)
(options, args) = parser.parse_args()
ti_opts = {key: options.__dict__[key] for key in ('platform_tag', 'soabi', 'python_version', 'python_root', 'sys_platform')}
ti_opts = {key: options.__dict__[key] for key in ('platform_tag', 'soabi', 'python_version', 'python_root', 'sys_platform', 'static_panda')}
target_info = TargetInfo(**ti_opts)
global verbose

View File

@@ -35,6 +35,7 @@ add_subdirectory(src/glxdisplay)
add_subdirectory(src/gobj)
add_subdirectory(src/grutil)
add_subdirectory(src/gsgbase)
add_subdirectory(src/ios)
add_subdirectory(src/linmath)
add_subdirectory(src/mathutil)
add_subdirectory(src/movies)

View File

@@ -20,6 +20,10 @@ if(HAVE_FREETYPE)
list(APPEND PANDA_LINK_TARGETS p3pnmtext)
endif()
# if(IS_IOS)
# list(APPEND PANDA_LINK_TARGETS p3ios)
# endif()
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel")
add_metalib(panda INIT init_libpanda panda.h COMPONENTS ${PANDA_LINK_TARGETS})
unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)

View File

@@ -22,13 +22,6 @@ add_metalib(pandagles2 ${MODULE_TYPE}
COMPONENTS ${PANDAGLES2_LINK_TARGETS})
unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
# We won't be linking with libpython until the wrapper app itself is built,
# so we'll quelch the errors that get spit out when trying to build with
# missing symbols.
target_link_options(pandagles2 PRIVATE -undefined dynamic_lookup)
endif()
install(TARGETS pandagles2
EXPORT OpenGLES2 COMPONENT OpenGLES2
DESTINATION ${MODULE_DESTINATION}

View File

@@ -2,6 +2,7 @@
################################# DO NOT EDIT ###########################
# Some paths first...
$<$<NOT:$<PLATFORM_ID:iOS>>:#> plugin-path $MAIN_DIR
plugin-path $THIS_PRC_DIR/${PLUGINS_PATH}
model-path $MAIN_DIR
model-path $THIS_PRC_DIR/${MODELS_PARENT_PATH}

View File

@@ -9,7 +9,6 @@ set(P3EAGLDISPLAY_HEADERS
eaglGraphicsWindow.h eaglGraphicsWindow.I
eaglGraphicsBuffer.h
pandaEAGLView.h
PandaViewController.h
)
set(P3EAGLDISPLAY_SOURCES
@@ -19,7 +18,6 @@ set(P3EAGLDISPLAY_SOURCES
eaglGraphicsWindow.mm
eaglGraphicsBuffer.mm
pandaEAGLView.mm
PandaViewController.mm
)
composite_sources(p3eagldisplay P3EAGLDISPLAY_SOURCES)
@@ -27,7 +25,6 @@ add_component_library(p3eagldisplay SYMBOL BUILDING_PANDA_EAGLDISPLAY
${P3EAGLDISPLAY_HEADERS} ${P3EAGLDISPLAY_SOURCES})
target_link_libraries(p3eagldisplay p3gles2gsg panda)
target_include_directories(p3eagldisplay PUBLIC ${PYTHON_INCLUDE_DIRS})
target_compile_options(p3eagldisplay PRIVATE -fobjc-arc)
# Frameworks:
@@ -38,4 +35,4 @@ target_link_libraries(p3eagldisplay ${UIKIT_LIBRARY} ${QUARTZCORE_LIBRARY})
if(NOT BUILD_METALIBS)
install(TARGETS p3eagldisplay EXPORT GLES COMPONENT GLES DESTINATION lib)
endif()
install(FILES ${P3EAGLDISPLAY_HEADERS} COMPONENT GLES DESTINATION include/panda3d)
install(FILES ${P3EAGLDISPLAY_HEADERS} COMPONENT GLES DESTINATION include/panda3d)

View File

@@ -29,10 +29,6 @@ class EAGLGraphicsStateGuardian;
*/
class EAGLGraphicsWindow : public GraphicsWindow {
public:
static PandaViewController *next_view_controller;
static TrueMutexImpl vc_lock;
static TrueConditionVarImpl vc_condition;
EAGLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
const std::string &name,
const FrameBufferProperties &fb_prop,

View File

@@ -23,10 +23,6 @@
TypeHandle EAGLGraphicsWindow::_type_handle;
PandaViewController *EAGLGraphicsWindow::next_view_controller = nil;
TrueMutexImpl EAGLGraphicsWindow::vc_lock;
TrueConditionVarImpl EAGLGraphicsWindow::vc_condition = TrueConditionVarImpl(EAGLGraphicsWindow::vc_lock);
// See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
// for what this is doing. Since UITouches don't come with an ID (or any member
// that can meaningfully be converted to one), we can attach our own using the
@@ -177,24 +173,14 @@ open_window() {
// reset the GSG before it tries to use it.
eaglgsg->lock_context();
// Create the view we're going to render into, and attach it to the supplied
// view controller if given.
PandaViewController *vc = EAGLGraphicsWindow::next_view_controller;
dispatch_sync(dispatch_get_main_queue(), ^{
CGRect frame = vc ? vc.view.frame : UIScreen.mainScreen.bounds;
_view = [[PandaEAGLView alloc] initWithFrame:frame graphicsWindow:this];
UIWindow *main_window = UIApplication.sharedApplication.windows[0];
_view = [[PandaEAGLView alloc] initWithFrame:main_window.frame graphicsWindow:this];
main_window.rootViewController.view = _view;
_backing_buffer->_layer = _view.layer;
_properties.set_size(frame.size.width, frame.size.height);
if (vc) {
vc.view = _view;
}
_properties.set_size(_view.frame.size.width, _view.frame.size.height);
});
EAGLGraphicsWindow::next_view_controller = nil;
EAGLGraphicsWindow::vc_lock.lock();
EAGLGraphicsWindow::vc_condition.notify();
EAGLGraphicsWindow::vc_lock.unlock();
[EAGLContext setCurrentContext:eaglgsg->_context];
eaglgsg->reset_if_new();

View File

@@ -2,48 +2,51 @@ if(NOT BUILD_PANDA)
message(FATAL_ERROR "Cannot build pandatool without panda! Please enable the BUILD_PANDA option.")
endif()
# Include pandatool source directories
add_subdirectory(src/assimp)
add_subdirectory(src/bam)
add_subdirectory(src/converter)
add_subdirectory(src/daeegg)
add_subdirectory(src/daeprogs)
if(BUILD_PANDATOOL)
# Include pandatool source directories
add_subdirectory(src/assimp)
add_subdirectory(src/bam)
add_subdirectory(src/converter)
add_subdirectory(src/daeegg)
add_subdirectory(src/daeprogs)
add_subdirectory(src/dxf)
add_subdirectory(src/dxfegg)
add_subdirectory(src/dxfprogs)
add_subdirectory(src/eggbase)
add_subdirectory(src/eggcharbase)
add_subdirectory(src/eggprogs)
add_subdirectory(src/egg-mkfont)
add_subdirectory(src/egg-optchar)
add_subdirectory(src/egg-palettize)
add_subdirectory(src/egg-qtess)
add_subdirectory(src/flt)
add_subdirectory(src/fltegg)
add_subdirectory(src/fltprogs)
add_subdirectory(src/gtk-stats)
add_subdirectory(src/imagebase)
add_subdirectory(src/imageprogs)
add_subdirectory(src/lwo)
add_subdirectory(src/lwoegg)
add_subdirectory(src/lwoprogs)
add_subdirectory(src/miscprogs)
add_subdirectory(src/objegg)
add_subdirectory(src/objprogs)
add_subdirectory(src/palettizer)
add_subdirectory(src/pandatoolbase)
add_subdirectory(src/pfmprogs)
add_subdirectory(src/progbase)
add_subdirectory(src/pstatserver)
add_subdirectory(src/ptloader)
add_subdirectory(src/text-stats)
add_subdirectory(src/vrml)
add_subdirectory(src/vrmlegg)
add_subdirectory(src/vrmlprogs)
add_subdirectory(src/win-stats)
add_subdirectory(src/xfile)
add_subdirectory(src/xfileegg)
add_subdirectory(src/xfileprogs)
endif()
add_subdirectory(src/deploy-stub)
add_subdirectory(src/dxf)
add_subdirectory(src/dxfegg)
add_subdirectory(src/dxfprogs)
add_subdirectory(src/eggbase)
add_subdirectory(src/eggcharbase)
add_subdirectory(src/eggprogs)
add_subdirectory(src/egg-mkfont)
add_subdirectory(src/egg-optchar)
add_subdirectory(src/egg-palettize)
add_subdirectory(src/egg-qtess)
add_subdirectory(src/flt)
add_subdirectory(src/fltegg)
add_subdirectory(src/fltprogs)
add_subdirectory(src/gtk-stats)
add_subdirectory(src/imagebase)
add_subdirectory(src/imageprogs)
add_subdirectory(src/lwo)
add_subdirectory(src/lwoegg)
add_subdirectory(src/lwoprogs)
add_subdirectory(src/miscprogs)
add_subdirectory(src/objegg)
add_subdirectory(src/objprogs)
add_subdirectory(src/palettizer)
add_subdirectory(src/pandatoolbase)
add_subdirectory(src/pfmprogs)
add_subdirectory(src/progbase)
add_subdirectory(src/pstatserver)
add_subdirectory(src/ptloader)
add_subdirectory(src/text-stats)
add_subdirectory(src/vrml)
add_subdirectory(src/vrmlegg)
add_subdirectory(src/vrmlprogs)
add_subdirectory(src/win-stats)
add_subdirectory(src/xfile)
add_subdirectory(src/xfileegg)
add_subdirectory(src/xfileprogs)
export_targets(Tools)

View File

@@ -2,38 +2,68 @@ if(NOT HAVE_PYTHON)
return()
endif()
add_executable(deploy-stub deploy-stub.c)
if(NOT IS_IOS)
add_executable(deploy-stub deploy-stub.c)
if(IS_OSX)
target_link_options(deploy-stub PRIVATE -sectcreate __PANDA __panda /dev/null)
set_target_properties(deploy-stub PROPERTIES
INSTALL_RPATH "@executable_path"
BUILD_WITH_INSTALL_RPATH ON)
elseif(WIN32)
target_sources(deploy-stub frozen_dllmain.c)
elseif(IS_LINUX OR IS_FREEBSD)
set_target_properties(deploy-stub PROPERTIES
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH ON)
if(APPLE)
target_link_options(deploy-stub PRIVATE -sectcreate __PANDA __panda /dev/null)
set_target_properties(deploy-stub PROPERTIES
INSTALL_RPATH "@executable_path"
BUILD_WITH_INSTALL_RPATH ON)
if(IS_IOS)
target_sources(deploy-stub PRIVATE ios_main.m)
find_library(UIKIT_LIBRARY UIKit)
target_link_libraries(deploy-stub ${UIKIT_LIBRARY})
target_link_options(deploy-stub PRIVATE -undefined dynamic_lookup)
endif()
elseif(WIN32)
target_sources(deploy-stub PRIVATE frozen_dllmain.c)
elseif(IS_LINUX OR IS_FREEBSD)
set_target_properties(deploy-stub PROPERTIES
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH ON)
endif()
target_link_libraries(deploy-stub Python::Python)
install(TARGETS deploy-stub EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
target_link_libraries(deploy-stub Python::Python)
install(TARGETS deploy-stub)
if(WIN32 OR IS_OSX)
if(WIN32 OR APPLE)
add_executable(deploy-stubw deploy-stub.c)
if(IS_OSX)
target_link_options(deploy-stubw PRIVATE -sectcreate __PANDA __panda /dev/null)
set_target_properties(deploy-stubw PROPERTIES
INSTALL_RPATH "@executable_path/../Frameworks"
BUILD_WITH_INSTALL_RPATH ON)
if(APPLE)
if(IS_IOS)
set(_rpath "@executable_path")
target_sources(deploy-stubw PRIVATE ios_main.m)
else()
set(_rpath "@executable_path/../Frameworks")
endif()
target_compile_definitions(deploy-stubw PRIVATE MACOS_APP_BUNDLE=1)
target_link_options(deploy-stubw PRIVATE -sectcreate __PANDA __panda /dev/null)
set_target_properties(deploy-stubw PROPERTIES
UNITY_BUILD OFF
INSTALL_RPATH ${_rpath}
BUILD_WITH_INSTALL_RPATH ON
XCODE_PRODUCT_TYPE "com.apple.product-type.application")
if(IS_IOS)
find_library(UIKIT_LIBRARY UIKit)
target_link_libraries(deploy-stubw ${UIKIT_LIBRARY} OpenSSL::SSL OpenSSL::Crypto p3ios)
target_link_options(deploy-stubw PRIVATE -undefined dynamic_lookup)
set_target_properties(deploy-stubw PROPERTIES
XCODE_PRODUCT_TYPE "com.apple.product-type.library.static"
XCODE_ATTRIBUTE_MACH_O_TYPE "mh_execute"
XCODE_ATTRIBUTE_EXECUTABLE_PREFIX ""
XCODE_ATTRIBUTE_EXECUTABLE_SUFFIX "")
endif()
elseif(WIN32)
target_sources(deploy-stubw frozen_dllmain.c)
target_sources(deploy-stubw PRIVATE frozen_dllmain.c)
set_property(TARGET deploy-stubw WIN32_EXECUTABLE)
endif()
target_link_libraries(deploy-stubw Python::Python)
install(TARGETS deploy-stubw)
install(TARGETS deploy-stubw EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

View File

@@ -16,6 +16,7 @@
#ifdef __APPLE__
# include <mach-o/dyld.h>
# include <libgen.h>
# include <TargetConditionals.h>
#endif
#include <stdio.h>
@@ -52,6 +53,7 @@ volatile struct {
// The reason we initialize it to -1 is because otherwise, smart linkers may
// end up putting it in the .bss section for zero-initialized data.
} blobinfo = {(uint64_t)-1};
void *blob;
#ifdef MS_WINDOWS
# define WIN32_LEAN_AND_MEAN
@@ -101,6 +103,13 @@ static int supports_code_page(UINT cp) {
}
#endif
#if TARGET_OS_IPHONE
extern void ios_ensure_thread_safety();
extern int ios_main(int argc, char *argv[]);
int stored_argc;
#endif
/**
* Sets the main_dir field of the blobinfo structure, but only if it wasn't
* already set.
@@ -446,7 +455,11 @@ int Py_FrozenMain(int argc, char **argv)
return 1;
}
const char *dir = dirname(resolved);
#if TARGET_OS_IPHONE
strcpy(buffer, dir);
#else
sprintf(buffer, "%s/../Frameworks", dir);
#endif
PyObject *sys_path = PyList_New(1);
PyList_SET_ITEM(sys_path, 0, PyUnicode_FromString(buffer));
@@ -455,7 +468,11 @@ int Py_FrozenMain(int argc, char **argv)
// Now, store a path to the Resources directory into the main_dir pointer,
// for ConfigPageManager to read out and assign to MAIN_DIR.
#if TARGET_OS_IPHONE
strcpy(buffer, dir);
#else
sprintf(buffer, "%s/../Resources", dir);
#endif
set_main_dir(buffer);
// Finally, chdir to it, so that regular Python files are read from the
@@ -492,6 +509,12 @@ error:
return sts;
}
#if TARGET_OS_IPHONE
void Py_FrozenMain_Threaded(void *argv_ptr) {
Py_FrozenMain(stored_argc, (char **)argv_ptr);
}
#endif
/**
* Maps the binary blob at the given memory address to memory, and returns the
* pointer to the beginning of it.
@@ -571,6 +594,41 @@ static void unmap_blob(void *blob) {
}
}
__attribute__((__visibility__("default")))
void *load_blobinfo_pointers() {
if (blob == NULL) {
blob = map_blob((off_t)blobinfo.blob_offset, (size_t)blobinfo.blob_size);
assert(blob != NULL);
}
// Offset the pointers in the header using the base mmap address.
if (blobinfo.version > 0 && blobinfo.num_pointers > 0) {
uint32_t i;
assert(blobinfo.num_pointers <= MAX_NUM_POINTERS);
for (i = 0; i < blobinfo.num_pointers; ++i) {
// Only offset if the pointer is non-NULL. Except for the first
// pointer, which may never be NULL and usually (but not always)
// points to the beginning of the blob.
if (i == 0 || blobinfo.pointers[i] != 0) {
blobinfo.pointers[i] = (void *)((uintptr_t)blobinfo.pointers[i] + (uintptr_t)blob);
}
}
} else {
blobinfo.pointers[0] = blob;
}
// Offset the pointers in the module table using the base mmap address.
struct _frozen *moddef = blobinfo.pointers[0];
while (moddef->name) {
moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob);
if (moddef->code != 0) {
moddef->code = (unsigned char *)((uintptr_t)moddef->code + (uintptr_t)blob);
}
//printf("MOD: %s %p %d\n", moddef->name, (void*)moddef->code, moddef->size);
moddef++;
}
}
/**
* Main entry point to deploy-stub.
*/
@@ -580,9 +638,7 @@ int wmain(int argc, wchar_t *argv[]) {
int main(int argc, char *argv[]) {
#endif
int retval;
struct _frozen *moddef;
const char *log_filename;
void *blob = NULL;
log_filename = NULL;
#ifdef __APPLE__
@@ -606,37 +662,11 @@ int main(int argc, char *argv[]) {
// If we have a blob offset, we have to map the blob to memory.
if (blobinfo.version == 0 || blobinfo.blob_offset != 0) {
void *blob = map_blob((off_t)blobinfo.blob_offset, (size_t)blobinfo.blob_size);
assert(blob != NULL);
// Offset the pointers in the header using the base mmap address.
if (blobinfo.version > 0 && blobinfo.num_pointers > 0) {
uint32_t i;
assert(blobinfo.num_pointers <= MAX_NUM_POINTERS);
for (i = 0; i < blobinfo.num_pointers; ++i) {
// Only offset if the pointer is non-NULL. Except for the first
// pointer, which may never be NULL and usually (but not always)
// points to the beginning of the blob.
if (i == 0 || blobinfo.pointers[i] != 0) {
blobinfo.pointers[i] = (void *)((uintptr_t)blobinfo.pointers[i] + (uintptr_t)blob);
}
}
if (blobinfo.num_pointers >= 12) {
log_filename = blobinfo.pointers[11];
}
} else {
blobinfo.pointers[0] = blob;
if (blobinfo.pointers[0] == NULL) {
load_blobinfo_pointers();
}
// Offset the pointers in the module table using the base mmap address.
moddef = blobinfo.pointers[0];
while (moddef->name) {
moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob);
if (moddef->code != 0) {
moddef->code = (unsigned char *)((uintptr_t)moddef->code + (uintptr_t)blob);
}
//printf("MOD: %s %p %d\n", moddef->name, (void*)moddef->code, moddef->size);
moddef++;
if (blobinfo.version > 0 && blobinfo.num_pointers > 0 && blobinfo.num_pointers >= 12) {
log_filename = blobinfo.pointers[11];
}
}
@@ -653,7 +683,19 @@ int main(int argc, char *argv[]) {
// Run frozen application
PyImport_FrozenModules = blobinfo.pointers[0];
#if TARGET_OS_IPHONE
stored_argc = argc;
ios_ensure_thread_safety();
pthread_t thread_id;
pthread_create(&thread_id, NULL, Py_FrozenMain_Threaded, argv);
pthread_detach(thread_id);
retval = ios_main(argc, argv);
#else
retval = Py_FrozenMain(argc, argv);
#endif
fflush(stdout);
fflush(stderr);