Description
Building curl with -DCURL_STATIC_CRT=ON
Run "x64 Native Tools Command Prompt for VS 2019"
> git clone https://github.com/curl/curl
(on commit 69d5d18)
> md build
> cd build
> cmake -DCURL_STATIC_CRT=ON -DBUILD_SHARED_LIBS=OFF ../curl
> cmake --build . --target curl
I see the following
> dumpbin /imports src\Debug\curl.exe | find ".dll"
WLDAP32.dll
WS2_32.dll
ADVAPI32.dll
KERNEL32.dll
VCRUNTIME140D.dll
ucrtbased.dll
(This is identical with the output when -DCURL_STATIC_CRT=ON
is not provided)
I expected the following
> dumpbin /imports src\Debug\curl.exe | find ".dll"
WLDAP32.dll
WS2_32.dll
ADVAPI32.dll
KERNEL32.dll
curl/libcurl version
> src\Debug\curl.exe -V
curl 7.70.0-DEV (Windows) libcurl/7.70.0-DEV
Release-Date: [unreleased]
Protocols: dict file ftp gopher http imap ldap pop3 rtsp smb smtp telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM
operating system
Windows 10 1909
I am using Visual Studio 16.5.1, and the cmake that is supplied with VS (cmake version 3.16.19112601-MSVC_2)
Analysis
Cmake CMP0091 ( https://cmake.org/cmake/help/git-stage/policy/CMP0091.html ) changes the way CMake on Windows handles the flags controlling the C runtime being used.
Prior to CMake 3.15 the /MT
or /MTd
flags could simply be added to CMAKE_C_FLAGS_DEBUG
or CMAKE_C_FLAGS_RELEASE
.
Starting with CMake 3.15 the CMAKE_MSVC_RUNTIME_LIBRARY
abstraction should be used instead -- values provided in the other locations are ignored.
Possible Solution
Change CMakeLists.txt:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e70a6e348..a410d4955 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -232,6 +232,7 @@ set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
if(CURL_STATIC_CRT)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
endif()
Note: the existing settings should be left in place, for versions of cmake prior to 3.15
Activity
bagder commentedon Mar 30, 2020
Seems primarily like a cmake bug to me... Should
CMAKE_MSVC_RUNTIME_LIBRARY
really be set independent of what platform/compiler that's used? Can you please provide your suggested fix as a pull request?Add CMAKE_MSVC_RUNTIME_LIBRARY: fixes curl#5165
rogerorr commentedon Mar 30, 2020
I agree with you that it is a cmake issue - but I think this is mostly because they're trying to improve the vexing issue of handling the Microsoft compiler's setting of the relevant options controlling the C/C++ runtime library.
The existing code handling
CURL_STATIC_CRT
in curl'sCMakeLists.txt
is alreadyWIN32
specific, and the additional flags/MT
and/MTd
are Microsoft specific, so I think adding theCMAKE_MSVC_RUNTIME_LIBRARY
setting here is appropriate.P/R #5167 raised
jzakrzewski commentedon Mar 30, 2020
The behaviour is controlled by cmake policy
CMP0091
, which is automatically set to NEW if your top project declares minimum version of cmake to 3.15+. It must have been #4975 that introduced the problem for curl.If I understand the description of
CMAKE_MSVC_RUNTIME_LIBRARY
correctly, cmake will only apply it where it makes sense, so it can be set without thinking about other platforms/compilers, etc.rogerorr commentedon Mar 30, 2020
That matches my understanding.