Skip to content

Commit 87de617

Browse files
committed
Improve dependencies superbuild for Windows
Closes lifting-bits#735
1 parent 9816ccc commit 87de617

6 files changed

Lines changed: 94 additions & 20 deletions

File tree

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858

5959
- name: Build dependencies
6060
run: |
61-
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX"
61+
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
6262
cmake --build dependencies/build
6363
6464
- name: Python venv for tests
@@ -69,7 +69,7 @@ jobs:
6969
- name: Build remill
7070
run: |
7171
. .venv/bin/activate
72-
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX;$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
72+
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
7373
cmake --build build
7474
7575
- name: Install remill
@@ -116,7 +116,7 @@ jobs:
116116

117117
- name: Build dependencies
118118
run: |
119-
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX"
119+
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
120120
cmake --build dependencies/build
121121
122122
- name: Python venv for tests
@@ -127,7 +127,7 @@ jobs:
127127
- name: Build remill
128128
run: |
129129
. .venv/bin/activate
130-
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX;$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
130+
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
131131
cmake --build build
132132
133133
- name: Install remill

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,21 @@ cmake -G Ninja -S dependencies -B dependencies/build
6868
cmake --build dependencies/build
6969

7070
# Step 2: Build remill
71-
cmake -G Ninja -B build -DCMAKE_PREFIX_PATH=$(pwd)/dependencies/install -DCMAKE_BUILD_TYPE=Release
71+
cmake -G Ninja -B build -DCMAKE_PREFIX_PATH:PATH=$(pwd)/dependencies/install -DCMAKE_BUILD_TYPE=Release
7272
cmake --build build
7373
```
7474

75-
### Windows (requires clang or clang-cl)
75+
### Windows (requires clang-cl)
7676

7777
**Note**: This requires running from a Visual Studio developer prompt.
7878

7979
```bash
8080
# Step 1: Build dependencies
81-
cmake -G Ninja -S dependencies -B dependencies/build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
81+
cmake -G Ninja -S dependencies -B dependencies/build -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
8282
cmake --build dependencies/build
8383

8484
# Step 2: Build remill
85-
cmake -G Ninja -B build -DCMAKE_PREFIX_PATH=%CD%/dependencies/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release
85+
cmake -G Ninja -B build -DCMAKE_PREFIX_PATH:PATH=%CD%/dependencies/install -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Release
8686
cmake --build build
8787
```
8888

@@ -94,11 +94,11 @@ brew install llvm@17
9494
LLVM_PREFIX=$(brew --prefix llvm@17)
9595

9696
# Build dependencies with external LLVM
97-
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX"
97+
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
9898
cmake --build dependencies/build
9999

100100
# Build remill
101-
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX;$(pwd)/dependencies/install" -DCMAKE_BUILD_TYPE=Release
101+
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$(pwd)/dependencies/install" -DCMAKE_BUILD_TYPE=Release
102102
cmake --build build
103103
```
104104

@@ -110,6 +110,6 @@ cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON
110110
cmake --build dependencies/build
111111

112112
# Build remill
113-
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH=$LLVM_PREFIX;$(pwd)/dependencies/install" -DCMAKE_BUILD_TYPE=Release
113+
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$(pwd)/dependencies/install" -DCMAKE_BUILD_TYPE=Release
114114
cmake --build build
115115
```

dependencies/CMakeLists.txt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ simple_git(https://github.com/google/googletest v1.17.0
5151

5252
include(xed.cmake)
5353

54-
if(NOT USE_EXTERNAL_LLVM)
54+
set(LLVM_CONFIG "${CMAKE_INSTALL_PREFIX}/lib/cmake/llvm/LLVMConfig.cmake")
55+
if(USE_EXTERNAL_LLVM)
56+
# Create a forwarding LLVMConfig.cmake file that adds the external LLVM to CMAKE_PREFIX_PATH
57+
# and then includes the external LLVMConfig.cmake
58+
if(NOT EXISTS "${LLVM_DIR}/LLVMConfig.cmake")
59+
message(FATAL_ERROR "LLVMConfig.cmake not found in LLVM_DIR (${LLVM_DIR})")
60+
endif()
61+
file(WRITE "${CMAKE_INSTALL_PREFIX}/lib/cmake/llvm/LLVMConfig.cmake"
62+
"if(NOT \"${LLVM_INSTALL_PREFIX}\" IN_LIST CMAKE_PREFIX_PATH)\n"
63+
" list(PREPEND CMAKE_PREFIX_PATH \"${LLVM_INSTALL_PREFIX}\")\n"
64+
" set(CMAKE_PREFIX_PATH \"\${CMAKE_PREFIX_PATH}\" CACHE PATH \"\" FORCE)\n"
65+
" message(STATUS \"Updating CMAKE_PREFIX_PATH: \${CMAKE_PREFIX_PATH}\")\n"
66+
"endif()\n"
67+
"include(\"${LLVM_DIR}/LLVMConfig.cmake\")\n"
68+
)
69+
else()
70+
file(REMOVE "${LLVM_CONFIG}")
5571
include(llvm.cmake)
5672
endif()

dependencies/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ cmake -B build -DCMAKE_BUILD_TYPE=Release
99
cmake --build build
1010
```
1111

12-
This will create a [CMake prefix](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure), which you pass to your project with `-DCMAKE_PREFIX_PATH=/path/to/dependencies/install`. See [presentation.md](https://github.com/LLVMParty/packages/blob/main/presentation.md) and [dependencies.md](https://github.com/LLVMParty/packages/blob/main/dependencies.md) for more information.
12+
This will create a [CMake prefix](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure), which you pass to your project with `-DCMAKE_PREFIX_PATH:FILEPATH=/path/to/dependencies/install`. See [presentation.md](https://github.com/LLVMParty/packages/blob/main/presentation.md) and [dependencies.md](https://github.com/LLVMParty/packages/blob/main/dependencies.md) for more information.

dependencies/llvm.cmake

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,29 @@ set(LLVM_ARGS
2121
"-DLLVM_LINK_LLVM_DYLIB:STRING=${BUILD_SHARED_LIBS}"
2222
)
2323

24+
# LLVM has a bug on Windows where using clang.exe as the compiler fails to detect
25+
# the host target triple, so we have to specify it manually.
26+
# Reference: https://github.com/lifting-bits/remill/issues/735#issuecomment-3590986077
27+
if(WIN32)
28+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$")
29+
message(WARNING
30+
"Using clang.exe as the compiler on Windows is not well supported.\n"
31+
"If you run into issues, use clang-cl instead:\n"
32+
" cmake -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl ...\n"
33+
)
34+
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
35+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|arm64|aarch64)$")
36+
set(LLVM_ARCH "aarch64")
37+
else()
38+
set(LLVM_ARCH "x86_64")
39+
endif()
40+
else()
41+
set(LLVM_ARCH "i686")
42+
endif()
43+
list(APPEND LLVM_ARGS "-DLLVM_HOST_TRIPLE:STRING=${LLVM_ARCH}-pc-windows-msvc")
44+
endif()
45+
endif()
46+
2447
if(USE_SANITIZERS)
2548
list(APPEND LLVM_ARGS "-DLLVM_USE_SANITIZER:STRING=Address;Undefined")
2649
endif()

dependencies/superbuild.cmake

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,37 @@ message(STATUS "Configuration: ${CMAKE_BUILD_TYPE}")
2020
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
2121
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/../install" CACHE PATH "Install prefix" FORCE)
2222
endif()
23+
cmake_path(ABSOLUTE_PATH CMAKE_INSTALL_PREFIX NORMALIZE)
24+
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Install prefix" FORCE)
2325
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
2426

25-
# Save the host platform in the install prefix
26-
make_directory(${CMAKE_INSTALL_PREFIX})
27-
file(TOUCH ${CMAKE_INSTALL_PREFIX}/${CMAKE_SYSTEM}.build)
27+
# Verify build configuration hasn't changed
28+
set(BUILD_CONFIG_FILE "${CMAKE_INSTALL_PREFIX}/.build_config")
29+
string(JOIN "\n" CURRENT_BUILD_CONFIG
30+
"CMAKE_SYSTEM=${CMAKE_SYSTEM}"
31+
"CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}"
32+
"CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}"
33+
"CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
34+
"CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
35+
)
36+
37+
if(EXISTS "${BUILD_CONFIG_FILE}")
38+
file(READ "${BUILD_CONFIG_FILE}" PREVIOUS_BUILD_CONFIG)
39+
if(NOT PREVIOUS_BUILD_CONFIG STREQUAL CURRENT_BUILD_CONFIG)
40+
message(FATAL_ERROR
41+
"Build configuration changed!\n"
42+
"[previous]\n${PREVIOUS_BUILD_CONFIG}\n"
43+
"[current]\n${CURRENT_BUILD_CONFIG}\n"
44+
"\n"
45+
"Please delete the build and install directories, then reconfigure:\n"
46+
" cmake -E rm -rf \"${CMAKE_BINARY_DIR}\"\n"
47+
" cmake -E rm -rf \"${CMAKE_INSTALL_PREFIX}\"\n"
48+
)
49+
endif()
50+
else()
51+
file(MAKE_DIRECTORY "${CMAKE_INSTALL_PREFIX}")
52+
file(WRITE "${BUILD_CONFIG_FILE}" "${CURRENT_BUILD_CONFIG}")
53+
endif()
2854

2955
# Git is necessary for submodules
3056
find_package(Git REQUIRED)
@@ -87,21 +113,30 @@ list(JOIN ADDITIONAL_FLAGS " " ADDITIONAL_FLAGS)
87113

88114
# Default cache variables for all projects
89115
list(APPEND CMAKE_ARGS
90-
"-DCMAKE_PREFIX_PATH:FILEPATH=${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}"
91-
"-DCMAKE_INSTALL_PREFIX:FILEPATH=${CMAKE_INSTALL_PREFIX}"
116+
"-DCMAKE_PREFIX_PATH:PATH=${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}"
117+
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}"
92118
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
93119
"-DBUILD_SHARED_LIBS:STRING=${BUILD_SHARED_LIBS}"
94120
"-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}"
95121
"-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}"
96122
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${ADDITIONAL_FLAGS}"
97123
"-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${ADDITIONAL_FLAGS}"
124+
"-DCMAKE_POSITION_INDEPENDENT_CODE:STRING=ON"
125+
"-DCMAKE_ERROR_DEPRECATED:STRING=OFF"
126+
"-DCMAKE_ERROR_DEVELOPER_WARNINGS:STRING=OFF"
98127
)
99128

129+
if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
130+
list(APPEND CMAKE_ARGS
131+
"-DCMAKE_POLICY_VERSION_MINIMUM:STRING=${CMAKE_MINIMUM_REQUIRED_VERSION}"
132+
)
133+
endif()
134+
100135
if(CMAKE_C_COMPILER_LAUNCHER)
101-
list(APPEND CMAKE_ARGS "-DCMAKE_C_COMPILER_LAUNCHER:STRING=${CMAKE_C_COMPILER_LAUNCHER}")
136+
list(APPEND CMAKE_ARGS "-DCMAKE_C_COMPILER_LAUNCHER:FILEPATH=${CMAKE_C_COMPILER_LAUNCHER}")
102137
endif()
103138
if(CMAKE_CXX_COMPILER_LAUNCHER)
104-
list(APPEND CMAKE_ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER:STRING=${CMAKE_CXX_COMPILER_LAUNCHER}")
139+
list(APPEND CMAKE_ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER:FILEPATH=${CMAKE_CXX_COMPILER_LAUNCHER}")
105140
endif()
106141

107142
message(STATUS "Compiling all dependencies with the following CMake arguments:")

0 commit comments

Comments
 (0)