Open fentanyluser opened 3 years ago
Just guessing, but that's probably a setting you'd want to put in your toolchain. So that it is propagated to all your dependencies.
I've been trying to do this same thing today. Setting the runtime in the toolchain doesn't seem to alter how Boost gets compiled resulting in messages like:
libboost_program_options-mt-gd-x32.lib(value_semantic.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MTd_StaticDebug'
The boost build seems to set it based on the _DLL #define.
if(MSVC)
hunter_check_toolchain_definition(NAME "_DLL" DEFINED _hunter_vs_md)
hunter_cmake_args(
Boost
CMAKE_ARGS
BOOST_BUILD_DYNAMIC_VSRUNTIME=${_hunter_vs_md}
)
endif()
But this doesn't seem to be working as intended. I set the compiler option in the toolchain and see that my code is being compiled with /MTd
but _DLL
in the toolchain id is 1
implying that its /MDd
Yet it is unset when I build my code
Value of _DLL: _DLL
Value of _MT: 1
Yeah I ended up just disabling hunter and compiling each lib manually, kind of a pain, would be nice to have this feature.
I have the cmake_policy(SET CMP0091 NEW)
in my toolchain file but I kinda feel like it is ignoring the setting. I noticed the toolchain CMakeLists.txt is set to 3.0 as the minimum cmake version.
Just confirmed cmake_policy has no effect in a toolchain file.
(╯°□°)╯︵ ┻━┻
Here be 🐉🐉🐉
Hunter only propagates the Toolchain file, but you can't change the MSVC flags CMAKE generates in pre-3.15 versioned configs until after it has loaded the MSVC toolchain info which happens AFTER the toolchain file is processed.
So... h4ck5
3.15 also introduced CMAKE_PROJECT_INCLUDE
which includes a cmake file after the toolchain is loaded but before anything in the project is processed. This is done regardless of what minimum version is specified in CMakeLists.txt.
∴
We can specify a default toolchain in our CMakeLists.txt
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
set(
CMAKE_TOOLCHAIN_FILE
"cmake/toolchain.cmake"
CACHE
FILEPATH
"Default toolchain used for both hunter and our code"
)
That in turn configures an after project include
set(
CMAKE_PROJECT_INCLUDE
"${CMAKE_CURRENT_LIST_DIR}/project_after.cmake"
CACHE
FILEPATH
"Project after include"
)
That performs the hacks on the flags when running msvc
#This has to happen after the toolchain is done loading.
IF(MSVC)
#Static build
#cmake_policy(SET CMP0091 NEW) #This doesn't work in a toolchain, nor in project_after
#But we still need to set this for the root Cmake which requires cmake 3.15 for the project_include rule...
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
#This is for cmake_minimum_version less than 3.15 (AKA the Hunter builds)
set(variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
message(STATUS "MSVC -> forcing use of statically-linked runtime.")
foreach(variable ${variables})
if(${variable} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}")
endif()
endforeach()
ENDIF(MSVC)
The toolchain id does indeed reflect this modification, boost believes it is being compiled with a static runtime. I'll let you know in a few hours if it worked once it is done compiling boost. For the 20th time... 😭😭😭😭
Did appear to work, I don't see the runtime dlls in dependency walker anymore. Sent it off to someone without the runtime for testing.
@thomassuckow yay hax! lol
Did it work in your testing?
@rbsheth Ya, I did end up having to add set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
as well to the after project include script because I went ahead and updated the minimum cmake version in our main project and because of that the string replacement doesn't work on our project, just on the HUNTER builds.
I edited the script above to reflect having to do it both ways.
To set policies in cmake toolchain you could try e.g. https://cmake.org/cmake/help/latest/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.html?highlight=cmake_policy_default#variable:CMAKE_POLICY_DEFAULT_CMP%3CNNNN%3E
CMAKE_POLICY_DEFAULT_CMP0114=NEW
I think I found a less hacky way, create a local hunter config file with the following to get a statically linked runtime for boost
hunter_config(
Boost
VERSION ${HUNTER_Boost_VERSION}
CMAKE_ARGS
BUILD_SHARED_LIBS=OFF
BOOST_BUILD_DYNAMIC_VSRUNTIME=OFF
USE_CONFIG_FROM_BOOST=ON
)
When searching for this boost version I use the following, because I like to be able to still build with system-boost, when not using Hunter:
if(HUNTER_ENABLED)
find_package(Boost 1.64.0 CONFIG REQUIRED system filesystem)
else()
find_package(Boost 1.64.0 REQUIRED system filesystem)
endif()
I think updating the documentation with the BOOST_BUILD_DYNAMIC_VSRUNTIME
variable would be a great idea
You can set runtime in cmake in your main CMakeLists.txt
So your project will use static runtime but everything built with hunter will still be dynamic and unlinkable. Was not able to find a way to change this.