Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 67 additions & 6 deletions Common/3dParty/boost/nc-build.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,31 @@
)

modules_needed = [ "headers", "system", "filesystem", "regex", "date_time" ]
header_only_modules_needed = [ "any", "asio", "beast", "foreach", "format", "functional", "multi_index", "uuid" ]
# Only these submodules get checked out, so every boost header the project
# includes must be reachable from this list (directly or as a boostdep-resolved
# dependency of one of them).
#
# ptr_container / serialization / spirit / variant are listed explicitly because
# they are NOT dependencies of anything above: they used to be pulled in
# transitively on 1.78, but boost has been migrating away from Boost.Variant
# towards std::variant, so on current boost they are no longer dragged in and
# the headers went missing -> "fatal error C1083: Cannot open include file:
# 'boost/variant.hpp'" in libetonyek, and the same for the spirit / ptr_container
# / boost-archive includes in librevenge.
#
# NOTE: boost/archive/** (the base64 iterators librevenge uses) ships in the
# SERIALIZATION module - there is no boost module called "archive". Those
# iterators are pure templates, so headers alone are enough and serialization
# does not have to be built.
header_only_modules_needed = [ "any", "asio", "beast", "foreach", "format", "functional",
"multi_index", "ptr_container", "serialization", "spirit",
"uuid", "variant" ]

def fetch_and_patch():
nc.create_workdir()
print( "Clone Boost 1.78.0..." )
nc.run_command(
[ "git", "clone", "https://github.com/boostorg/boost.git", "-b", "boost-1.78.0", nc.work_dir, "--depth", "1" ],
[ "git", "clone", "https://github.com/boostorg/boost.git", nc.work_dir, "--depth", "1" ],
"Clone Boost 1.78.0"
)

Expand Down Expand Up @@ -70,6 +88,36 @@ def boost_msvc_arch() -> tuple[ str, str ]:
return "arm", "Hostarm64\\arm64"
nc.abort_op( f"Unsupported target arch for boost: {a!r}" )

def jam_path( p ) -> str:
return str( Path( p ) ).replace( "\\", "\\\\" )

def boost_msvc_toolset_version() -> str:
"""
The 'using msvc : <version>' value for the compiler we actually build with.

Boost derives the library name tag from this value - common.jam's
toolset-tag joins major+minor, so 14.0 -> vc140, 14.3 -> vc143,
14.5 -> vc145. CMake's BoostConfig computes the same tag from the compiler
it detects and REJECTS libs whose tag differs:

libboost_filesystem-vc140-mt-x64-1_92.lib (vc140, detected vc145)
No suitable build variant has been found.

which is exactly what happened while this was hardcoded to 14.0 but cl.exe
came from MSVC 14.51 - the libs were built by the right compiler, only the
name lied. So derive it from the toolchain actually in use.

MSVC's tag keeps only the FIRST digit of the minor version (14.51 -> vc145,
14.39 -> vc143), hence 'MAJOR.<first digit of MINOR>' from VCToolsVersion.
"""
ver = os.environ.get( "VCToolsVersion", "" )
parts = ver.split( "." )
if len( parts ) < 2 or not parts[ 0 ].isdigit() or not parts[ 1 ][ :1 ].isdigit():
nc.abort_op(
f"Cannot derive the MSVC toolset version from VCToolsVersion={ ver!r }. "
"Is the MSVC environment loaded (vcvars)?"
)
return f"{ parts[ 0 ] }.{ parts[ 1 ][ 0 ] }"

def build_and_install():
nc.create_install_dir()
Expand All @@ -94,14 +142,27 @@ def build_and_install():

if nc.is_windows():
print( "Fixing project-config.jam..." )
msvc_version = boost_msvc_toolset_version()
print( f"Using MSVC toolset { msvc_version } "
f"(libs will be tagged vc{ msvc_version.replace( '.', '' ) })" )
# Jam treats a backslash inside a quoted string as an escape, so a raw
# Windows path silently collapses ("C:\Program Files\..." arrives as
# "C:Program Files...") and b2 then warns "Did not find command for MSVC
# toolset" and falls back to whatever cl.exe is on PATH. jam_path()
# doubles the separators, which is exactly what it exists for.
# Built outside the f-string so no backslash appears in an f-string
# expression (only allowed from Python 3.12 on).
cl_path = jam_path(
Path( os.environ[ "VCToolsInstallDir" ] ) / "bin" / host_subdir / "cl.exe"
)
content = f"""
# Boost.Build Configuration
# Generated by nc-build.py

import option ;
using msvc : 14.0 : "{ os.environ[ "VCToolsInstallDir" ] }\\bin\\{ host_subdir }\\cl.exe";

using msvc : { msvc_version } : "{ cl_path }";

option.set keep-going : false ;

"""
Expand Down
8 changes: 7 additions & 1 deletion Common/3dParty/cryptopp/integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3056,7 +3056,13 @@ Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s, Byt
else
{
SecByteBlock block(byteCount);
#if (_MSC_VER >= 1500)
// The stdext:: iterator extensions were removed from the MSVC STL (gone as of
// MSVC 14.51 / _MSC_VER 1951), so a pure version check picks a namespace that
// no longer exists: "error C2653: 'stdext': is not a class or namespace".
// Gate on _STDEXT_BEGIN - the macro the MSVC headers use to open that namespace -
// like the guard in zdeflate.cpp already does. The portable path below is
// equivalent; the wrapper only added debug-time bounds checking.
#if (_MSC_VER >= 1500) && defined(_STDEXT_BEGIN)
std::reverse_copy(encodedInteger, encodedInteger+byteCount,
stdext::make_checked_array_iterator(block.begin(), block.size()));
#else
Expand Down
6 changes: 5 additions & 1 deletion Common/3dParty/cryptopp/zdeflate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,11 @@ unsigned int Deflator::LongestMatch(unsigned int &bestMatch) const
#else
std::mismatch
#endif
#if _MSC_VER >= 1600
// Same _STDEXT_BEGIN feature test as the guard above: the stdext:: extensions
// are gone from the MSVC STL (as of MSVC 14.51 / _MSC_VER 1951), so a bare
// version check would name a namespace that no longer exists. The unchecked
// wrappers only suppressed iterator-debug warnings, so raw pointers are equivalent.
#if _MSC_VER >= 1600 && defined(_STDEXT_BEGIN)
(stdext::make_unchecked_array_iterator(scan)+3, stdext::make_unchecked_array_iterator(scanEnd), stdext::make_unchecked_array_iterator(match)+3).first - stdext::make_unchecked_array_iterator(scan));
#else
(scan+3, scanEnd, match+3).first - scan);
Expand Down
38 changes: 37 additions & 1 deletion Common/3dParty/icu-desktop/nc-build-cygwin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,43 @@ if [[ $install_dir == /mnt/* ]]; then
fi

export PATH="$PATH:/usr/bin"
export PYTHON=/usr/bin/python3

# Pick a working Python 3 for ICU's data/rules.mk generation. Prefer Cygwin's
# python3, but fall back to any python3/python on PATH (e.g. the native Windows
# one the build front-loads) when Cygwin's isn't installed. ICU's databuilder
# normalizes path separators to '/', so native Python produces correct makefile
# fragments too.
if [ -x /usr/bin/python3 ]; then
export PYTHON=/usr/bin/python3
elif command -v python3 >/dev/null 2>&1; then
export PYTHON="$( command -v python3 )"
elif command -v python >/dev/null 2>&1; then
export PYTHON="$( command -v python )"
else
echo "ERROR: no Python 3 found. Install Cygwin's python3, or ensure a native python3 is on PATH." >&2
exit 1
fi
echo "Using PYTHON=$PYTHON"

# --- Make MSVC's link.exe win over Cygwin's /usr/bin/link (coreutils) --------
# ICU's configure runs `link --version` and aborts with "link.exe is not a
# valid linker" if it reports "GNU coreutils". Cygwin ships such a `link`, and
# depending on the inherited PATH order it can shadow MSVC's linker. cl is
# already on PATH (CC=cl) and MSVC's link.exe lives in the SAME directory, so
# front-load that directory; falls back to VCToolsInstallDir if cl isn't found.
msvc_bin=""
cl_path="$( command -v cl 2>/dev/null || true )"
if [ -n "$cl_path" ]; then
msvc_bin="$( dirname "$cl_path" )"
elif [ -n "$VCToolsInstallDir" ]; then
msvc_bin="$( cygpath -u "$VCToolsInstallDir" )/bin/Hostx64/x64"
fi
if [ -n "$msvc_bin" ] && [ -x "$msvc_bin/link.exe" ]; then
export PATH="$msvc_bin:$PATH"
echo "Front-loaded MSVC bin so link.exe resolves to the MS linker: $msvc_bin"
else
echo "WARNING: could not locate MSVC bin dir; Cygwin's link may shadow link.exe" >&2
fi

abort_op()
{
Expand Down
18 changes: 16 additions & 2 deletions Common/3dParty/icu-desktop/nc-build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,22 @@ echo Using Cygwin: %CYGWIN_BIN%
echo Using vcvars: %VCVARS%

REM ---- PATH ORDER: MSVC first, Cygwin second ----
set "PATH=%CYGWIN_BIN%;%PATH%"
call "%VCVARS%" || exit /b 1
REM If the caller already loaded the MSVC environment (build.ps1 does this via
REM Import-VcVars, so VCINSTALLDIR/VSCMD/PATH/INCLUDE/LIB are inherited here),
REM DON'T re-run vcvars: it concatenates all MSVC/SDK dirs onto the already-long
REM inherited PATH again and blows past cmd's 8191-char line limit
REM ("Die eingegebene Zeile ist zu lang. / Syntaxfehler."), aborting the build.
if defined VCINSTALLDIR (
echo MSVC environment already active ^(VCINSTALLDIR set^) - reusing it, skipping vcvars.
REM Cygwin is already on the inherited PATH; append (not prepend) so MSVC's
REM link.exe still precedes Cygwin's /usr/bin/link. Keeps cygpath reachable
REM even when the batch is run standalone from a VS dev prompt.
set "PATH=%PATH%;%CYGWIN_BIN%"
) else (
REM Fresh shell: Cygwin first, then let vcvars prepend MSVC on top -> MSVC first.
set "PATH=%CYGWIN_BIN%;%PATH%"
call "%VCVARS%" || exit /b 1
)

echo "------------- DBG 1"

Expand Down
38 changes: 37 additions & 1 deletion Common/3dParty/icu/nc-build-cygwin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,43 @@ if [[ $install_dir == /mnt/* ]]; then
fi

export PATH="$PATH:/usr/bin"
export PYTHON=/usr/bin/python3

# Pick a working Python 3 for ICU's data/rules.mk generation. Prefer Cygwin's
# python3, but fall back to any python3/python on PATH (e.g. the native Windows
# one the build front-loads) when Cygwin's isn't installed. ICU's databuilder
# normalizes path separators to '/', so native Python produces correct makefile
# fragments too.
if [ -x /usr/bin/python3 ]; then
export PYTHON=/usr/bin/python3
elif command -v python3 >/dev/null 2>&1; then
export PYTHON="$( command -v python3 )"
elif command -v python >/dev/null 2>&1; then
export PYTHON="$( command -v python )"
else
echo "ERROR: no Python 3 found. Install Cygwin's python3, or ensure a native python3 is on PATH." >&2
exit 1
fi
echo "Using PYTHON=$PYTHON"

# --- Make MSVC's link.exe win over Cygwin's /usr/bin/link (coreutils) --------
# ICU's configure runs `link --version` and aborts with "link.exe is not a
# valid linker" if it reports "GNU coreutils". Cygwin ships such a `link`, and
# depending on the inherited PATH order it can shadow MSVC's linker. cl is
# already on PATH (CC=cl) and MSVC's link.exe lives in the SAME directory, so
# front-load that directory; falls back to VCToolsInstallDir if cl isn't found.
msvc_bin=""
cl_path="$( command -v cl 2>/dev/null || true )"
if [ -n "$cl_path" ]; then
msvc_bin="$( dirname "$cl_path" )"
elif [ -n "$VCToolsInstallDir" ]; then
msvc_bin="$( cygpath -u "$VCToolsInstallDir" )/bin/Hostx64/x64"
fi
if [ -n "$msvc_bin" ] && [ -x "$msvc_bin/link.exe" ]; then
export PATH="$msvc_bin:$PATH"
echo "Front-loaded MSVC bin so link.exe resolves to the MS linker: $msvc_bin"
else
echo "WARNING: could not locate MSVC bin dir; Cygwin's link may shadow link.exe" >&2
fi

# --- logging: write a clean UTF-8 log straight from bash ---------------------
# Done before any heavy work so the real output never passes through the
Expand Down
18 changes: 16 additions & 2 deletions Common/3dParty/icu/nc-build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,22 @@ echo Using Cygwin: %CYGWIN_BIN%
echo Using vcvars: %VCVARS%

REM ---- PATH ORDER: MSVC first, Cygwin second ----
set "PATH=%CYGWIN_BIN%;%PATH%"
call "%VCVARS%" || exit /b 1
REM If the caller already loaded the MSVC environment (build.ps1 does this via
REM Import-VcVars, so VCINSTALLDIR/VSCMD/PATH/INCLUDE/LIB are inherited here),
REM DON'T re-run vcvars: it concatenates all MSVC/SDK dirs onto the already-long
REM inherited PATH again and blows past cmd's 8191-char line limit
REM ("Die eingegebene Zeile ist zu lang. / Syntaxfehler."), aborting the build.
if defined VCINSTALLDIR (
echo MSVC environment already active ^(VCINSTALLDIR set^) - reusing it, skipping vcvars.
REM Cygwin is already on the inherited PATH; append (not prepend) so MSVC's
REM link.exe still precedes Cygwin's /usr/bin/link. Keeps cygpath reachable
REM even when the batch is run standalone from a VS dev prompt.
set "PATH=%PATH%;%CYGWIN_BIN%"
) else (
REM Fresh shell: Cygwin first, then let vcvars prepend MSVC on top -> MSVC first.
set "PATH=%CYGWIN_BIN%;%PATH%"
call "%VCVARS%" || exit /b 1
)

echo "------------- DBG 1"

Expand Down
22 changes: 22 additions & 0 deletions Common/3dParty/v8/nc-build.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@

gn_source_path = nc.work_dir / "gn-source"

# Enable git long paths for EVERY git process started from here on - including
# the ones gclient spawns internally, which we can't pass -c flags to.
# GIT_CONFIG_COUNT/KEY/VALUE (git >= 2.31) outranks the system/global config, so
# this works without touching the user's ~/.gitconfig (which may not even exist -
# depot_tools then warns about it, harmlessly).
#
# Why it's needed: some v8 dependency paths exceed MAX_PATH, e.g.
# buildtools/third_party/libc++/trunk/test/std/thread/... = 264 chars. Without
# this git cannot write those files, reports "Filename too long", and the
# unwritten file shows up as a local deletion -> gclient aborts the sync with
# "You have uncommitted changes". The Windows-wide LongPathsEnabled registry
# flag does NOT cover this; git needs its own opt-in.
#
# Deliberately ONLY longpaths. depot_tools also recommends core.autocrlf=false,
# but do NOT set it here: an existing tree checked out with CRLF no longer
# matches the LF patches in tools/8.9/, and every `git apply` fails with
# "patch does not apply".
if nc.is_windows():
os.environ[ "GIT_CONFIG_COUNT" ] = "1"
os.environ[ "GIT_CONFIG_KEY_0" ] = "core.longpaths"
os.environ[ "GIT_CONFIG_VALUE_0" ] = "true"

def check_prequisites():
tools_needed = [ "git", "python3" ]
if nc.is_linux():
Expand Down
11 changes: 11 additions & 0 deletions common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,17 @@ else()
set(Boost_USE_STATIC_LIBS ON)
find_package( Boost REQUIRED COMPONENTS system filesystem regex date_time )

# Boost.Regex is header-only since Boost 1.77, so Boost::regex is now an
# INTERFACE target. For the COMPILED components (filesystem, ...) Boost's own
# CMake config sets BOOST_<LIB>_NO_LIB, which switches off the auto-link
# #pragma in the headers because CMake passes the .lib path itself. A
# header-only target gets no such define AND no library directory, yet
# boost/regex/v5/cregex.hpp still emits the auto-link pragma - so the linker
# demands libboost_regex-vcXXX-mt-x64-Y_ZZ.lib and fails with LNK1104 even
# though nothing needs to be linked. On Boost 1.78 regex was still a compiled
# component, hence the define came for free and this never surfaced.
add_definitions(-DBOOST_REGEX_NO_LIB)

# Setup v8
set(V8_INSTALL_DIR "${EO_CORE_3RD_PARTY_INSTALL_DIR}/v8")
get_filename_component(V8_INSTALL_DIR_ABS "${V8_INSTALL_DIR}" ABSOLUTE)
Expand Down