Browse Source

Mac OS X build improvements

rdb 10 years ago
parent
commit
bcb203af9a

+ 4 - 1
direct/src/p3d/Packager.py

@@ -1156,7 +1156,10 @@ class Packager:
                     self.__alterFrameworkDependencies(file, framework_deps)
                     self.__alterFrameworkDependencies(file, framework_deps)
 
 
                 for filename in filenames:
                 for filename in filenames:
-                    if '.framework/' in filename:
+                    if '@loader_path' in filename:
+                        filename = filename.replace('@loader_path', file.filename.getDirname())
+
+                    if False and '.framework/' in filename:
                         # It references a framework, and besides the fact
                         # It references a framework, and besides the fact
                         # that those often contain absolute paths, they
                         # that those often contain absolute paths, they
                         # aren't commonly on the library path either.
                         # aren't commonly on the library path either.

+ 2 - 3
direct/src/p3d/ppackage.py

@@ -90,7 +90,7 @@ Options:
      each supported architecture).  On other platforms, this option
      each supported architecture).  On other platforms, this option
      does nothing.  This is therefore safe to apply in all cases, if
      does nothing.  This is therefore safe to apply in all cases, if
      you wish to take advantage of universal binaries.  This is
      you wish to take advantage of universal binaries.  This is
-     equivalent to "-P osx_ppc -P osx_i386" on Mac platforms.
+     equivalent to "-P osx_i386 -P osx_x86_64" on Mac platforms.
 
 
   -P platform
   -P platform
      Specify the platform to masquerade as.  The default is whatever
      Specify the platform to masquerade as.  The default is whatever
@@ -215,8 +215,7 @@ if universalBinaries:
         print '\nYou may not specify both -u and -P.\n'
         print '\nYou may not specify both -u and -P.\n'
         sys.exit(1)
         sys.exit(1)
     if PandaSystem.getPlatform().startswith('osx_'):
     if PandaSystem.getPlatform().startswith('osx_'):
-        # Maybe soon we'll add osx_x86_64 to this default list.
-        platforms = ['osx_i386', 'osx_ppc']
+        platforms = ['osx_i386', 'osx_x86_64']
 
 
 if not platforms:
 if not platforms:
     platforms = [PandaSystem.getPlatform()]
     platforms = [PandaSystem.getPlatform()]

+ 1 - 1
direct/src/showutil/FreezeTool.py

@@ -144,7 +144,7 @@ class CompilationEnvironment:
             elif proc == 'ppc':
             elif proc == 'ppc':
                 self.arch = '-arch ppc'
                 self.arch = '-arch ppc'
             elif proc == 'x86_64':
             elif proc == 'x86_64':
-                self.arch = '-arch x86_x64'
+                self.arch = '-arch x86_64'
             self.compileObj = "gcc -fPIC -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
             self.compileObj = "gcc -fPIC -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
             self.linkExe = "gcc %(arch)s -o %(basename)s %(basename)s.o -framework Python"
             self.linkExe = "gcc %(arch)s -o %(basename)s %(basename)s.o -framework Python"
             self.linkDll = "gcc %(arch)s -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"
             self.linkDll = "gcc %(arch)s -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"

+ 3 - 0
makepanda/installpanda.py

@@ -127,6 +127,9 @@ def GetLibDir():
     something like "lib" or "lib64" or in some cases, something
     something like "lib" or "lib64" or in some cases, something
     similar to "lib/x86_64-linux-gnu". """
     similar to "lib/x86_64-linux-gnu". """
 
 
+    if sys.platform == "darwin":
+        return "lib"
+
     # This one's a bit tricky.  Some systems require us to install
     # This one's a bit tricky.  Some systems require us to install
     # 64-bits libraries into /usr/lib64, some into /usr/lib.
     # 64-bits libraries into /usr/lib64, some into /usr/lib.
     # Debian forbids installing to lib64 nowadays, and the only distros
     # Debian forbids installing to lib64 nowadays, and the only distros

+ 77 - 63
makepanda/makepanda.py

@@ -67,7 +67,7 @@ MAJOR_VERSION=None
 COREAPI_VERSION=None
 COREAPI_VERSION=None
 PLUGIN_VERSION=None
 PLUGIN_VERSION=None
 OSXTARGET=None
 OSXTARGET=None
-UNIVERSAL=False
+OSX_ARCHS=[]
 HOST_URL=None
 HOST_URL=None
 global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
 global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
 STRDXSDKVERSION = 'default'
 STRDXSDKVERSION = 'default'
@@ -165,7 +165,7 @@ def usage(problem):
 
 
 def parseopts(args):
 def parseopts(args):
     global INSTALLER,RTDIST,RUNTIME,GENMAN,DISTRIBUTOR,VERSION
     global INSTALLER,RTDIST,RUNTIME,GENMAN,DISTRIBUTOR,VERSION
-    global COMPRESSOR,THREADCOUNT,OSXTARGET,UNIVERSAL,HOST_URL
+    global COMPRESSOR,THREADCOUNT,OSXTARGET,OSX_ARCHS,HOST_URL
     global DEBVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX
     global DEBVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX
     global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
     global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
     longopts = [
     longopts = [
@@ -179,6 +179,7 @@ def parseopts(args):
     optimize = ""
     optimize = ""
     target = None
     target = None
     target_arch = None
     target_arch = None
+    universal = False
     for pkg in PkgListGet(): longopts.append("no-"+pkg.lower())
     for pkg in PkgListGet(): longopts.append("no-"+pkg.lower())
     for pkg in PkgListGet(): longopts.append("use-"+pkg.lower())
     for pkg in PkgListGet(): longopts.append("use-"+pkg.lower())
     try:
     try:
@@ -197,7 +198,7 @@ def parseopts(args):
             elif (option=="--threads"): THREADCOUNT=int(value)
             elif (option=="--threads"): THREADCOUNT=int(value)
             elif (option=="--outputdir"): SetOutputDir(value.strip())
             elif (option=="--outputdir"): SetOutputDir(value.strip())
             elif (option=="--osxtarget"): OSXTARGET=value.strip()
             elif (option=="--osxtarget"): OSXTARGET=value.strip()
-            elif (option=="--universal"): UNIVERSAL=True
+            elif (option=="--universal"): universal = True
             elif (option=="--target"): target = value.strip()
             elif (option=="--target"): target = value.strip()
             elif (option=="--arch"): target_arch = value.strip()
             elif (option=="--arch"): target_arch = value.strip()
             elif (option=="--nocolor"): DisableColors()
             elif (option=="--nocolor"): DisableColors()
@@ -252,23 +253,39 @@ def parseopts(args):
         usage("Options --runtime and --rtdist cannot be specified at the same time!")
         usage("Options --runtime and --rtdist cannot be specified at the same time!")
     if (optimize=="" and (RTDIST or RUNTIME)): optimize = "4"
     if (optimize=="" and (RTDIST or RUNTIME)): optimize = "4"
     elif (optimize==""): optimize = "3"
     elif (optimize==""): optimize = "3"
-    if (OSXTARGET != None and OSXTARGET.strip() == ""):
-        OSXTARGET = None
-    elif (OSXTARGET != None):
-        OSXTARGET = OSXTARGET.strip()
-        if (len(OSXTARGET) != 4 or not OSXTARGET.startswith("10.")):
-            usage("Invalid setting for OSXTARGET")
+
+    if OSXTARGET:
         try:
         try:
-            OSXTARGET = "10.%d" % (int(OSXTARGET[-1]))
+            maj, min = OSXTARGET.strip().split('.')
+            OSXTARGET = int(maj), int(min)
+            assert OSXTARGET[0] == 10
         except:
         except:
             usage("Invalid setting for OSXTARGET")
             usage("Invalid setting for OSXTARGET")
+    else:
+        OSXTARGET = None
+
+    if target is not None or target_arch is not None:
+        SetTarget(target, target_arch)
 
 
-    if UNIVERSAL:
-        if not OSXTARGET:
-            exit("--universal requires --osxtarget")
+    if universal:
         if target_arch:
         if target_arch:
             exit("--universal is incompatible with --arch")
             exit("--universal is incompatible with --arch")
 
 
+        OSX_ARCHS.append("i386")
+        if OSXTARGET:
+            osxver = OSXTARGET
+        else:
+            maj, min = platform.mac_ver()[0].split('.')[:2]
+            osxver = int(maj), int(min)
+
+        if osxver[1] < 6:
+            OSX_ARCHS.append("ppc")
+        else:
+            OSX_ARCHS.append("x86_64")
+
+    elif HasTargetArch():
+        OSX_ARCHS.append(GetTargetArch())
+
     try:
     try:
         SetOptimize(int(optimize))
         SetOptimize(int(optimize))
         assert GetOptimize() in [1, 2, 3, 4]
         assert GetOptimize() in [1, 2, 3, 4]
@@ -278,9 +295,6 @@ def parseopts(args):
     if GIT_COMMIT is not None and not re.match("^[a-f0-9]{40}$", GIT_COMMIT):
     if GIT_COMMIT is not None and not re.match("^[a-f0-9]{40}$", GIT_COMMIT):
         usage("Invalid SHA-1 hash given for --git-commit option!")
         usage("Invalid SHA-1 hash given for --git-commit option!")
 
 
-    if target is not None or target_arch is not None:
-        SetTarget(target, target_arch)
-
     is_win7 = False
     is_win7 = False
     if GetHost() == "windows":
     if GetHost() == "windows":
         if (STRMSPLATFORMVERSION not in ['winserver2003r2', 'win60A']):
         if (STRMSPLATFORMVERSION not in ['winserver2003r2', 'win60A']):
@@ -316,8 +330,8 @@ if ("LDFLAGS" in os.environ):
     LDFLAGS = os.environ["LDFLAGS"].strip()
     LDFLAGS = os.environ["LDFLAGS"].strip()
 
 
 os.environ["MAKEPANDA"] = os.path.abspath(sys.argv[0])
 os.environ["MAKEPANDA"] = os.path.abspath(sys.argv[0])
-if (GetHost() == "darwin" and OSXTARGET != None):
-    os.environ["MACOSX_DEPLOYMENT_TARGET"] = OSXTARGET
+if GetHost() == "darwin" and OSXTARGET is not None:
+    os.environ["MACOSX_DEPLOYMENT_TARGET"] = "%d.%d" % OSXTARGET
 
 
 ########################################################################
 ########################################################################
 ##
 ##
@@ -683,7 +697,7 @@ if (COMPILER=="GCC"):
     elif RUNTIME:
     elif RUNTIME:
         # We don't support Cocoa in the runtime yet.
         # We don't support Cocoa in the runtime yet.
         PkgDisable("COCOA")
         PkgDisable("COCOA")
-    if UNIVERSAL or GetTargetArch() == 'x86_64':
+    if 'x86_64' in OSX_ARCHS:
         # 64-bits OS X doesn't have Carbon.
         # 64-bits OS X doesn't have Carbon.
         PkgDisable("CARBON")
         PkgDisable("CARBON")
 
 
@@ -738,7 +752,7 @@ if (COMPILER=="GCC"):
         cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
         cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
         if cv_lib == "opencv_core":
         if cv_lib == "opencv_core":
             OPENCV_VER_23 = True
             OPENCV_VER_23 = True
-            SmartPkgEnable("OPENCV", "opencv",   ("opencv_core"), ("opencv2/core/core.hpp"))
+            SmartPkgEnable("OPENCV", "opencv",   ("opencv_core", "opencv_highgui"), ("opencv2/core/core.hpp"))
         else:
         else:
             SmartPkgEnable("OPENCV", "opencv",   ("cv", "highgui", "cvaux", "ml", "cxcore"),
             SmartPkgEnable("OPENCV", "opencv",   ("cv", "highgui", "cvaux", "ml", "cxcore"),
                            ("opencv", "opencv/cv.h", "opencv/cxcore.h", "opencv/highgui.h"))
                            ("opencv", "opencv/cv.h", "opencv/cxcore.h", "opencv/highgui.h"))
@@ -752,8 +766,8 @@ if (COMPILER=="GCC"):
         SmartPkgEnable("ROCKET",    "",          rocket_libs, "Rocket/Core.h")
         SmartPkgEnable("ROCKET",    "",          rocket_libs, "Rocket/Core.h")
 
 
         if not PkgSkip("PYTHON"):
         if not PkgSkip("PYTHON"):
-            if GetHost() == "darwin" and GetTarget() == "darwin" and not RTDIST:
-                # Use the system Python framework in the standard Mac SDK.
+            if GetTarget() == "darwin" and SDK.get("MACOSX") and not RTDIST:
+                # When targeting a specific OSX version, use the system Python framework in the standard Mac SDK.
                 LibName("PYTHON", "-framework Python")
                 LibName("PYTHON", "-framework Python")
             else:
             else:
                 SmartPkgEnable("PYTHON", "", SDK["PYTHONVERSION"], (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"), tool = SDK["PYTHONVERSION"] + "-config")
                 SmartPkgEnable("PYTHON", "", SDK["PYTHONVERSION"], (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"), tool = SDK["PYTHONVERSION"] + "-config")
@@ -1125,20 +1139,13 @@ def CompileCxx(obj,src,opts):
         # Mac-specific flags.
         # Mac-specific flags.
         if GetTarget() == "darwin":
         if GetTarget() == "darwin":
             cmd += " -Wno-deprecated-declarations"
             cmd += " -Wno-deprecated-declarations"
-            if (OSXTARGET != None):
+            if OSXTARGET is not None:
                 cmd += " -isysroot " + SDK["MACOSX"]
                 cmd += " -isysroot " + SDK["MACOSX"]
-                cmd += " -mmacosx-version-min=" + OSXTARGET
-
-            if UNIVERSAL:
-                cmd += " -arch i386"
-                if OSXTARGET:
-                    osxver = int(OSXTARGET[-1])
-                    if "NOPPC" not in opts and int(OSXTARGET[-1]) < 6:
-                        cmd += " -arch ppc"
-                    if int(OSXTARGET[-1]) >= 5:
-                        cmd += " -arch x86_64"
-            elif HasTargetArch():
-                cmd += " -arch %s" % (GetTargetArch())
+                cmd += " -mmacosx-version-min=%d.%d" % (OSXTARGET)
+
+            for arch in OSX_ARCHS:
+                if arch != "ppc" or "NOPPC" not in OPTS:
+                    cmd += " -arch %s" % arch
 
 
         if "SYSROOT" in SDK:
         if "SYSROOT" in SDK:
             cmd += ' --sysroot=%s -no-canonical-prefixes' % (SDK["SYSROOT"])
             cmd += ' --sysroot=%s -no-canonical-prefixes' % (SDK["SYSROOT"])
@@ -1587,20 +1594,13 @@ def CompileLink(dll, obj, opts):
         # Mac OS X specific flags.
         # Mac OS X specific flags.
         if GetTarget() == 'darwin':
         if GetTarget() == 'darwin':
             cmd += " -headerpad_max_install_names"
             cmd += " -headerpad_max_install_names"
-            if OSXTARGET != None:
+            if OSXTARGET is not None:
                 cmd += " -isysroot " + SDK["MACOSX"] + " -Wl,-syslibroot," + SDK["MACOSX"]
                 cmd += " -isysroot " + SDK["MACOSX"] + " -Wl,-syslibroot," + SDK["MACOSX"]
-                cmd += " -mmacosx-version-min=" + OSXTARGET
-
-            if UNIVERSAL:
-                cmd += " -arch i386"
-                if OSXTARGET:
-                    osxver = int(OSXTARGET[-1])
-                    if "NOPPC" not in opts and int(OSXTARGET[-1]) < 6:
-                        cmd += " -arch ppc"
-                    if int(OSXTARGET[-1]) >= 5:
-                        cmd += " -arch x86_64"
-            elif HasTargetArch():
-                cmd += " -arch %s" % (GetTargetArch())
+                cmd += " -mmacosx-version-min=%d.%d" % (OSXTARGET)
+
+            for arch in OSX_ARCHS:
+                if arch != "ppc" or "NOPPC" not in OPTS:
+                    cmd += " -arch %s" % arch
 
 
         if "SYSROOT" in SDK:
         if "SYSROOT" in SDK:
             cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
             cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
@@ -1820,10 +1820,11 @@ def Package(target, inputs, opts):
     command += "direct/src/p3d/ppackage.py"
     command += "direct/src/p3d/ppackage.py"
 
 
     if GetTarget() == "darwin":
     if GetTarget() == "darwin":
-        if SDK.get("MACOSX") is not None:
+        if SDK.get("MACOSX"):
             command += " -R \"%s\"" % SDK["MACOSX"]
             command += " -R \"%s\"" % SDK["MACOSX"]
-        if UNIVERSAL:
-            command += " -u"
+
+        for arch in OSX_ARCHS:
+            command += " -P osx_%s" % arch
 
 
     command += " -i \"" + GetOutputDir() + "/stage\""
     command += " -i \"" + GetOutputDir() + "/stage\""
     if (P3DSUFFIX):
     if (P3DSUFFIX):
@@ -2608,14 +2609,27 @@ if tp_dir is not None:
                 if (PkgSkip("PYTHON")==0 and os.path.exists(tp_pkg + "/bin/" + SDK["PYTHONVERSION"])):
                 if (PkgSkip("PYTHON")==0 and os.path.exists(tp_pkg + "/bin/" + SDK["PYTHONVERSION"])):
                     CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/" + SDK["PYTHONVERSION"] + "/")
                     CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/" + SDK["PYTHONVERSION"] + "/")
         else:
         else:
-            if os.path.exists(tp_pkg + "/lib"):
-                CopyAllFiles(GetOutputDir() + "/lib/", tp_pkg + "/lib/")
-                if (PkgSkip("PYTHON")==0 and os.path.exists(tp_pkg + "/lib/" + SDK["PYTHONVERSION"])):
-                    CopyAllFiles(GetOutputDir() + "/lib/", tp_pkg + "/lib/" + SDK["PYTHONVERSION"] + "/")
+            for tp_lib in glob.glob(tp_pkg + "/lib/*.so*"):
+                CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
+
+            if not PkgSkip("PYTHON"):
+                for tp_lib in glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.so*")):
+                    CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
+
+            if GetTarget() == 'darwin':
+                for tp_lib in glob.glob(tp_pkg + "/lib/*.dylib"):
+                    CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
+
+                if not PkgSkip("PYTHON"):
+                    for tp_lib in glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.dylib")):
+                        CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
+
+                for fwx in glob.glob(tp_pkg + "/*.framework"):
+                    CopyTree(GetOutputDir() + "/Frameworks/" + os.path.basename(fwx), fwx)
 
 
     if GetTarget() == 'windows':
     if GetTarget() == 'windows':
         CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
         CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
-        if PkgSkip("PYTHON") == 0:
+        if not PkgSkip("PYTHON"):
             pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
             pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
             if (GetOptimize() <= 2): pydll += "_d.dll"
             if (GetOptimize() <= 2): pydll += "_d.dll"
             else: pydll += ".dll"
             else: pydll += ".dll"
@@ -3745,7 +3759,6 @@ if (not RUNTIME):
 
 
   TargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core'])
   TargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core'])
 
 
-  OPTS=['WINSOCK2']
   TargetAdd('core.pyd', input='libp3downloader_igate.obj')
   TargetAdd('core.pyd', input='libp3downloader_igate.obj')
   TargetAdd('core.pyd', input='p3express_ext_composite.obj')
   TargetAdd('core.pyd', input='p3express_ext_composite.obj')
   TargetAdd('core.pyd', input='libp3express_igate.obj')
   TargetAdd('core.pyd', input='libp3express_igate.obj')
@@ -3795,7 +3808,7 @@ if (not RUNTIME):
   TargetAdd('core.pyd', input='core_module.obj')
   TargetAdd('core.pyd', input='core_module.obj')
   TargetAdd('core.pyd', input='libp3tinyxml.ilb')
   TargetAdd('core.pyd', input='libp3tinyxml.ilb')
   TargetAdd('core.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('core.pyd', input=COMMON_PANDA_LIBS)
-  TargetAdd('core.pyd', opts=OPTS)
+  TargetAdd('core.pyd', opts=['PYTHON', 'WINSOCK2'])
 
 
 #
 #
 # DIRECTORY: panda/src/vision/
 # DIRECTORY: panda/src/vision/
@@ -6597,6 +6610,7 @@ def MakeInstallerOSX():
     oscmd("cp -R %s/models                dstroot/base/Developer/Panda3D/models" % GetOutputDir())
     oscmd("cp -R %s/models                dstroot/base/Developer/Panda3D/models" % GetOutputDir())
     oscmd("cp -R doc/LICENSE              dstroot/base/Developer/Panda3D/LICENSE")
     oscmd("cp -R doc/LICENSE              dstroot/base/Developer/Panda3D/LICENSE")
     oscmd("cp -R doc/ReleaseNotes         dstroot/base/Developer/Panda3D/ReleaseNotes")
     oscmd("cp -R doc/ReleaseNotes         dstroot/base/Developer/Panda3D/ReleaseNotes")
+    oscmd("cp -R %s/Frameworks            dstroot/base/Developer/Panda3D/Frameworks" % GetOutputDir())
     if os.path.isdir(GetOutputDir()+"/plugins"):
     if os.path.isdir(GetOutputDir()+"/plugins"):
         oscmd("cp -R %s/plugins           dstroot/base/Developer/Panda3D/plugins" % GetOutputDir())
         oscmd("cp -R %s/plugins           dstroot/base/Developer/Panda3D/plugins" % GetOutputDir())
 
 
@@ -6650,11 +6664,11 @@ def MakeInstallerOSX():
     if PkgSkip("PYTHON")==0:
     if PkgSkip("PYTHON")==0:
         PV = SDK["PYTHONVERSION"].replace("python", "")
         PV = SDK["PYTHONVERSION"].replace("python", "")
         oscmd("mkdir -p dstroot/pythoncode/usr/bin")
         oscmd("mkdir -p dstroot/pythoncode/usr/bin")
-        oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D/direct")
+        oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D")
         oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
         oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
         WriteFile("dstroot/pythoncode/Library/Python/%s/site-packages/Panda3D.pth" % PV, "/Developer/Panda3D")
         WriteFile("dstroot/pythoncode/Library/Python/%s/site-packages/Panda3D.pth" % PV, "/Developer/Panda3D")
         oscmd("cp -R %s/pandac                dstroot/pythoncode/Developer/Panda3D/pandac" % GetOutputDir())
         oscmd("cp -R %s/pandac                dstroot/pythoncode/Developer/Panda3D/pandac" % GetOutputDir())
-        oscmd("cp -R direct/src/*             dstroot/pythoncode/Developer/Panda3D/direct")
+        oscmd("cp -R %s/direct                dstroot/pythoncode/Developer/Panda3D/direct" % GetOutputDir())
         oscmd("ln -s %s                       dstroot/pythoncode/usr/bin/ppython" % SDK["PYTHONEXEC"])
         oscmd("ln -s %s                       dstroot/pythoncode/usr/bin/ppython" % SDK["PYTHONEXEC"])
         if os.path.isdir(GetOutputDir()+"/Pmw"):
         if os.path.isdir(GetOutputDir()+"/Pmw"):
             oscmd("cp -R %s/Pmw               dstroot/pythoncode/Developer/Panda3D/Pmw" % GetOutputDir())
             oscmd("cp -R %s/Pmw               dstroot/pythoncode/Developer/Panda3D/Pmw" % GetOutputDir())
@@ -6691,15 +6705,15 @@ def MakeInstallerOSX():
         if not os.path.isdir("dstroot/" + pkg):
         if not os.path.isdir("dstroot/" + pkg):
             os.makedirs("dstroot/" + pkg)
             os.makedirs("dstroot/" + pkg)
 
 
-        if OSXTARGET:
-            target = '--target %s' % (OSXTARGET)
+        if OSXTARGET and OSXTARGET <= (10, 5):
+            target = '--target %d.%d' % (OSXTARGET)
         else:
         else:
             target = ''
             target = ''
 
 
         if os.path.exists("/Developer/usr/bin/packagemaker"):
         if os.path.exists("/Developer/usr/bin/packagemaker"):
             cmd = '/Developer/usr/bin/packagemaker --info /tmp/Info_plist --version ' + VERSION + ' --out dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg ' + target + ' --domain system --root dstroot/' + pkg + '/ --no-relocate'
             cmd = '/Developer/usr/bin/packagemaker --info /tmp/Info_plist --version ' + VERSION + ' --out dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg ' + target + ' --domain system --root dstroot/' + pkg + '/ --no-relocate'
         elif os.path.exists("/Applications/Xcode.app/Contents/Applications/PackageMaker.app/Contents/MacOS/PackageMaker"):
         elif os.path.exists("/Applications/Xcode.app/Contents/Applications/PackageMaker.app/Contents/MacOS/PackageMaker"):
-            cmd = '/Applications/Xcode.app/Contents/Applications/PackageMaker.app/Contents/MacOS/PackageMaker --info /tmp/Info_plist --version ' + VERSION + ' --out dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg --target ' + target + ' --domain system --root dstroot/' + pkg + '/ --no-relocate'
+            cmd = '/Applications/Xcode.app/Contents/Applications/PackageMaker.app/Contents/MacOS/PackageMaker --info /tmp/Info_plist --version ' + VERSION + ' --out dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg ' + target + ' --domain system --root dstroot/' + pkg + '/ --no-relocate'
         elif os.path.exists("/Developer/Tools/packagemaker"):
         elif os.path.exists("/Developer/Tools/packagemaker"):
             cmd = '/Developer/Tools/packagemaker -build -f dstroot/' + pkg + '/ -p dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg -i /tmp/Info_plist'
             cmd = '/Developer/Tools/packagemaker -build -f dstroot/' + pkg + '/ -p dstroot/Panda3D/Panda3D.mpkg/Contents/Packages/' + pkg + '.pkg -i /tmp/Info_plist'
         else:
         else:

+ 37 - 17
makepanda/makepandacore.py

@@ -1062,7 +1062,10 @@ def MakeBuildTree():
     MakeDirectory(OUTPUTDIR + "/panda3d")
     MakeDirectory(OUTPUTDIR + "/panda3d")
     CreateFile(OUTPUTDIR + "/panda3d/__init__.py")
     CreateFile(OUTPUTDIR + "/panda3d/__init__.py")
 
 
-    if GetTarget() == 'android':
+    if GetTarget() == 'darwin':
+        MakeDirectory(OUTPUTDIR + "/Frameworks")
+
+    elif GetTarget() == 'android':
         MakeDirectory(OUTPUTDIR + "/libs")
         MakeDirectory(OUTPUTDIR + "/libs")
         MakeDirectory(OUTPUTDIR + "/libs/" + ANDROID_ABI)
         MakeDirectory(OUTPUTDIR + "/libs/" + ANDROID_ABI)
         MakeDirectory(OUTPUTDIR + "/src")
         MakeDirectory(OUTPUTDIR + "/src")
@@ -1847,7 +1850,6 @@ def SdkLocatePython(prefer_thirdparty_python=False):
 
 
     elif CrossCompiling() or (prefer_thirdparty_python and os.path.isdir(os.path.join(GetThirdpartyDir(), "python"))):
     elif CrossCompiling() or (prefer_thirdparty_python and os.path.isdir(os.path.join(GetThirdpartyDir(), "python"))):
         tp_python = os.path.join(GetThirdpartyDir(), "python")
         tp_python = os.path.join(GetThirdpartyDir(), "python")
-        SDK["PYTHON"] = tp_python + "/include"
 
 
         if GetTarget() == 'darwin':
         if GetTarget() == 'darwin':
             py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].dylib")
             py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].dylib")
@@ -1865,6 +1867,24 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         py_lib = os.path.basename(py_libs[0])
         py_lib = os.path.basename(py_libs[0])
         SDK["PYTHONVERSION"] = "python" + py_lib[9] + "." + py_lib[11]
         SDK["PYTHONVERSION"] = "python" + py_lib[9] + "." + py_lib[11]
         SDK["PYTHONEXEC"] = tp_python + "/bin/" + SDK["PYTHONVERSION"]
         SDK["PYTHONEXEC"] = tp_python + "/bin/" + SDK["PYTHONVERSION"]
+        SDK["PYTHON"] = tp_python + "/include/" + SDK["PYTHONVERSION"]
+
+    elif GetTarget() == 'darwin' and SDK.get("MACOSX"):
+         # When targeting a specific Mac OS X version, use the system Python framework.
+         py_fwx = SDK.get("MACOSX", "") + "/System/Library/Frameworks/Python.framework/Versions/Current"
+
+         if not os.path.islink(py_fwx):
+             exit("Could not locate Python installation at %s" % (py_fwx))
+
+         ver = os.path.basename(os.readlink(py_fwx))
+         py_fwx = SDK.get("MACOSX", "") + "/System/Library/Frameworks/Python.framework/Versions/%s" % ver
+
+         SDK["PYTHON"] = py_fwx + "/Headers"
+         SDK["PYTHONVERSION"] = "python" + ver
+         SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
+
+         if sys.version[:3] != ver:
+             print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
 
 
     #elif GetTarget() == 'windows':
     #elif GetTarget() == 'windows':
     #    SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
     #    SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
@@ -1932,22 +1952,23 @@ def SdkLocateMSPlatform(strMode = 'default'):
 def SdkLocateMacOSX(osxtarget = None):
 def SdkLocateMacOSX(osxtarget = None):
     if (GetHost() != "darwin"): return
     if (GetHost() != "darwin"): return
     if (osxtarget != None):
     if (osxtarget != None):
-        if (os.path.exists("/Developer/SDKs/MacOSX%su.sdk" % osxtarget)):
-            SDK["MACOSX"] = "/Developer/SDKs/MacOSX%su.sdk" % osxtarget
-        elif (os.path.exists("/Developer/SDKs/MacOSX%s.sdk" % osxtarget)):
-            SDK["MACOSX"] = "/Developer/SDKs/MacOSX%s.sdk" % osxtarget
-        elif (os.path.exists("/Developer/SDKs/MacOSX%s.0.sdk" % osxtarget)):
-            SDK["MACOSX"] = "/Developer/SDKs/MacOSX%s.0.sdk" % osxtarget
-        elif (os.path.exists("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%s.sdk" % osxtarget)):
-            SDK["MACOSX"] = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%s.sdk" % osxtarget
+        sdkname = "MacOSX%d.%d" % osxtarget
+        if (os.path.exists("/Developer/SDKs/%su.sdk" % sdkname)):
+            SDK["MACOSX"] = "/Developer/SDKs/%su.sdk" % sdkname
+        elif (os.path.exists("/Developer/SDKs/%s.sdk" % sdkname)):
+            SDK["MACOSX"] = "/Developer/SDKs/%s.sdk" % sdkname
+        elif (os.path.exists("/Developer/SDKs/%s.0.sdk" % sdkname)):
+            SDK["MACOSX"] = "/Developer/SDKs/%s.0.sdk" % sdkname
+        elif (os.path.exists("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/%s.sdk" % sdkname)):
+            SDK["MACOSX"] = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/%s.sdk" % sdkname
         else:
         else:
             handle = os.popen("xcode-select -print-path")
             handle = os.popen("xcode-select -print-path")
             result = handle.read().strip().rstrip('/')
             result = handle.read().strip().rstrip('/')
             handle.close()
             handle.close()
-            if (os.path.exists("%s/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%s.sdk" % (result, osxtarget))):
-                SDK["MACOSX"] = "%s/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%s.sdk" % (result, osxtarget)
+            if (os.path.exists("%s/Platforms/MacOSX.platform/Developer/SDKs/%s.sdk" % (result, sdkname))):
+                SDK["MACOSX"] = "%s/Platforms/MacOSX.platform/Developer/SDKs/%s.sdk" % (result, sdkname)
             else:
             else:
-                exit("Couldn't find any MacOSX SDK for OSX version %s!" % osxtarget)
+                exit("Couldn't find any MacOSX SDK for OSX version %s!" % sdkname)
     else:
     else:
         SDK["MACOSX"] = ""
         SDK["MACOSX"] = ""
 
 
@@ -2370,11 +2391,10 @@ def SetupBuildEnvironment(compiler):
     AddToPathEnv("PYTHONPATH", builtdir)
     AddToPathEnv("PYTHONPATH", builtdir)
     AddToPathEnv("PANDA_PRC_DIR", os.path.join(builtdir, "etc"))
     AddToPathEnv("PANDA_PRC_DIR", os.path.join(builtdir, "etc"))
     AddToPathEnv("PATH", os.path.join(builtdir, "bin"))
     AddToPathEnv("PATH", os.path.join(builtdir, "bin"))
-    if (GetHost() == 'windows'):
-        AddToPathEnv("PATH", os.path.join(builtdir, "plugins"))
+    if GetHost() == 'windows':
+        # extension_native_helpers.py currently expects to find libpandaexpress on sys.path.
         AddToPathEnv("PYTHONPATH", os.path.join(builtdir, "bin"))
         AddToPathEnv("PYTHONPATH", os.path.join(builtdir, "bin"))
-    else:
-        AddToPathEnv("PYTHONPATH", os.path.join(builtdir, "lib"))
+        AddToPathEnv("PATH", os.path.join(builtdir, "plugins"))
 
 
     # Now for the special (DY)LD_LIBRARY_PATH on Unix-esque systems.
     # Now for the special (DY)LD_LIBRARY_PATH on Unix-esque systems.
     if GetHost() != 'windows':
     if GetHost() != 'windows':