Skip to content
Merged
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
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,16 @@ if(BUILD_ENTERPRISE)
endif()

if(LITECORE_BUILD_SHARED)
add_library(LiteCore SHARED $<TARGET_OBJECTS:LiteCoreObjects>)
if(MSVC)
add_library(LiteCore SHARED $<TARGET_OBJECTS:LiteCoreObjects> MSVC/dllmain.c)
target_include_directories(
LiteCore PRIVATE
C/include
)
else()
add_library(LiteCore SHARED $<TARGET_OBJECTS:LiteCoreObjects>)
endif()

target_include_directories(
LiteCore INTERFACE
C/include
Expand Down
98 changes: 98 additions & 0 deletions MSVC/dllmain.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#pragma comment(lib, "Version.lib")

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "c4Log.h"

typedef struct {
WORD major;
WORD minor;
WORD build;
WORD revision;
} Version;

static int GetDllVersion(const wchar_t* path, Version* out_version) {
DWORD dummy;
DWORD size = GetFileVersionInfoSizeW(path, &dummy);
if ( size == 0 ) { return 0; }

BYTE* buffer = (BYTE*)malloc(size);
if ( !buffer ) { return 0; }
if ( !GetFileVersionInfoW(path, 0, size, buffer) ) {
c4log(kC4DefaultLog, kC4LogVerbose, "GetFileVersionInfoW failed: %lu", GetLastError());
free(buffer);
return 0;
}

VS_FIXEDFILEINFO* fileInfo;
UINT len = 0;
if ( !VerQueryValueA(buffer, "\\", (LPVOID*)&fileInfo, &len) ) {
c4log(kC4DefaultLog, kC4LogVerbose, "VerQueryValueA failed: %lu", GetLastError());
free(buffer);
return 0;
}

if ( fileInfo ) {
out_version->major = HIWORD(fileInfo->dwFileVersionMS);
out_version->minor = LOWORD(fileInfo->dwFileVersionMS);
out_version->build = HIWORD(fileInfo->dwFileVersionLS);
out_version->revision = LOWORD(fileInfo->dwFileVersionLS);
free(buffer);
return 1;
}

c4log(kC4DefaultLog, kC4LogVerbose, "VerQueryValueA returned NULL");
free(buffer);
return 0;
}

static int CompareVersions(const Version* a, const Version* b) {
if ( a->major != b->major ) return a->major < b->major ? -1 : 1;
if ( a->minor != b->minor ) return a->minor < b->minor ? -1 : 1;
if ( a->build != b->build ) return a->build < b->build ? -1 : 1;
if ( a->revision != b->revision ) return a->revision < b->revision ? -1 : 1;
return 0;
}

void CheckCppRuntime() {
HMODULE hMod = GetModuleHandleA("msvcp140.dll");
if ( !hMod ) { hMod = LoadLibraryA("msvcp140d.dll"); }

if ( !hMod ) {
c4log(kC4DefaultLog, kC4LogWarning, "msvcp140.dll not loaded yet, unable to check version...");
return;
}

wchar_t path[MAX_PATH];
if ( GetModuleFileNameW(hMod, path, MAX_PATH) == 0 ) {
c4log(kC4DefaultLog, kC4LogWarning, "Unable to determine msvcp140.dll filename to check version...");
return;
}

Version loaded = {0};
if ( !GetDllVersion(path, &loaded) ) {
c4log(kC4DefaultLog, kC4LogWarning, "Unable to get version of msvcp140.dll to check...");
return;
}

Version expected = {14, 36, 32457, 0};
int cmp = CompareVersions(&loaded, &expected);
if ( cmp < 0 ) {
c4log(kC4DefaultLog, kC4LogWarning, "msvcp140.dll version is older than expected: %u.%u.%u.%u < %u.%u.%u.%u",
loaded.major, loaded.minor, loaded.revision, loaded.build, expected.major, expected.minor,
expected.revision, expected.build);
Comment on lines +83 to +84

Copilot AI Jun 27, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order of version numbers is inconsistent with the defined version structure; the 'build' value should be printed before the 'revision' to correctly reflect the version as major.minor.build.revision.

Suggested change
loaded.major, loaded.minor, loaded.revision, loaded.build, expected.major, expected.minor,
expected.revision, expected.build);
loaded.major, loaded.minor, loaded.build, loaded.revision, expected.major, expected.minor,
expected.build, expected.revision);

Copilot uses AI. Check for mistakes.
c4log(kC4DefaultLog, kC4LogWarning, "This may cause instability in your application");
}
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch ( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
CheckCppRuntime();
break;
default:
break;
}
return TRUE;
}
6 changes: 4 additions & 2 deletions cmake/platform_win.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ function(set_litecore_source)
endfunction()

function(setup_globals)
set(CMAKE_C_FLAGS_MINSIZEREL "/MD /O1 /Ob1 /DNDEBUG /Zi /GL" CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "/MD /O1 /Ob1 /DNDEBUG /Zi /GL" CACHE INTERNAL "")
add_compile_options(/MP)
add_link_options(/CGTHREADS:8)
set(CMAKE_C_FLAGS_MINSIZEREL "/MD /O1 /Ob1 /DNDEBUG /Zi /GL /MP" CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "/MD /O1 /Ob1 /DNDEBUG /Zi /GL /MP" CACHE INTERNAL "")
set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "/INCREMENTAL:NO /LTCG:incremental /debug" CACHE INTERNAL "")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/INCREMENTAL:NO /LTCG:incremental /debug" CACHE INTERNAL "")
set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "/LTCG:incremental" CACHE INTERNAL "")
Expand Down
3 changes: 3 additions & 0 deletions jenkins/build_server_win.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ function Build() {
$build_enterprise = "OFF"
}

# This -T version controls which version of the MSVC toolchain is used.
# Once it is decided for a given minor release line, it should not be changed.
& "C:\Program Files\CMake\bin\cmake.exe" `
-T version=14.36.17.6 `
-A $MsArch `
-DBUILD_ENTERPRISE=$build_enterprise `
-DCMAKE_INSTALL_PREFIX="$(Get-Location)\install" `
Expand Down
7 changes: 5 additions & 2 deletions jenkins/jenkins_win.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ try {

New-Item -Type Directory -ErrorAction Ignore couchbase-lite-core\build_cmake\x64
Set-Location couchbase-lite-core\build_cmake\x64
& 'C:\Program Files\CMake\bin\cmake.exe' -A x64 -DCMAKE_SYSTEM_VERSION="10.0" -DBUILD_ENTERPRISE=ON ..\..

# This -T version controls which version of the MSVC toolchain is used.
# Once it is decided for a given minor release line, it should not be changed.
& 'C:\Program Files\CMake\bin\cmake.exe' -T version=14.36.17.6 -DCMAKE_SYSTEM_VERSION="10.0" -DBUILD_ENTERPRISE=ON ..\..
if($LASTEXITCODE -ne 0) {
Write-Host "Failed to run CMake!" -ForegroundColor Red
exit 1
}

& 'C:\Program Files\CMake\bin\cmake.exe' --build . --parallel 8
& 'C:\Program Files\CMake\bin\cmake.exe' --build . --parallel $env:NUMBER_OF_PROCESSORS
if($LASTEXITCODE -ne 0) {
Write-Host "Failed to build!" -ForegroundColor Red
exit 1
Expand Down