mstorsjo wrote:

Now I've had time to study lldb-rpc-gen a little bit closer...

For myself and others, to clarify what lldb-rpc-gen does (as how command 
options flow into it that aren't immediately obvious): It is a tool that 
includes clang tooling libraries. It runs at the regular LLVM/LLDB build 
directory, reading `compile_commans.json` from there, then using them to figure 
out how to compile certain files, and use those to preprocess(?) and parse some 
LLDB headers.

This is in a rather large contrast to other existing build time code generation 
tools (like `llvm-tblgen` or `clang-tidy-confusable-chars-gen`); those are 
relatively small executables that on their own generate code to be used during 
the build - and those tools are mostly independent of the build environment.

Your initial attempts seem quite close to actually getting this right (already 
attempting to use `get_host_tool_path` etc), but both the initial attempt and 
this one missed one subtle detail: The cmake functions `get_host_tool_path` and 
`setup_host_tool` do take a cmake variable name `LLDB_RPC_GEN_EXE` as input, 
which allows the user to set this variable if they want to point to the tool, 
but it doesn't set the final path in that variable, but in a different variable.

I managed to simplify the setup of all this, and got a cross build to actually 
successfully build and use a nested cmake build to build `lldb-rpc-gen`, just 
like it does for other tools. My diff to achieve this looks like this:

```diff
diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig
.cmake
index 88b4eca4112c..f108110ff94b 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -334,11 +334,4 @@ else()
 endif()
 
 
-if (CMAKE_CROSSCOMPILING)
-  set(LLDB_BUILD_LLDBRPC OFF CACHE BOOL "")
-  get_host_tool_path(lldb-rpc-gen LLDB_RPC_GEN_EXE lldb_rpc_gen_exe 
lldb_rpc_gen_target)
-else()
-  set(LLDB_BUILD_LLDBRPC ON CACHE BOOL "")
-endif()
-
 include(LLDBGenerateConfig)
diff --git a/lldb/tools/CMakeLists.txt b/lldb/tools/CMakeLists.txt
index e2f039527ad7..d3096765ad8f 100644
--- a/lldb/tools/CMakeLists.txt
+++ b/lldb/tools/CMakeLists.txt
@@ -10,9 +10,7 @@ add_subdirectory(lldb-fuzzer EXCLUDE_FROM_ALL)
 
 add_lldb_tool_subdirectory(lldb-instr)
 add_lldb_tool_subdirectory(lldb-dap)
-if (LLDB_BUILD_LLDBRPC)
-  add_lldb_tool_subdirectory(lldb-rpc-gen)
-endif()
+add_lldb_tool_subdirectory(lldb-rpc-gen)
 if (LLDB_CAN_USE_LLDB_RPC_SERVER)
   add_subdirectory(lldb-rpc)
 endif()
diff --git a/lldb/tools/lldb-rpc-gen/CMakeLists.txt 
b/lldb/tools/lldb-rpc-gen/CMakeLists.txt
index 4b2e5d7483a5..7a50072865ab 100644
--- a/lldb/tools/lldb-rpc-gen/CMakeLists.txt
+++ b/lldb/tools/lldb-rpc-gen/CMakeLists.txt
@@ -18,11 +18,6 @@ add_lldb_tool(lldb-rpc-gen
       Support
   )
 
-if (CMAKE_CROSSCOMPILING)
-  setup_host_tool(lldb-rpc-gen LLDB_RPC_GEN_EXE lldb_rpc_gen_exe 
lldb_rpc_gen_target)
-else()
-  if (NOT DEFINED LLDB_RPC_GEN_EXE)
-    set(LLDB_RPC_GEN_EXE $<TARGET_FILE:lldb-rpc-gen> CACHE STRING "Executable 
that generates lldb-rpc-server")
-  endif()
-endif()
+add_dependencies(lldb-rpc-gen clang-resource-headers)
 
+setup_host_tool(lldb-rpc-gen LLDB_RPC_GEN_EXE lldb_rpc_gen_exe 
lldb_rpc_gen_target)
diff --git a/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake 
b/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
index a4cacf8692a8..91188ca393a1 100644
--- a/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
+++ b/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
@@ -1,9 +1,3 @@
-if (NOT DEFINED LLDB_RPC_GEN_EXE)
-  message(FATAL_ERROR
-    "Unable to generate lldb-rpc sources because LLDB_RPC_GEN_EXE is not
-    defined. If you are cross-compiling, please build lldb-rpc-gen for your 
host
-    platform.")
-endif()
 set(lldb_rpc_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
 set(lldb_rpc_server_generated_source_dir "${lldb_rpc_generated_dir}/server")
 
@@ -60,14 +54,14 @@ add_custom_command(OUTPUT ${lldb_rpc_gen_byproducts}
   COMMAND ${CMAKE_COMMAND} -E make_directory
     ${lldb_rpc_server_generated_source_dir}
 
-  COMMAND ${LLDB_RPC_GEN_EXE}
+  COMMAND ${lldb_rpc_gen_exe}
     -p ${CMAKE_BINARY_DIR}
     --output-dir=${lldb_rpc_generated_dir}
     ${sysroot_arg}
     --extra-arg="-USWIG"
     ${api_headers}
 
-  DEPENDS ${LLDB_RPC_GEN_EXE} ${api_headers}
+  DEPENDS ${lldb_rpc_gen_target} ${api_headers}
   COMMENT "Generating sources for lldb-rpc-server..."
   WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
 )
```

I had to add the dependency on `clang-resource-headers`, so that the tool 
`<builddir>/NATIVE/bin/lldb-rpc-gen` gets the clang resource headers it expects 
in `<builddir>/NATIVE/lib/clang/<version>/include`.


However, even with all this in place, I fear that it may be brittle - in 
particular during cross builds. (I wouldn't always assume that the clang 
tooling flawlessly would figure out the ins and outs if I'm using an unusual 
cross compiler.)

And secondly - building `lldb-rpc-gen` requires building most of LLVM and 
Clang, which adds a lot of extra work to cross builds. Currently, when cross 
compiling, it builds `llvm-tblgen`, `clang-tblgen` and `lldb-tblgen` and 
similar tools natively - which is extra overhead to the build. But this is 
usually just a couple hundred object files - so it's easier to just let cmake 
do that, rather than to fiddle with manually pointing to a preexisting native 
build (with the risk of it being out of sync etc). But here, this essentially 
would make the nested native build duplicate 70% of the whole llvm build - 
which is quite out of scope for what's probably expected.


I also see that the existing logic for setting up lldb-rpc here does seem to 
try to account for this to some extent:
```
# In a cross-compile build, we need to skip building the generated
# lldb-rpc sources in the first phase of host build so that they can
# get built using the just-built Clang toolchain in the second phase.
if ((CMAKE_CROSSCOMPILING OR LLVM_HOST_TRIPLE MATCHES 
"${LLVM_DEFAULT_TARGET_TRIPLE}") AND
```
But it's very unclear to me exactly how this is meant to work - the condition 
seems to miss a negation with regards to `CMAKE_CROSS_COMPILING`? (And the 
check for `LLVM_HOST_TRIPLE` and `LLVM_DEFAULT_TARGET_TRIPLE` seems unusual 
here - we don't normally check `LLVM_DEFAULT_TARGET_TRIPLE` like that - just 
checking `CMAKE_CROSSCOMPILING` should be enough.)

So we can probably do something like my inline diff above, to make the build 
succeed _if_ we want to build this, but we probably should default to having 
this disabled in general:
```diff

diff --git a/lldb/cmake/modules/LLDBConfig.cmake 
b/lldb/cmake/modules/LLDBConfig.cmake
index f108110ff94b..388e37d0da78 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -323,14 +323,16 @@ else()
     set(LLDB_CAN_USE_DEBUGSERVER OFF)
 endif()
 
-# In a cross-compile build, we need to skip building the generated
-# lldb-rpc sources in the first phase of host build so that they can
-# get built using the just-built Clang toolchain in the second phase.
-if ((CMAKE_CROSSCOMPILING OR LLVM_HOST_TRIPLE MATCHES 
"${LLVM_DEFAULT_TARGET_TRIPLE}") AND
-    CMAKE_SYSTEM_NAME MATCHES 
"AIX|Android|Darwin|FreeBSD|Linux|NetBSD|OpenBSD|Windows")
-  set(LLDB_CAN_USE_LLDB_RPC_SERVER ON)
-else()
-  set(LLDB_CAN_USE_LLDB_RPC_SERVER OFF)
+if (NOT DEFINED LLDB_CAN_USE_LLDB_RPC_SERVER)
+  # In a cross-compile build, we don't want to try to build a lldb-rpc-gen, as
+  # as that essentially forces rebuilding a whole separate native copy of 
clang.
+  # Allow the caller to set this variable manually to opt in/out of it.
+  if (NOT CMAKE_CROSSCOMPILING AND
+      CMAKE_SYSTEM_NAME MATCHES 
"AIX|Android|Darwin|FreeBSD|Linux|NetBSD|OpenBSD|Windows")
+    set(LLDB_CAN_USE_LLDB_RPC_SERVER ON)
+  else()
+    set(LLDB_CAN_USE_LLDB_RPC_SERVER OFF)
+  endif()
 endif()

```

https://github.com/llvm/llvm-project/pull/151603
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to