how can i build static program by cmake+clang+nmake on windows?

i asked this question on stackoverflow two days ago.this is original post.
due to my low english proficiency,please don’t be surprised if there are any strange expressions.
thanks for your response.

So you want your executable to statically link to CRT (C++ runtime)? Because the term “static program” is probably not the most correct one.

You can take a look at how Microsoft itself does it in their vcpkg toolchain. So in your project it would be something like this (note the leading space inside quotes):

string(APPEND CMAKE_C_FLAGS_DEBUG " /MT")
string(APPEND CMAKE_C_FLAGS_RELEASE " /MT")

string(APPEND CMAKE_CXX_FLAGS_DEBUG " /MT")
string(APPEND CMAKE_CXX_FLAGS_RELEASE " /MT")

But for that to work you might need to use Visual Studio generator (I’ve never used NMake Makefiles).

This approach is quite obsolete.
Use preferably the variable CMAKE_MSVC_RUNTIME_LIBRARY or the target property MSVC_RUNTIME_LIBRARY to control how the build is done.

1 Like

i’ve tried these two variables but seems not work. Could you please give me an example?
actually, i’ve solved this weird problem by use this:

string(REPLACE "--dependent-lib=msvcrtd" "--dependent-lib=libcmtd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
string(REPLACE "-D_DLL" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})

and the whole CMakeLists.txt is:

cmake_minimum_required(VERSION 3.5)


set(CMAKE_C_COMPILER "C:/Software/LLVM/bin/clang.exe")
set(CMAKE_CXX_COMPILER "C:/Software/LLVM/bin/clang++.exe")

project(helloworld)

set(CMAKE_VERBOSE_MAKEFILE ON)

string(REPLACE "--dependent-lib=msvcrtd" "--dependent-lib=libcmtd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
string(REPLACE "-D_DLL" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})

message(${CMAKE_CXX_FLAGS_DEBUG})

set(CMAKE_CXX_COMPILER_TARGET i686-pc-windows-msvc)

set(CMAKE_CXX_STANDARD 17)
set(SOURCE helloworld.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})

may this is a stupid solution,I don’t know how to do it better…
please reply me if you have any better suggestions, thank you very much.

I see neither my/Microsoft’s suggestion about /MT nor Marc’s suggestion about MSVC_RUNTIME_LIBRARY (much better one, admittedly) in your project file fragment.

i tried both of your suggestions but seems clang doesn’t support MSVC_RUNTIME_LIBRARY (just ignore and nothing happened) and /MT(it did good job in Visual Studio but i prefer not to use visual studio but vscode)… therefore, i replace the flags manually and delete those code…

The following is perfectly operational but require, at least, CMake version 3.15 (you specified version 3.5 through cmake_minimum_required() command):

cmake_minimum_required(VERSION 3.15)

set(CMAKE_C_COMPILER "C:/Software/LLVM/bin/clang.exe")
set(CMAKE_CXX_COMPILER "C:/Software/LLVM/bin/clang++.exe")

project(helloworld)

set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_STANDARD 17)
set(SOURCE helloworld.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})
set_property(TARGET main PROPERTY MSVC_RUNTIME_LIBRARY MultiThreadedDebug)

By the way, I strongly suggest to you to read the CMake documentation. For example, setting variable CMAKE_CXX_COMPILER_TARGET outside a toolchain file is irrelevant.

thanks for your perfect solution, i’ll try to read cmake doc.