ceph/cmake/modules/Distutils.cmake
Kefu Chai ebfa2df2d5 cmake: do not pass unnecessary param to setup.py
--single-version-externally-managed is used for packaging python eggs
to deb. so the metadata can be stored in the egg, and can be accessed
by user if necessary, see [1]. but this does not apply to users who
just want to "make install" without packaging Ceph.

the problem is, if we pass --single-version-externally-managed to
setup.py, we need to pass --record or --root also. otherwise setuptools
complains:

error: You must specify --record or --root when building system packages

so in this change, we choose not to pass
"--single-version-externally-managed", unless $DESTDIR is set.

both "ceph.spec.in" and "debian/rules" set $DESTDIR when running "make
install". so we can always check $DESTDIR to tell if current "make
install" is launched by the packaging script or not. this might not be
accurate, but good enough. assuming enduser does not use DESTDIR when
running plain "make install".

--
[1] https://wiki.debian.org/Python/FAQ#How_should_we_package_Python_eggs.3F

Signed-off-by: Kefu Chai <kchai@redhat.com>
2018-11-20 22:20:41 +08:00

110 lines
4.8 KiB
CMake

include(CMakeParseArguments)
function(distutils_install_module name)
set(py_srcs setup.py README.rst requirements.txt test-requirements.txt bin ${name})
foreach(src ${py_srcs})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${src})
list(APPEND py_clone ${CMAKE_CURRENT_BINARY_DIR}/${src})
add_custom_command(
OUTPUT ${src}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${src}
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${src})
endif()
endforeach()
add_custom_target(${name}-clone ALL
DEPENDS ${py_clone})
cmake_parse_arguments(DU "" INSTALL_SCRIPT "" ${ARGN})
install(CODE "
set(options --prefix=${CMAKE_INSTALL_PREFIX})
if(DEFINED ENV{DESTDIR})
if(EXISTS /etc/debian_version)
list(APPEND options --install-layout=deb)
endif()
list(APPEND options
--root=\$ENV{DESTDIR}
--single-version-externally-managed)
if(NOT \"${DU_INSTALL_SCRIPT}\" STREQUAL \"\")
list(APPEND options --install-script=${DU_INSTALL_SCRIPT})
endif()
endif()
execute_process(
COMMAND ${PYTHON${PYTHON_VERSION}_EXECUTABLE}
setup.py install \${options}
WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")")
endfunction(distutils_install_module)
function(distutils_add_cython_module name src)
get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK)
# When using ccache, CMAKE_C_COMPILER is ccache executable absolute path
# and the actual C compiler is CMAKE_C_COMPILER_ARG1.
# However with a naive
# set(PY_CC ${compiler_launcher} ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1})
# distutils tries to execve something like "/usr/bin/cmake gcc" and fails.
# Removing the leading whitespace from CMAKE_C_COMPILER_ARG1 helps to avoid
# the failure.
string(STRIP "${CMAKE_C_COMPILER_ARG1}" c_compiler_arg1)
string(STRIP "${CMAKE_CXX_COMPILER_ARG1}" cxx_compiler_arg1)
# Note: no quotes, otherwise distutils will execute "/usr/bin/ccache gcc"
# CMake's implicit conversion between strings and lists is wonderful, isn't it?
string(REPLACE " " ";" cflags ${CMAKE_C_FLAGS})
list(APPEND cflags -iquote${CMAKE_SOURCE_DIR}/src/include -w)
set(PY_CC ${compiler_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} ${cflags})
set(PY_CXX ${compiler_launcher} ${CMAKE_CXX_COMPILER} ${cxx_compiler_arg1})
set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared")
add_custom_target(${name} ALL
COMMAND
env
CC="${PY_CC}"
CXX="${PY_CXX}"
LDSHARED="${PY_LDSHARED}"
OPT=\"-DNDEBUG -g -fwrapv -O2 -w\"
LDFLAGS=-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
CYTHON_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}
CEPH_LIBDIR=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
${PYTHON${PYTHON_VERSION}_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py
build --verbose --build-base ${CYTHON_MODULE_DIR}
--build-platlib ${CYTHON_MODULE_DIR}/lib.${PYTHON${PYTHON_VERSION}_VERSION_MAJOR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${src})
endfunction(distutils_add_cython_module)
function(distutils_install_cython_module name)
get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK)
set(PY_CC "${compiler_launcher} ${CMAKE_C_COMPILER}")
set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared")
install(CODE "
set(ENV{CC} \"${PY_CC}\")
set(ENV{LDSHARED} \"${PY_LDSHARED}\")
set(ENV{CPPFLAGS} \"-iquote${CMAKE_SOURCE_DIR}/src/include\")
set(ENV{LDFLAGS} \"-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\")
set(ENV{CYTHON_BUILD_DIR} \"${CMAKE_CURRENT_BINARY_DIR}\")
set(ENV{CEPH_LIBDIR} \"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\")
set(options --prefix=${CMAKE_INSTALL_PREFIX})
if(DEFINED ENV{DESTDIR})
if(EXISTS /etc/debian_version)
list(APPEND options --install-layout=deb)
endif()
list(APPEND options --root=\$ENV{DESTDIR})
else()
list(APPEND options --root=/)
endif()
execute_process(
COMMAND
${PYTHON${PYTHON_VERSION}_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py
build --verbose --build-base ${CYTHON_MODULE_DIR}
--build-platlib ${CYTHON_MODULE_DIR}/lib.${PYTHON${PYTHON_VERSION}_VERSION_MAJOR}
build_ext --cython-c-in-temp --build-temp ${CMAKE_CURRENT_BINARY_DIR} --cython-include-dirs ${PROJECT_SOURCE_DIR}/src/pybind/rados
install \${options} --single-version-externally-managed --record /dev/null
egg_info --egg-base ${CMAKE_CURRENT_BINARY_DIR}
--verbose
WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\"
RESULT_VARIABLE install_res)
if(NOT \"\${install_res}\" STREQUAL 0)
message(FATAL_ERROR \"Failed to build and install ${name} python module\")
endif()
")
endfunction(distutils_install_cython_module)