diff --git a/.github/workflows/build-test-windows.yml b/.github/workflows/build-test-windows.yml index 923c29fe5315..f70873b9d3aa 100644 --- a/.github/workflows/build-test-windows.yml +++ b/.github/workflows/build-test-windows.yml @@ -195,7 +195,7 @@ jobs: if: ${{inputs.mrbind}} shell: msys2 {0} run: | - ./scripts/mrbind/msys2_install_clang_ver.sh $(cat scripts/mrbind/clang_version_msys2.txt) + ./scripts/mrbind/msys2_install_clang_ver.sh $(scripts/mrbind/select_clang_version.sh) - name: Install Ninja for CMake if: ${{ matrix.build_system == 'CMake' }} diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index a44b7eb9f282..7728a3142616 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -129,6 +129,7 @@ jobs: - 'scripts/install_apt_requirements.sh' - 'scripts/install_dnf_requirements.sh' - 'scripts/mrbind/install_deps_ubuntu.sh' + - 'scripts/mrbind/select_clang_version.sh' - 'thirdparty/!(install.bat|vcpkg/**)' - name: Filter Linux vcpkg paths diff --git a/.github/workflows/pip-build.yml b/.github/workflows/pip-build.yml index fb448aa728a5..8a34b24a6eea 100644 --- a/.github/workflows/pip-build.yml +++ b/.github/workflows/pip-build.yml @@ -269,7 +269,7 @@ jobs: - name: Install Clang in MSYS2 shell: msys2 {0} run: | - ./scripts/mrbind/msys2_install_clang_ver.sh $(cat scripts/mrbind/clang_version_msys2.txt) + ./scripts/mrbind/msys2_install_clang_ver.sh $(scripts/mrbind/select_clang_version.sh) - name: Build MRBind shell: cmd diff --git a/docker/ubuntu20Dockerfile b/docker/ubuntu20Dockerfile index 0116c0c86e8b..45afddecee3e 100644 --- a/docker/ubuntu20Dockerfile +++ b/docker/ubuntu20Dockerfile @@ -34,7 +34,7 @@ WORKDIR "/usr/local/lib/meshlib-thirdparty-lib/" COPY scripts/install_apt_requirements.sh scripts/install_apt_requirements.sh COPY scripts/mrbind/install_deps_ubuntu.sh scripts/mrbind/install_deps_ubuntu.sh -COPY scripts/mrbind/clang_version.txt scripts/mrbind/clang_version.txt +COPY scripts/mrbind/select_clang_version.sh scripts/mrbind/select_clang_version.sh COPY scripts/install_thirdparty.sh scripts/install_thirdparty.sh COPY scripts/patches scripts/patches COPY requirements requirements diff --git a/docker/ubuntu22Dockerfile b/docker/ubuntu22Dockerfile index 752e166cc588..433eef23fa77 100644 --- a/docker/ubuntu22Dockerfile +++ b/docker/ubuntu22Dockerfile @@ -34,7 +34,7 @@ WORKDIR "/usr/local/lib/meshlib-thirdparty-lib/" COPY scripts/install_apt_requirements.sh scripts/install_apt_requirements.sh COPY scripts/mrbind/install_deps_ubuntu.sh scripts/mrbind/install_deps_ubuntu.sh -COPY scripts/mrbind/clang_version.txt scripts/mrbind/clang_version.txt +COPY scripts/mrbind/select_clang_version.sh scripts/mrbind/select_clang_version.sh COPY scripts/install_thirdparty.sh scripts/install_thirdparty.sh COPY scripts/patches scripts/patches COPY requirements requirements diff --git a/docker/ubuntu24Dockerfile b/docker/ubuntu24Dockerfile index 33ce64962c9e..bc740db6e52c 100644 --- a/docker/ubuntu24Dockerfile +++ b/docker/ubuntu24Dockerfile @@ -35,7 +35,7 @@ WORKDIR "/usr/local/lib/meshlib-thirdparty-lib/" COPY scripts/install_apt_requirements.sh scripts/install_apt_requirements.sh COPY scripts/mrbind/install_deps_ubuntu.sh scripts/mrbind/install_deps_ubuntu.sh -COPY scripts/mrbind/clang_version.txt scripts/mrbind/clang_version.txt +COPY scripts/mrbind/select_clang_version.sh scripts/mrbind/select_clang_version.sh COPY scripts/install_thirdparty.sh scripts/install_thirdparty.sh COPY scripts/patches scripts/patches COPY requirements requirements diff --git a/requirements/ubuntu.txt b/requirements/ubuntu.txt index dba913851a6c..7f96575ad88f 100644 --- a/requirements/ubuntu.txt +++ b/requirements/ubuntu.txt @@ -23,6 +23,7 @@ libtinyxml2-dev libturbojpeg0-dev libzip-dev libzstd-dev +lsb-release occt-misc pkg-config python3-venv diff --git a/scripts/mrbind/README-generating.md b/scripts/mrbind/README-generating.md index ac2d6e089180..5569cb87ddbc 100644 --- a/scripts/mrbind/README-generating.md +++ b/scripts/mrbind/README-generating.md @@ -28,7 +28,7 @@ Among other things, the scripts can do following: We use [MSYS2 CLANG64](https://www.msys2.org/docs/environments/) environment. Consult `install_deps_windows_msys2.bat` for the list of packages we install in it. - We don't use the latest Clang version, instead we download and install the version specified in `clang_version_msys2.txt`. + We don't use the latest Clang version, instead we download and install the version specified in `select_clang_version.sh`. * **Building MRBind:** @@ -45,7 +45,7 @@ Among other things, the scripts can do following: * **Installing dependencies:** - We want a certain version of Clang (see `clang_version.txt`), and since older versions of Ubuntu don't have it, we add Clang's repository: https://apt.llvm.org + We want a certain version of Clang (see `select_clang_version.sh`), and since older versions of Ubuntu don't have it, we add Clang's repository: https://apt.llvm.org And obviously we install some packages, see `install_deps_ubuntu.sh` for the list. @@ -55,7 +55,7 @@ Among other things, the scripts can do following: We build MRBind at `MeshLib/mrbind`, but you can build it [elsewhere](#less-common-flags) manually. - You might want to pass `-DClang_DIR=/usr/lib/cmake/clang-VERSION` (where `VERSION` is the one mentioned in `clang_version.txt`) if you have several versions of libclang installed, because otherwise CMake might pick an arbitrary one (apparently it picks the first one returned by globbing `clang-*`, which might not be the latest one). + You might want to pass `-DClang_DIR=/usr/lib/cmake/clang-VERSION` (where `VERSION` is the one mentioned in `select_clang_version.sh`) if you have several versions of libclang installed, because otherwise CMake might pick an arbitrary one (apparently it picks the first one returned by globbing `clang-*`, which might not be the latest one). Use `CC=clang-VERSION CXX=clang++-VERSION cmake ....` to build using Clang. Other compilers might work, but that's not guaranteed. @@ -67,14 +67,14 @@ Among other things, the scripts can do following: Homebrew must already be installed. - We install a certain version of Clang and libclang from it (see `clang_version.txt`), and also GNU Make and Gawk. MacOS has its own Make, but it's outdated. It seems to have Gawk, but we install our own just in case. + We install a certain version of Clang and libclang from it (see `select_clang_version.sh`), and also GNU Make and Gawk. MacOS has its own Make, but it's outdated. It seems to have Gawk, but we install our own just in case. What we install from Brew is the regular Clang, not Apple Clang (Apple's fork for Clang), because that is based on an outdated branch of Clang. You must run following to add the installed things to your PATH. On Arm Macs: ```sh export PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH" - export PATH="/opt/homebrew/opt/llvm/bin@VERSION:$PATH" # See the correct VERSION in `clang_version.txt`. + export PATH="/opt/homebrew/opt/llvm/bin@VERSION:$PATH" # See the correct VERSION in `select_clang_version.sh`. ``` And on x86 Macs the installation directory seems to be `/usr/local/...` instead of `/opt/homebrew/...`. @@ -123,7 +123,7 @@ Then generate the bindings: ### Selecting the compiler: -For simplicity, we compile the bindings with the same Clang that we use for parsing the code. (Consult `clang_version.txt` for the current version.) But you can override this using `CXX_FOR_BINDINGS`. +For simplicity, we compile the bindings with the same Clang that we use for parsing the code. (Consult `select_clang_version.sh` for the current version.) But you can override this using `CXX_FOR_BINDINGS`. **ABI compatibility:** Since MeshLib is compiled using a different compiler, we must ensure the two use the same ABI. `CXX_FOR_ABI` should be set to the compiler the ABI of which we're trying to match. (Defaults to `CXX` environment variable, or `g++` if not set.) At the moment, if `CXX_FOR_ABI` is GCC 13 or older or Clang 17 or older (note that Apple Clang uses a [different version numbering scheme](https://en.wikipedia.org/wiki/Xcode#Xcode_15.0_-_(since_visionOS_support)_2)), we pass `-fclang-abi-compat=17` to our Clang 18 or newer. This flag *disables* mangling `requires` constraints into function names. If we guess incorrectly, you'll get undefined references to functions with `requires` constraints on them. diff --git a/scripts/mrbind/clang_version.txt b/scripts/mrbind/clang_version.txt index 3c032078a4a2..209e3ef4b624 100644 --- a/scripts/mrbind/clang_version.txt +++ b/scripts/mrbind/clang_version.txt @@ -1 +1 @@ -18 +20 diff --git a/scripts/mrbind/clang_version_msys2.txt b/scripts/mrbind/clang_version_msys2.txt index f279294d9dc7..edd3c7621af1 100644 --- a/scripts/mrbind/clang_version_msys2.txt +++ b/scripts/mrbind/clang_version_msys2.txt @@ -1 +1 @@ -18.1.8-2 \ No newline at end of file +20.1.7-1 diff --git a/scripts/mrbind/common_compiler_parser_flags.txt b/scripts/mrbind/common_compiler_parser_flags.txt index 845ff0e32730..0b8670327cb8 100644 --- a/scripts/mrbind/common_compiler_parser_flags.txt +++ b/scripts/mrbind/common_compiler_parser_flags.txt @@ -1,5 +1,3 @@ -std=c++23 -Wno-nonportable-include-path --Wno-enum-constexpr-conversion -Wno-deprecated-enum-enum-conversion --frelaxed-template-template-args diff --git a/scripts/mrbind/generate.mk b/scripts/mrbind/generate.mk index 9f256e31d03d..bfab34e6a87f 100644 --- a/scripts/mrbind/generate.mk +++ b/scripts/mrbind/generate.mk @@ -156,10 +156,10 @@ MRBIND_EXE := $(MRBIND_SOURCE)/build/mrbind ifneq ($(IS_WINDOWS),) CXX_FOR_BINDINGS := clang++ else ifneq ($(IS_MACOS),) -CXX_FOR_BINDINGS := $(HOMEBREW_DIR)/opt/llvm@$(strip $(file <$(makefile_dir)clang_version.txt))/bin/clang++ +CXX_FOR_BINDINGS := $(HOMEBREW_DIR)/opt/llvm@$(call safe_shell,$(makefile_dir)select_clang_version.sh)/bin/clang++ else # Only on Ubuntu we don't want the default Clang version, as it can be outdated. Use the suffixed one. -CXX_FOR_BINDINGS := clang++-$(strip $(file <$(makefile_dir)clang_version.txt)) +CXX_FOR_BINDINGS := clang++-$(call safe_shell,$(makefile_dir)select_clang_version.sh) endif # Which C++ compiler we should try to match for ABI. @@ -428,7 +428,13 @@ INPUT_GLOBS := *.h # `referenced by source/TempOutput/PythonBindings/x64/Release/binding.0.o:(public: __cdecl std::_Literal_zero::_Literal_zero(int))`. MRBIND_FLAGS := $(call load_file,$(makefile_dir)mrbind_flags.txt) MRBIND_FLAGS_FOR_EXTRA_INPUTS := $(call load_file,$(makefile_dir)mrbind_flags_for_helpers.txt) + COMPILER_FLAGS := $(ABI_COMPAT_FLAG) $(EXTRA_CFLAGS) $(call load_file,$(makefile_dir)common_compiler_parser_flags.txt) -I. -I$(DEPS_INCLUDE_DIR) -I$(makefile_dir)../../source +# Add some flags for old Clangs. +ifneq ($(filter 18 19,$(call safe_shell,$(CXX_FOR_BINDINGS) -dumpversion | cut -d. -f1)),) +COMPILER_FLAGS += -Wno-enum-constexpr-conversion -frelaxed-template-template-args +endif + COMPILER_FLAGS_LIBCLANG := $(call load_file,$(makefile_dir)parser_only_flags.txt) # Need whitespace before `$(MRBIND_SOURCE)` to handle `~` correctly. COMPILER := $(CXX_FOR_BINDINGS) $(subst $(lf), ,$(call load_file,$(makefile_dir)compiler_only_flags.txt)) -I $(MRBIND_SOURCE)/include -I$(makefile_dir) diff --git a/scripts/mrbind/install_deps_macos.sh b/scripts/mrbind/install_deps_macos.sh index aa04ef12e4a7..8bb2719dc20c 100755 --- a/scripts/mrbind/install_deps_macos.sh +++ b/scripts/mrbind/install_deps_macos.sh @@ -4,10 +4,8 @@ # We assume `brew` is already installed. Automatic its installation is too much, # especially because of the conflicts that happen if several users install it. -# Read the Clang version from `clang_version.txt`. `xargs` trims the whitespace. -# Some versions of MacOS seem to lack `realpath`, so not using it here. SCRIPT_DIR="$(dirname "$BASH_SOURCE")" -CLANG_VER="$(cat $SCRIPT_DIR/clang_version.txt | xargs)" +CLANG_VER="$("$SCRIPT_DIR/select_clang_version.sh")" [[ $CLANG_VER ]] || (echo "Not sure what version of Clang to use." && false) brew update diff --git a/scripts/mrbind/install_deps_ubuntu.sh b/scripts/mrbind/install_deps_ubuntu.sh index b9965608d34d..ffdbe5392275 100755 --- a/scripts/mrbind/install_deps_ubuntu.sh +++ b/scripts/mrbind/install_deps_ubuntu.sh @@ -10,9 +10,8 @@ apt update # Install `xargs` because we need it below. apt install -y findutils -# Read the Clang version from `clang_version.txt`. `xargs` trims the whitespace. SCRIPT_DIR="$(realpath "$(dirname "$BASH_SOURCE")")" -CLANG_VER="$(cat $SCRIPT_DIR/clang_version.txt | xargs)" +CLANG_VER="$("$SCRIPT_DIR/select_clang_version.sh")" [[ $CLANG_VER ]] || (echo "Not sure what version of Clang to use." && false) # Add LLVM repositories if the required package is not accessible right now. diff --git a/scripts/mrbind/install_deps_windows_msys2.bat b/scripts/mrbind/install_deps_windows_msys2.bat index a1365c24e869..37c6932213a1 100644 --- a/scripts/mrbind/install_deps_windows_msys2.bat +++ b/scripts/mrbind/install_deps_windows_msys2.bat @@ -10,7 +10,6 @@ rem some other MSYS2 copy. setlocal if "%MSYS2_DIR%" == "" set MSYS2_DIR=C:\msys64_meshlib_mrbind -if "%CLANG_VER%" == "" set /p CLANG_VER=<%~dp0\clang_version_msys2.txt rem ------ Ensure MSYS2 is installed @@ -50,6 +49,6 @@ rem ------ Install needed packages call %MSYS2_DIR%\msys2_shell.cmd -no-start -defterm -clang64 -c "pacman -S --noconfirm --needed gawk make procps-ng $MINGW_PACKAGE_PREFIX-cmake" rem ------ Install a specific version of Clang -call %MSYS2_DIR%\msys2_shell.cmd -no-start -defterm -clang64 -c "'%~dp0'/msys2_install_clang_ver.sh %CLANG_VER%" +call %MSYS2_DIR%\msys2_shell.cmd -no-start -defterm -clang64 -c "'%~dp0'/msys2_install_clang_ver.sh $('%~dp0'/select_clang_version.sh)" endlocal diff --git a/scripts/mrbind/install_mrbind_macos.sh b/scripts/mrbind/install_mrbind_macos.sh index efcc559b8ded..ff0316638264 100755 --- a/scripts/mrbind/install_mrbind_macos.sh +++ b/scripts/mrbind/install_mrbind_macos.sh @@ -8,9 +8,7 @@ SCRIPT_DIR="$(dirname "$BASH_SOURCE")" [[ ${MRBIND_DIR:=} ]] || MRBIND_DIR="$SCRIPT_DIR/../../thirdparty/mrbind" -# Read the Clang version from `clang_version.txt`. `xargs` trims the whitespace. -# Some versions of MacOS seem to lack `realpath`, so not using it here. -CLANG_VER="$(cat "$SCRIPT_DIR/clang_version.txt" | xargs)" +CLANG_VER="$("$SCRIPT_DIR/select_clang_version.sh")" [[ ${CLANG_VER:=} ]] || (echo "Not sure what version of Clang to use." && false) cd "$MRBIND_DIR" diff --git a/scripts/mrbind/install_mrbind_ubuntu.sh b/scripts/mrbind/install_mrbind_ubuntu.sh index fa820c7a767e..ac02d135f18b 100755 --- a/scripts/mrbind/install_mrbind_ubuntu.sh +++ b/scripts/mrbind/install_mrbind_ubuntu.sh @@ -8,8 +8,7 @@ SCRIPT_DIR="$(realpath "$(dirname "$BASH_SOURCE")")" [[ -v MRBIND_DIR ]] || MRBIND_DIR="$(realpath "$SCRIPT_DIR/../../thirdparty/mrbind")" -# Read the Clang version from `clang_version.txt`. `xargs` trims the whitespace. -CLANG_VER="$(cat "$SCRIPT_DIR/clang_version.txt" | xargs)" +CLANG_VER="$("$SCRIPT_DIR/select_clang_version.sh")" [[ $CLANG_VER ]] || (echo "Not sure what version of Clang to use." && false) cd "$MRBIND_DIR" diff --git a/scripts/mrbind/select_clang_version.sh b/scripts/mrbind/select_clang_version.sh new file mode 100755 index 000000000000..477dc93cfe58 --- /dev/null +++ b/scripts/mrbind/select_clang_version.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +# Returns the version of Clang that we want to use on the current platform. +# If you also pass `--flags`, we return the extra flags it needs. + +set -euo pipefail + +if [[ $# > 0 ]]; then + echo 'Expected no arguments.' >&2 + exit +fi + + +CLANG_18=18 +CLANG_20=20 +CLANG_MSYS2=20.1.7-1 + + +# Windows, Clang installed via MSYS2. +if [[ $(uname -o) == Msys ]]; then + echo $CLANG_MSYS2 + exit +fi + +UNAME_S=$(uname -s) + +# MacOS. +if [[ $UNAME_S == Darwin ]]; then + # Clang 20 can't find the C++ standard library, so staying 18 for now. + # I didn't dig too deep here, and we have to maintain 18 anyway for Ubuntu 20.04 and 22.04 (see below for why that is). + echo 18 + exit +fi + +# Linux. +if [[ $UNAME_S == Linux ]]; then + # Here we use `type` to not rely on `which` existing, since it's getting removed from some distros. + if ! type lsb_release >/dev/null 2>/dev/null; then + echo "`lsb_release` is not installed!" >&2 + fi + + # Is `Ubuntu <= 22.04`? + if (lsb_release -rs; echo "22.04") | sort -CV; then + # Here we need the outdated Clang because the old Boost doesn't compile on the new Clang, because of this change: https://github.com/llvm/llvm-project/issues/59036 + # This is what is actually locking us to Clang 18 at the moment. Other platforms are using it for less scare reasons. + echo 18 + exit + fi + + # Is any other ubuntu? + if [[ $(lsb_release -is) == Ubuntu ]]; then + # This is because teh stock spdlog and libfmt fail with `call to consteval function ... is not a constant expression` somewhere in the formatting logic. Hmm. + echo 18 + exit + fi + + # Any other linux. + echo 20 + exit +fi + +echo "Unknown OS" >&2 +exit 1