Skip to content

Building CUDA-Q with CUDAQ_ENABLE_REST=OFF fails with multiple compilation and linker errors #4042

@amccaskey

Description

@amccaskey

Description

When building CUDA-Q outside of the standard Docker image environment (e.g., on a bare host without OpenSSL or other REST-related dependencies), the CUDAQ_ENABLE_REST=OFF path has several breakages that prevent a successful build. These are a mix of unconditional link dependencies on REST-only libraries, missing stub implementations, and CMake cache variable propagation issues.

This issue tracks the full set of problems encountered and fixes needed to support CUDAQ_ENABLE_REST=OFF builds cleanly.

Environment

  • Building on a Linux host outside the official CUDA-Q Docker image
  • CMake configuration: -DCUDAQ_ENABLE_REST=OFF
  • OpenSSL is not available on the system

Issue 1: RestClient.cpp not compiled, causing undefined symbol errors

Error:

undefined reference to `cudaq::RestClient::post(...)'
undefined reference to `cudaq::RestClient::~RestClient()'
...

Root cause:

In runtime/common/CMakeLists.txt, RestClient.cpp was only added to cudaq-common via target_sources() inside the if(OPENSSL_FOUND) block. When OpenSSL is not found, the file is never compiled, but other translation units (e.g. Executor.cpp) unconditionally reference RestClient symbols.

Fix:

  1. Always compile RestClient.cpp into cudaq-common (add it to the COMMON_RUNTIME_SRC list unconditionally).
  2. In RestClient.cpp, guard the CPR-based implementation with #ifdef CUDAQ_RESTCLIENT_AVAILABLE and provide stub implementations in the #else branch that throw a descriptive runtime error.
  3. The #else branch also needs a dummy namespace cpr { struct SslOptions {}; } definition so that std::unique_ptr<cpr::SslOptions> in the RestClient header has a complete type at the point its destructor is instantiated.

Files changed:

  • runtime/common/CMakeLists.txt
  • runtime/common/RestClient.cpp

Issue 2: cudaq-qpud built despite CUDAQ_ENABLE_REST=OFF (CMake cache variable leak)

Error:

cannot find -lrest-remote-platform-server: No such file or directory

(during linking of bin/cudaq-qpud)

Root cause:

CUDAQ_ENABLE_REMOTE_SIM controls whether cudaq-qpud is built. When the build directory was previously configured with CUDAQ_ENABLE_REST=ON, the cached value of CUDAQ_ENABLE_REMOTE_SIM=ON persists. On reconfigure with CUDAQ_ENABLE_REST=OFF, the top-level CMakeLists.txt uses if (NOT DEFINED CUDAQ_ENABLE_REMOTE_SIM) which does not override the cached value, so cudaq-qpud is still built even though its REST dependencies no longer exist.

Fix:

In CMakeLists.txt, when CUDAQ_ENABLE_REST is OFF, force-set the dependent options:

if (NOT CUDAQ_ENABLE_REST)
  set(CUDAQ_ENABLE_REMOTE_SIM OFF CACHE BOOL "Enable building cudaq-qpud." FORCE)
  set(CUDAQ_TEST_REMOTE_SIM OFF CACHE BOOL "Run remote-sim tests." FORCE)
endif()

Files changed:

  • CMakeLists.txt (top-level)

Issue 3: Python extension unconditionally links unzip_util

Error:

cannot find -lunzip_util: No such file or directory

(during linking of _quakeDialects.cpython-*.so)

Root cause:

In python/extension/CMakeLists.txt, unzip_util is unconditionally linked into the Python extension target. However, unzip_util (which wraps minizip) is only defined/built when REST is enabled (it lives under runtime/cudaq/platform/default/rest_server/).

Fix:

Conditionally link unzip_util only when CUDAQ_ENABLE_REST is ON:

if (CUDAQ_ENABLE_REST)
  target_link_libraries(CUDAQuantumPythonSources.Extension INTERFACE unzip_util)
endif()

Files changed:

  • python/extension/CMakeLists.txt

Issue 4: Backend unit tests unconditionally link cudaq-rest-qpu

Error:

cannot find -lcudaq-rest-qpu: No such file or directory

(during linking of unittests/backends/qpp_observe/test_observe_backend)

Root cause:

In unittests/backends/CMakeLists.txt, the default_backend_unittest_libs list unconditionally includes cudaq-rest-qpu. This library is only built when REST is enabled (it is defined under runtime/cudaq/platform/default/rest/).

Fix:

Conditionally append cudaq-rest-qpu to the default test libs:

set(default_backend_unittest_libs
  fmt::fmt-header-only
  cudaq-common
  cudaq
  cudaq-builder
  cudaq-mlir-runtime
  cudaq-operator
  nvqir nvqir-qpp
  cudaq-platform-default
  gtest_main)
if (CUDAQ_ENABLE_REST)
  list(APPEND default_backend_unittest_libs cudaq-rest-qpu)
endif()

Files changed:

  • unittests/backends/CMakeLists.txt

Issue 5: CUDAToolkit_INCLUDE_DIRS generator expression malformed when list has multiple entries

Error (CMake generation):

Target "cudaq" INTERFACE_INCLUDE_DIRECTORIES property contains path:
"/path/to/cudaq/runtime/cudaq/" which is prefixed in the source directory.

Root cause:

In runtime/cudaq/CMakeLists.txt, the CUDA include directories were added as $<BUILD_INTERFACE:${CUDAToolkit_INCLUDE_DIRS}>. When CUDAToolkit_INCLUDE_DIRS is a semicolon-separated list, the generator expression only wraps the first entry; the remaining entries are bare source-tree paths which violate the install-interface check.

Fix:

Iterate over the list and wrap each entry individually:

set(_cudaq_cuda_include_genex "")
foreach(_cuda_inc IN LISTS CUDAToolkit_INCLUDE_DIRS)
  list(APPEND _cudaq_cuda_include_genex "$<BUILD_INTERFACE:${_cuda_inc}>")
endforeach()

target_include_directories(${LIBRARY_NAME}
  PUBLIC ...
         ${_cudaq_cuda_include_genex}
  ...)

Files changed:

  • runtime/cudaq/CMakeLists.txt

Summary of all files requiring changes

File Change
runtime/common/CMakeLists.txt Always compile RestClient.cpp; conditional cpr linking/defines
runtime/common/RestClient.cpp #ifdef guard + stub implementations
CMakeLists.txt (top-level) FORCE remote-sim options off when REST is disabled
python/extension/CMakeLists.txt Conditional unzip_util linking
unittests/backends/CMakeLists.txt Conditional cudaq-rest-qpu linking
runtime/cudaq/CMakeLists.txt Per-element BUILD_INTERFACE wrapping for CUDA includes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions