Back to home page

EIC code displayed by LXR

 
 

    


Warning, /acts/cmake/ActsCodegen.cmake is written in an unsupported language. File is not indexed.

0001 include_guard(GLOBAL)
0002 
0003 if(NOT ACTS_USE_SYSTEM_LIBS)
0004     message(STATUS "Configuring codegen: preparing uv")
0005 
0006     find_program(uv_exe uv)
0007 
0008     set(_uv_version "0.7.19")
0009     set(_base_url
0010         "https://github.com/astral-sh/uv/releases/download/${_uv_version}"
0011     )
0012 
0013     if(uv_exe STREQUAL "uv_exe-NOTFOUND")
0014         message(STATUS "uv not found, installing it")
0015 
0016         if(NOT APPLE AND NOT UNIX)
0017             message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
0018         endif()
0019 
0020         if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
0021             if(APPLE)
0022                 set(UV_NAME "${_base_url}/uv-x86_64-apple-darwin.tar.gz")
0023                 set(UV_HASH
0024                     "SHA256=698d24883fd441960fb4bc153b7030b89517a295502017ff3fdbba2fb0a0aa67"
0025                 )
0026             elseif(UNIX)
0027                 set(UV_URL "${_base_url}/uv-x86_64-unknown-linux-musl.tar.gz")
0028                 set(UV_HASH
0029                     "SHA256=6236ed00a7442ab2c0f56f807d5a3331f3fb5c7640a357482fbc8492682641b2"
0030                 )
0031             endif()
0032         elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm)|(ARM)|(aarch64)")
0033             if(APPLE)
0034                 set(UV_URL "${_base_url}/uv-aarch64-apple-darwin.tar.gz")
0035                 set(UV_HASH
0036                     "SHA256=698d24883fd441960fb4bc153b7030b89517a295502017ff3fdbba2fb0a0aa67"
0037                 )
0038             elseif(UNIX)
0039                 set(UV_URL "${_base_url}/uv-aarch64-unknown-linux-musl.tar.gz")
0040                 set(UV_HASH
0041                     "SHA256=e83c7c6d86c8e7456078c736a72550ce20222df8083f9317fc58cd49422ce5eb"
0042                 )
0043             endif()
0044         else()
0045             message(
0046                 FATAL_ERROR
0047                 "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}"
0048             )
0049         endif()
0050 
0051         message(STATUS "Downloading uv from ${UV_URL}")
0052         set(UV_DIR "${CMAKE_BINARY_DIR}/uv")
0053         file(DOWNLOAD ${UV_URL} ${UV_DIR}/uv.tar.gz EXPECTED_HASH ${UV_HASH})
0054 
0055         file(ARCHIVE_EXTRACT INPUT ${UV_DIR}/uv.tar.gz DESTINATION ${UV_DIR})
0056 
0057         file(REMOVE ${UV_DIR}/uv.tar.gz)
0058 
0059         file(GLOB uv_extracted ${UV_DIR}/uv*)
0060         message(STATUS "Extracted uv: ${uv_extracted}")
0061 
0062         find_program(uv_exe uv PATHS ${uv_extracted} REQUIRED NO_DEFAULT_PATH)
0063     endif()
0064 
0065     message(STATUS "Found uv: ${uv_exe}")
0066 
0067     execute_process(
0068         COMMAND ${uv_exe} --version
0069         OUTPUT_VARIABLE uv_version
0070         OUTPUT_STRIP_TRAILING_WHITESPACE
0071     )
0072     message(STATUS "uv version: ${uv_version}")
0073 else()
0074     message(
0075         STATUS
0076         "Configuring codegen in offline mode: preparing virtual environment"
0077     )
0078 
0079     find_package(Python REQUIRED COMPONENTS Interpreter)
0080 
0081     # The idea of the following code is to create a "nested" Python
0082     # environment; we grab the source of the packages in the current env
0083     # whether that is a virtual environment, a system environment, or a Spack
0084     # environment, and copy that into a newly created virtual environment.
0085     # This strategy comes from https://stackoverflow.com/a/75545634
0086     # First, we grab the Python package directory for the outside environment.
0087     execute_process(
0088         COMMAND
0089             ${Python_EXECUTABLE} -c
0090             "import sysconfig; print(sysconfig.get_paths()['purelib'])"
0091         OUTPUT_VARIABLE _python_package_dir
0092         OUTPUT_STRIP_TRAILING_WHITESPACE
0093     )
0094 
0095     # Then we create a new virtual env using the venv package which is built
0096     # into Python these days.
0097     execute_process(
0098         COMMAND ${Python_EXECUTABLE} -m venv ${CMAKE_BINARY_DIR}/codegen_venv
0099     )
0100     # Now, we get the package directory for the newly created virtual
0101     # environment.
0102     execute_process(
0103         COMMAND
0104             ${CMAKE_BINARY_DIR}/codegen_venv/bin/python -c
0105             "import sysconfig; print(sysconfig.get_paths()['purelib'])"
0106         OUTPUT_VARIABLE _python_nested_package_dir
0107         OUTPUT_STRIP_TRAILING_WHITESPACE
0108     )
0109 
0110     # Finally, we write the path found in the outside virtual env into the
0111     # new virtual env as described in the StackOverflow answer.
0112     file(
0113         WRITE
0114         "${_python_nested_package_dir}/_base_packages.pth"
0115         ${_python_package_dir}
0116     )
0117 
0118     message(
0119         STATUS
0120         "Virtual environment based on ${_python_package_dir} created in ${CMAKE_BINARY_DIR}/codegen_venv/"
0121     )
0122 endif()
0123 
0124 function(acts_code_generation)
0125     set(options ISOLATED)
0126     set(oneValueArgs ADD_TO_TARGET PYTHON PYTHON_VERSION OUTPUT)
0127     set(multiValueArgs DEPENDS WITH_REQUIREMENTS WITH)
0128     cmake_parse_arguments(
0129         PARSE_ARGV
0130         0
0131         ARGS
0132         "${options}"
0133         "${oneValueArgs}"
0134         "${multiValueArgs}"
0135     )
0136 
0137     if(NOT DEFINED ARGS_PYTHON_VERSION)
0138         set(ARGS_PYTHON_VERSION "3.13")
0139     endif()
0140 
0141     if(NOT DEFINED ARGS_PYTHON)
0142         message(SEND_ERROR "No python script specified")
0143         return()
0144     endif()
0145 
0146     if(NOT EXISTS ${ARGS_PYTHON})
0147         if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_PYTHON})
0148             set(ARGS_PYTHON ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_PYTHON})
0149         else()
0150             message(SEND_ERROR "Python script not found: ${ARGS_PYTHON}")
0151             return()
0152         endif()
0153     endif()
0154 
0155     set(_arg_isolated "")
0156     if(ARGS_ISOLATED)
0157         set(_arg_isolated "--isolated")
0158     endif()
0159 
0160     set(_depends "${ARGS_PYTHON}")
0161     set(_with_args "")
0162     foreach(_requirement ${ARGS_WITH_REQUIREMENTS})
0163         list(APPEND _depends ${_requirement})
0164         list(APPEND _with_args "--with-requirements;${_requirement}")
0165     endforeach()
0166 
0167     foreach(_requirement ${ARGS_WITH})
0168         list(APPEND _with_args "--with;${_requirement}")
0169         if(IS_DIRECTORY ${_requirement})
0170             if(NOT ACTS_USE_SYSTEM_LIBS)
0171                 file(GLOB_RECURSE _depends_py ${_requirement}/*)
0172                 list(APPEND _depends ${_depends_py})
0173             else()
0174                 # If we are not using uv, then we use pip to install the
0175                 # package into the virtual environment in the build directory.
0176                 # The --no-build-isolation flag ensures that we don't
0177                 # automatically download setuptools. The --no-index flag
0178                 # ensures that nothing can be downloaded ever, and the
0179                 # --no-deps is necessary to convince pip that the dependencies
0180                 # are already in the environment.
0181                 execute_process(
0182                     COMMAND
0183                         ${CMAKE_BINARY_DIR}/codegen_venv/bin/python -m pip
0184                         install --no-build-isolation --no-index --no-deps
0185                         ${_requirement}
0186                     OUTPUT_QUIET
0187                 )
0188             endif()
0189         endif()
0190     endforeach()
0191 
0192     get_filename_component(_output_name ${ARGS_OUTPUT} NAME)
0193 
0194     string(SHA1 _output_hash ${_output_name})
0195 
0196     set(_codegen_root ${CMAKE_CURRENT_BINARY_DIR}/codegen/${_output_hash})
0197     set(_output_file ${_codegen_root}/${ARGS_OUTPUT})
0198 
0199     get_filename_component(_output_dir ${_output_file} DIRECTORY)
0200     file(MAKE_DIRECTORY ${_output_dir})
0201 
0202     if(NOT ACTS_USE_SYSTEM_LIBS)
0203         add_custom_command(
0204             OUTPUT ${_output_file}
0205             COMMAND
0206                 env -i UV_NO_CACHE=1 ${uv_exe} run --quiet --python
0207                 ${ARGS_PYTHON_VERSION} --no-project ${_arg_isolated}
0208                 ${_with_args} ${ARGS_PYTHON} ${_output_file}
0209             DEPENDS ${_depends}
0210             COMMENT "Generating ${ARGS_OUTPUT}"
0211             VERBATIM
0212         )
0213     else()
0214         # If not using uv, just run Python from the virtual environment that
0215         # we created above.
0216         add_custom_command(
0217             OUTPUT ${_output_file}
0218             COMMAND
0219                 ${CMAKE_BINARY_DIR}/codegen_venv/bin/python ${ARGS_PYTHON}
0220                 ${_output_file}
0221             DEPENDS ${_depends}
0222             COMMENT "Generating ${ARGS_OUTPUT}"
0223             VERBATIM
0224         )
0225     endif()
0226 
0227     set(_internal_target codegen_${_output_hash}_Internal)
0228     add_custom_target(${_internal_target} DEPENDS ${_output_file})
0229 
0230     add_dependencies(${ARGS_ADD_TO_TARGET} ${_internal_target})
0231     target_include_directories(${ARGS_ADD_TO_TARGET} PRIVATE ${_codegen_root})
0232 endfunction()