CMake: Move __init__.py generation to Python.cmake
This also allows us to generate a suitable __init__.py for fixing up PATH and/or __path__ on platforms that need it to properly import Python extension modules.
This commit is contained in:
parent
73e273e782
commit
53920e7aee
|
|
@ -172,8 +172,6 @@ except ImportError as err:
|
|||
")
|
||||
endforeach()
|
||||
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/pandac/__init__.py" "")
|
||||
|
||||
# Now install ourselves:
|
||||
install_python_package("${PROJECT_BINARY_DIR}/pandac" LIB)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -302,10 +302,6 @@ endfunction(add_python_module)
|
|||
|
||||
|
||||
if(INTERROGATE_PYTHON_INTERFACE AND BUILD_SHARED_LIBS)
|
||||
# We have to create an __init__.py so that Python 2.x can recognize 'panda3d'
|
||||
# as a package.
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/panda3d/__init__.py" "")
|
||||
|
||||
# The Interrogate path needs to be installed to the architecture-dependent
|
||||
# Python directory.
|
||||
install_python_package("${PROJECT_BINARY_DIR}/panda3d")
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
# Functions:
|
||||
# add_python_target(target [source1 [source2 ...]])
|
||||
# install_python_package(path [ARCH/LIB])
|
||||
# ensure_python_init(path [ARCH] [ROOT] [OVERWRITE])
|
||||
#
|
||||
|
||||
#
|
||||
|
|
@ -47,6 +48,12 @@ function(add_python_target target)
|
|||
install(TARGETS ${target} DESTINATION lib)
|
||||
endif()
|
||||
|
||||
set(keywords OVERWRITE ARCH)
|
||||
if(NOT underscore_namespace MATCHES ".*_.*")
|
||||
list(APPEND keywords ROOT)
|
||||
endif()
|
||||
ensure_python_init("${PROJECT_BINARY_DIR}/${slash_namespace}" ${keywords})
|
||||
|
||||
endfunction(add_python_target)
|
||||
|
||||
#
|
||||
|
|
@ -90,6 +97,8 @@ function(install_python_package path)
|
|||
COMMAND "${PYTHON_EXECUTABLE}" -OO -m compileall -q "${relpath}")
|
||||
endif()
|
||||
|
||||
ensure_python_init("${path}")
|
||||
|
||||
set(dir ${PYTHON_${type}_INSTALL_DIR})
|
||||
if(dir)
|
||||
install(DIRECTORY "${path}" DESTINATION "${dir}"
|
||||
|
|
@ -97,3 +106,114 @@ function(install_python_package path)
|
|||
endif()
|
||||
|
||||
endfunction(install_python_package)
|
||||
|
||||
#
|
||||
# Function: ensure_python_init(path [ARCH] [ROOT] [OVERWRITE])
|
||||
#
|
||||
# Makes sure that the directory - at `path` - contains a file named
|
||||
# '__init__.py', which is necessary for Python to recognize the directory as a
|
||||
# package.
|
||||
#
|
||||
# ARCH, if specified, means that this is a binary package, and the build tree
|
||||
# might contain configuration-specific subdirectories. The __init__.py will be
|
||||
# generated with a function that ensures that the appropriate configuration
|
||||
# subdirectory is in the path.
|
||||
#
|
||||
# ROOT, if specified, means that the directory may sit directly adjacent to a
|
||||
# 'bin' directory, which should be added to the DLL search path on Windows.
|
||||
#
|
||||
# OVERWRITE causes the __init__.py file to be overwritten if one is already
|
||||
# present.
|
||||
#
|
||||
function(ensure_python_init path)
|
||||
set(arch OFF)
|
||||
set(root OFF)
|
||||
set(overwrite OFF)
|
||||
|
||||
foreach(arg ${ARGN})
|
||||
if(arg STREQUAL "ARCH")
|
||||
set(arch ON)
|
||||
elseif(arg STREQUAL "ROOT")
|
||||
set(root ON)
|
||||
elseif(arg STREQUAL "OVERWRITE")
|
||||
set(overwrite ON)
|
||||
else()
|
||||
message(FATAL_ERROR "ensure_python_init got unexpected argument: ${arg}")
|
||||
endif()
|
||||
endforeach(arg)
|
||||
|
||||
set(init_filename "${path}/__init__.py")
|
||||
if(EXISTS "${init_filename}" AND NOT overwrite)
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(WRITE "${init_filename}" "")
|
||||
|
||||
if(arch AND NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
|
||||
# ARCH set, and this is a multi-configuration generator
|
||||
|
||||
set(configs "${CMAKE_CONFIGURATION_TYPES}")
|
||||
|
||||
# Debug should be at the end (highest preference)
|
||||
list(REMOVE_ITEM configs "Debug")
|
||||
list(APPEND configs "Debug")
|
||||
|
||||
string(REPLACE ";" "', '" configs "${configs}")
|
||||
|
||||
file(APPEND "${init_filename}" "
|
||||
def _fixup_path():
|
||||
try:
|
||||
path = __path__[0]
|
||||
except (NameError, IndexError):
|
||||
return # Not a package, or not on filesystem
|
||||
|
||||
import os
|
||||
abspath = os.path.abspath(path)
|
||||
|
||||
newpath = None
|
||||
for config in ['${configs}']:
|
||||
cfgpath = os.path.join(abspath, config)
|
||||
if not os.path.isdir(cfgpath):
|
||||
continue
|
||||
|
||||
newpath = cfgpath
|
||||
|
||||
if config.lower() == os.environ.get('CMAKE_CONFIGURATION', '').lower():
|
||||
break
|
||||
|
||||
if newpath:
|
||||
__path__.insert(0, newpath)
|
||||
|
||||
_fixup_path()
|
||||
del _fixup_path
|
||||
")
|
||||
endif()
|
||||
|
||||
if(root AND WIN32 AND NOT CYGWIN)
|
||||
# ROOT set, and this is Windows
|
||||
|
||||
file(APPEND "${init_filename}" "
|
||||
def _fixup_dlls():
|
||||
try:
|
||||
path = __path__[0]
|
||||
except (NameError, IndexError):
|
||||
return # Not a package, or not on filesystem
|
||||
|
||||
import os
|
||||
|
||||
relpath = os.path.relpath(path, __path__[-1])
|
||||
dll_path = os.path.abspath(os.path.join(__path__[-1], '../bin', relpath))
|
||||
if not os.path.isdir(dll_path):
|
||||
return
|
||||
|
||||
os_path = os.environ.get('PATH', '')
|
||||
os_path = os_path.split(os.pathsep) if os_path else []
|
||||
os_path.insert(0, dll_path)
|
||||
os.environ['PATH'] = os.pathsep.join(os_path)
|
||||
|
||||
_fixup_dlls()
|
||||
del _fixup_dlls
|
||||
")
|
||||
endif()
|
||||
|
||||
endfunction(ensure_python_init)
|
||||
|
|
|
|||
|
|
@ -47,9 +47,6 @@ if(HAVE_PYTHON)
|
|||
FILES_MATCHING PATTERN "*.py")
|
||||
endforeach()
|
||||
|
||||
# We also need an __init__.py file, which we have to generate:
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/direct/__init__.py" "")
|
||||
|
||||
# Install all files
|
||||
install_python_package("${PROJECT_BINARY_DIR}/direct" LIB)
|
||||
endif()
|
||||
|
|
|
|||
Loading…
Reference in New Issue