View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0009445CMakeCMakepublic2009-08-21 23:272016-06-10 14:30
ReporterTaras 
Assigned ToBill Hoffman 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusclosedResolutionmoved 
PlatformOSOS Version
Product VersionCMake-2-6 
Target VersionFixed in Version 
Summary0009445: Ability to select static runtime when use generator for MSVC
DescriptionI couldn`t find out how to select static runtime for libraries when generate MSVC solution.
Google give only one usefull link related to problem,
http://www.cmake.org/pipermail/cmake/2008-September/023877.html [^]
But seems it is some kind of hack.
Could you add this? I think it can be another one property or even another one parameter in add_library, add_test, etc
TagsNo tags attached.
Attached Files

 Relationships
has duplicate 0011093closedDavid Cole [VS] Support static run-time 

  Notes
(0017175)
Taras (reporter)
2009-08-21 23:28

Or at least provide some examples or better documentation on how to workaround this
(0017176)
Philip Lowman (developer)
2009-08-22 16:35

The default compilation flags for CMake generated projects (at least as of MSVC 2005) are /MD. I'm assuming you want /MT which is the multithreaded static runtime flag.

Here are a two options to change this:

1. Use the code snippit that you linked to to replace any "/MD" entries in the compilation flags with "/MT". Assuming you would want these compilation flags to affect all targets, you would want to do this before declaring any add_executable() or add_library() targets and before recursing into any subdirectories with add_subdirectory().

foreach(flag_var
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    if(${flag_var} MATCHES "/MD")
        string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
    endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)

2. Manually change the CMAKE_CXX_FLAGS_* CMake cache variables by showing Advanced variables in the cache editor.

Obviously the first option is probably better if this is a permanent thing. It could also be made configurable if this is needed.

if(MSVC)
   option(BUILD_WITH_STATIC_RUNTIME "Build the libraries with /MT" ON)
   if(BUILD_WITH_STATIC_RUNTIME)
      # do REGEX REPLACE code
   endif()
endif()

I don't think adding a flag to add_library() or add_executable() would be good for this as it would conflict with what people already do which is change the compilation flags.

I have added this answer to the FAQ

http://www.vtk.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F [^]
(0017177)
Taras (reporter)
2009-08-22 20:05

Thanks a lot. But seems it is not what I am exaclty need.
Is it possible to declare simulationiously two variants of library: one with static runtime and the second with dynamic? I tried

FUNCTION(enable_static_runtime)
    FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
    ENDFOREACH(flag_var)
ENDFUNCTION(enable_static_runtime)

FUNCTION(disable_static_runtime)
    FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        STRING(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
    ENDFOREACH(flag_var)
ENDFUNCTION(disable_static_runtime)

# declare static library with dynamic runtime
ADD_LIBRARY(drwcurl_s STATIC ${libcurl_src})
SET(CURL_s_LIBRARIES ${drwcurl_s_location} PARENT_SCOPE)
SET(CURL_s_DEFINITIONS -DCURL_STATICLIB PARENT_SCOPE)

# declare also static library with static runtime for msvc
IF(MSVC)
    enable_static_runtime()
    ADD_LIBRARY(mycurl_s_c STATIC ${libcurl_src})
    disable_static_runtime()
    SET(CURL_s_c_LIBRARIES ${mycurl_s_c_location} PARENT_SCOPE)
    SET(CURL_s_c_DEFINITIONS -DCURL_STATICLIB PARENT_SCOPE)
ENDIF(MSVC)

But this doesn`t work properly. How can I change CXX flags only for target?
(0017178)
Taras (reporter)
2009-08-22 20:25

Hm, what about workaround idea to manually remove /MD or /MDd flags from CMAKE_CXX_FLAGS_* and add them only as additional target compile flags after any ADD_LIBRARY, ADD_EXECUTABLE and others.
(0017179)
Taras (reporter)
2009-08-22 21:04
edited on: 2009-08-22 21:07

The previous doesn`t work at all.
I placed
FUNCTION(enable_static_runtime)
    FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
    ENDFOREACH(flag_var)
    MESSAGE("Static runtime enabled")
    MESSAGE("CMAKE_CXX_FLAGS_DEBUG="${CMAKE_CXX_FLAGS_DEBUG})
# tried this too but it wasnt helpfull
# SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING)
ENDFUNCTION(enable_static_runtime)

enable_static_runtime()

in my topmost CMakeLists.txt

I got in console
Static runtime enabled
CMAKE_CXX_FLAGS_DEBUG=/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1

But still had in cache
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1

and in project properties Multi-threaded debug DLL runtime

How can I really change CMAKE_CXX_FLAGS_DEBUG variable?
So
http://www.vtk.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F [^]
is inapplicable

(0017233)
Philip Lowman (developer)
2009-08-29 21:16
edited on: 2009-08-29 21:19

There are 4 choices I am aware of.

1. Create a local variable called CMAKE_CXX_FLAGS_<FOO> which overrides the cache variable. This is what I suggested in the FAQ and it should work fine in terms of the actual generated makefiles/project files except whatever is in the CACHE would have to be ignored.

One problem with your code above is you are using a function() without setting the new variables to the PARENT_SCOPE. Replace your code with a MACRO and things should kinda work better except you'll soon discover (as I did) that CMAKE_CXX_FLAGS_<FOO> appears to be a per-directory level thing. You can't change the flags in the middle of a directory and have targets affected. :(

2. Manually modify the cache after an initial configure to contain the flags you want (not good).

3. Use the FORCE option to set() to exactly set compile flags into the cache on every configure. This has the effect of if the user changes a variable in the cache editor and configures again it will reset back to the way it was.

4. (the most promising)
Change the initial seeding values for CMAKE_CXX_FLAGS_<FOO>_INIT by using a CMAKE_USER_MAKE_RULES_OVERRIDE and/or CMAKE_USER_MAKE_RULES_OVERRIDE_CXX file. To do this you would create a .cmake file that defines the flags you want, then set the override variable to the path of that file prior to calling project().

E.g.:

set(CMAKE_USER_MAKE_RULES_OVERRIDE
    ${CMAKE_CURRENT_SOURCE_DIR}/c_flag_overrides.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX
    ${CMAKE_CURRENT_SOURCE_DIR}/cxx_flag_overrides.cmake)
project(Bar)


I think I like option 4 a lot better if the /MT is going to be a permanent change across all targets (very likely considering what this flag does).

It's important to note though that owing to how option 4 works you won't be able to undo it after it's run once. That is to say, setting the _INIT variables only works on the initial configure.

(0017389)
Bill Hoffman (manager)
2009-09-11 17:29

Yes, rule override should be used for this.
(0017654)
Taras (reporter)
2009-09-19 23:22

Hi,
I tried CMAKE_USER_MAKE_RULES_OVERRIDE as you advised, and it works fine. But I was unable to solve my initial problem.
I trying to migrate a huge crossplatform project in our company from own ugly build system to cmake. There are a few libs that must be build in 3 variants on windows:
shared with shared runtime, static with shared runtime and static with static runtime

I used CMAKE_USER_MAKE_RULES_OVERRIDE together with redefining INIT variables and almost solved this, but now the last problem is that I cannot specify <per target> and <per configuration> compile flags. COMPILE_FLAGS target property is not expanded to different configurations.

There is a feature request
http://www.vtk.org/Bug/view.php?id=6493, [^] seems it is what I am really need.

Please close this ticket
(0018004)
Philip Lowman (developer)
2009-10-07 01:10

I've updated the FAQ with an example of rule override. This bug can probably be closed.

http://www.vtk.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F [^]
(0024597)
Maddes (reporter)
2011-01-11 16:02
edited on: 2011-01-16 09:35

I use the following code that works well for me, at least in a clean build directory. Still I would like to have this handled inside CMake.

if(POLICY CMP0012)
    cmake_policy(SET CMP0012 NEW)
endif()

...

# Compilation options
# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS [^]
# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library [^]
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx [^]
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx [^]
option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)

...

###
### General compilation settings
###
if(${BUILD_SHARED_LIBS})
    set(LABEL_SUFFIX "shared")
else()
    set(LABEL_SUFFIX "static")
endif()

if(${MSVC})
    ### General stuff
    # a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003))
    # plus set lib suffix for later use and project label accordingly
    # see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx [^]
    # http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx [^]
    set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC
    set(LIB_RT_OPTION "/MD")
    #
    if(NOT ${MSVC_SHARED_RT}) # User wants to have static runtime libraries (/MT, /ML)
        if(${MSVC_STHREADED_RT}) # User wants to have old single-threaded static runtime libraries
            set(LIB_RT_SUFFIX "ml")
            set(LIB_RT_OPTION "/ML")
            if(NOT ${MSVC_VERSION} LESS 1400)
                message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).")
            endif()
        else()
            set(LIB_RT_SUFFIX "mt")
            set(LIB_RT_OPTION "/MT")
        endif()

        # correct linker options
        foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
            foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
                set(var_name "${flag_var}")
                if(NOT "${config_name}" STREQUAL "")
                    set(var_name "${var_name}_${config_name}")
                endif()
                string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}")
            endforeach()
        endforeach()
    endif()
    #
    set(LABEL_SUFFIX "${LABEL_SUFFIX} ${LIB_RT_OPTION}")

    # b) Change prefix for static libraries
    set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs

    # c) Correct suffixes for static libraries
    if(NOT ${BUILD_SHARED_LIBS})
        ### General stuff
        set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}")

        ### Project stuff
        # correct external library names
        set(YAML_CPP_LIB "${CMAKE_STATIC_LIBRARY_PREFIX}${YAML_CPP_LIB}${LIB_RT_SUFFIX}")
        set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}d")
    endif()
endif()

...

add_library(pinproc
...
)

set_target_properties(pinproc PROPERTIES
    PROJECT_LABEL "pinproc ${LABEL_SUFFIX}"
...
)

if(${MSVC})
    if(NOT ${BUILD_SHARED_LIBS})
        # correct library names
        set_target_properties(pinproc PROPERTIES
            DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d"
            RELEASE_POSTFIX "${LIB_TARGET_SUFFIX}"
            MINSIZEREL_POSTFIX "${LIB_TARGET_SUFFIX}"
            RELWITHDEBINFO_POSTFIX "${LIB_TARGET_SUFFIX}"
        )
    endif()
endif()

(0039950)
Mikhail Titov (reporter)
2015-12-03 13:36
edited on: 2015-12-03 13:41

I believe this is still an issue. Workarounds are fine for our own projects, but if I use ExternalProject (zlib is a good example), the only option left is to patch it. That just looks ugly and a PITA (https://cmake.org/pipermail/cmake/2014-January/056769.html [^]) :(

(0041588)
Kitware Robot (administrator)
2016-06-10 14:27

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2009-08-21 23:27 Taras New Issue
2009-08-21 23:28 Taras Note Added: 0017175
2009-08-22 16:35 Philip Lowman Note Added: 0017176
2009-08-22 20:05 Taras Note Added: 0017177
2009-08-22 20:25 Taras Note Added: 0017178
2009-08-22 21:04 Taras Note Added: 0017179
2009-08-22 21:07 Taras Note Edited: 0017179
2009-08-29 21:16 Philip Lowman Note Added: 0017233
2009-08-29 21:19 Philip Lowman Note Edited: 0017233
2009-09-11 17:29 Bill Hoffman Status new => assigned
2009-09-11 17:29 Bill Hoffman Assigned To => Bill Hoffman
2009-09-11 17:29 Bill Hoffman Note Added: 0017389
2009-09-19 23:22 Taras Note Added: 0017654
2009-10-07 01:10 Philip Lowman Note Added: 0018004
2011-01-11 16:02 Maddes Note Added: 0024597
2011-01-11 16:03 Maddes Note Edited: 0024597
2011-01-11 16:04 Maddes Note Edited: 0024597
2011-01-15 14:10 Maddes Note Edited: 0024597
2011-01-15 14:14 Maddes Note Edited: 0024597
2011-01-15 17:10 Maddes Note Edited: 0024597
2011-01-16 09:35 Maddes Note Edited: 0024597
2011-02-03 18:33 David Cole Relationship added has duplicate 0011093
2015-12-03 13:36 Mikhail Titov Note Added: 0039950
2015-12-03 13:41 Mikhail Titov Note Edited: 0039950
2016-06-10 14:27 Kitware Robot Note Added: 0041588
2016-06-10 14:27 Kitware Robot Status assigned => resolved
2016-06-10 14:27 Kitware Robot Resolution open => moved
2016-06-10 14:30 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team