mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
CMake: Restructure multi-configuration binary directory layout
This changes the structure to use paths like `build/Release/lib` instead of `build/lib/Release`, so that the `build/Release` directory more closely mimics the structure of `build` when in single-configuration mode.
This commit is contained in:
parent
49865c103a
commit
059c78bade
@ -34,9 +34,6 @@ include(Interrogate) # Defines target_interrogate AND add_python_module
|
||||
include(RunPzip) # Defines run_pzip function
|
||||
include(Versioning) # Hooks 'add_library' to apply VERSION/SOVERSION
|
||||
|
||||
# Add the include path for source and header files generated by CMake
|
||||
include_directories("${PROJECT_BINARY_DIR}/include/${CMAKE_CFG_INTDIR}")
|
||||
|
||||
# Determine which trees to build.
|
||||
option(BUILD_DTOOL "Build the dtool source tree." ON)
|
||||
option(BUILD_PANDA "Build the panda source tree." ON)
|
||||
@ -90,7 +87,15 @@ if(INTERROGATE_PYTHON_INTERFACE)
|
||||
# for pytest before adding this test. If the user doesn't have pytest, we'd
|
||||
# like for the tests to fail.
|
||||
|
||||
add_test(pytest "${PYTHON_EXECUTABLE}" -m pytest "${PROJECT_SOURCE_DIR}/tests")
|
||||
if(CMAKE_CFG_INTDIR STREQUAL ".")
|
||||
set(_workdir "${PROJECT_BINARY_DIR}")
|
||||
else()
|
||||
set(_workdir "${PROJECT_BINARY_DIR}/$<CONFIG>")
|
||||
endif()
|
||||
|
||||
add_test(NAME pytest
|
||||
COMMAND "${PYTHON_EXECUTABLE}" -m pytest "${PROJECT_SOURCE_DIR}/tests"
|
||||
WORKING_DIRECTORY "${_workdir}")
|
||||
endif()
|
||||
|
||||
# Generate the Panda3DConfig.cmake file so find_package(Panda3D) works, and
|
||||
|
@ -6,7 +6,6 @@
|
||||
# Functions:
|
||||
# add_python_target(target [source1 [source2 ...]])
|
||||
# install_python_package(path [ARCH/LIB])
|
||||
# ensure_python_init(path [ARCH] [ROOT] [OVERWRITE])
|
||||
#
|
||||
|
||||
#
|
||||
@ -52,12 +51,21 @@ function(add_python_target target)
|
||||
target_link_libraries(${target} PKG::PYTHON)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(_outdir "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${slash_namespace}")
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${slash_namespace}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${_outdir}"
|
||||
OUTPUT_NAME "${basename}"
|
||||
PREFIX ""
|
||||
SUFFIX "${PYTHON_EXTENSION_SUFFIX}")
|
||||
|
||||
# This is explained over in CompilerFlags.cmake
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${_config}" _config)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY_${_config} "${_outdir}")
|
||||
endforeach(_config)
|
||||
|
||||
if(PYTHON_ARCH_INSTALL_DIR)
|
||||
install(TARGETS ${target} EXPORT "${export}" COMPONENT "${component}" DESTINATION "${PYTHON_ARCH_INSTALL_DIR}/${slash_namespace}")
|
||||
endif()
|
||||
@ -71,12 +79,6 @@ function(add_python_target target)
|
||||
|
||||
endif()
|
||||
|
||||
set(keywords OVERWRITE ARCH)
|
||||
if(NOT slash_namespace MATCHES ".*/.*")
|
||||
list(APPEND keywords ROOT)
|
||||
endif()
|
||||
ensure_python_init("${PROJECT_BINARY_DIR}/${slash_namespace}" ${keywords})
|
||||
|
||||
endfunction(add_python_target)
|
||||
|
||||
#
|
||||
@ -131,7 +133,13 @@ function(install_python_package package_name)
|
||||
endif()
|
||||
endforeach(arg)
|
||||
|
||||
set(path "${PROJECT_BINARY_DIR}/${package_name}")
|
||||
if(NOT DEFINED src_path AND type STREQUAL "ARCH" AND WIN32 AND NOT CYGWIN)
|
||||
# Win32 needs a special fixup so the DLLs in "bin" can be on the path;
|
||||
# let's set src_path to the directory containing our fixup __init__.py
|
||||
set(src_path "${CMAKE_SOURCE_DIR}/cmake/templates/win32_python")
|
||||
endif()
|
||||
|
||||
set(path "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${package_name}")
|
||||
|
||||
set(args -D "OUTPUT_DIR=${path}")
|
||||
if(src_path)
|
||||
@ -153,120 +161,3 @@ function(install_python_package package_name)
|
||||
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)
|
||||
|
20
cmake/templates/win32_python/__init__.py
Normal file
20
cmake/templates/win32_python/__init__.py
Normal file
@ -0,0 +1,20 @@
|
||||
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
|
@ -29,9 +29,9 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Set up the output directory structure, mimicking that of makepanda
|
||||
set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/cmake")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib")
|
||||
set(MODULE_DESTINATION "lib")
|
||||
|
||||
# Runtime code assumes that dynamic modules have a "lib" prefix; Windows
|
||||
@ -44,12 +44,29 @@ if(WIN32)
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
|
||||
|
||||
# On Windows, modules (DLLs) are located in bin; lib is just for .lib files
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(MODULE_DESTINATION "bin")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Since we're using CMAKE_CFG_INTDIR to put everything in a
|
||||
# configuration-specific subdirectory when building on a multi-config
|
||||
# generator, we need to suppress the usual configuration name appending
|
||||
# behavior of CMake. In CMake 3.4+, it will suppress this behavior
|
||||
# automatically if the *_OUTPUT_DIRECTORY property contains a generator
|
||||
# expresssion, but:
|
||||
# a) As of this writing we support as early as CMake 3.0.2
|
||||
# b) ${CMAKE_CFG_INTDIR} doesn't actually expand to a generator expression
|
||||
#
|
||||
# So, to solve both of these, let's just do this:
|
||||
foreach(_type RUNTIME ARCHIVE LIBRARY)
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${_config}" _config)
|
||||
set(CMAKE_${_type}_OUTPUT_DIRECTORY_${_config} "${CMAKE_${_type}_OUTPUT_DIRECTORY}")
|
||||
endforeach(_config)
|
||||
endforeach(_type)
|
||||
|
||||
# Set warning levels
|
||||
if(MSVC)
|
||||
string(APPEND CMAKE_C_FLAGS " /W3")
|
||||
|
@ -193,8 +193,8 @@ else()
|
||||
set(intdir "${CMAKE_BUILD_TYPE}")
|
||||
endif()
|
||||
|
||||
configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/include/${intdir}/dtool_config.h")
|
||||
install(FILES "${PROJECT_BINARY_DIR}/include/${intdir}/dtool_config.h"
|
||||
configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/${intdir}/include/dtool_config.h")
|
||||
install(FILES "${PROJECT_BINARY_DIR}/${intdir}/include/dtool_config.h"
|
||||
COMPONENT CoreDevel
|
||||
DESTINATION include/panda3d)
|
||||
|
||||
|
@ -91,7 +91,7 @@ add_component_library(p3dtoolbase NOINIT SYMBOL BUILDING_DTOOL_DTOOLBASE
|
||||
# Help other libraries find the autogenerated headers
|
||||
target_include_directories(p3dtoolbase PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/${CMAKE_CFG_INTDIR}>)
|
||||
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}>/include)
|
||||
target_link_libraries(p3dtoolbase PKG::EIGEN PKG::THREADS)
|
||||
target_interrogate(p3dtoolbase ${P3DTOOLBASE_SOURCES} EXTENSIONS ${P3DTOOLBASE_IGATEEXT})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user