2012-04-11 28 views
31

Tôi đang làm theo hướng dẫn trong mục Câu hỏi thường gặp của CMake "How can I build my MSVC application with a static runtime?" để tập trung chọn thời gian chạy MSVC cho một loạt các dự án CMake lồng nhau (chúng được kéo vào dưới dạng mô-đun con Git và thêm vào dự án chính CMake của find_package() chỉ thị).Thiết lập thời gian chạy MSVC trong CMake

Vì vậy, tôi đã viết macro này CMake:

macro(configure_msvc_runtime) 
    if(MSVC) 
    # Default to statically-linked runtime. 
    if("${MSVC_RUNTIME}" STREQUAL "") 
     set(MSVC_RUNTIME "static") 
    endif() 
    # Set compiler options. 
    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 
    ) 
    if(${MSVC_RUNTIME} STREQUAL "static") 
     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() 
    else() 
     message(STATUS 
     "MSVC -> forcing use of dynamically-linked runtime." 
    ) 
     foreach(variable ${variables}) 
     if(${variable} MATCHES "/MT") 
      string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}") 
     endif() 
     endforeach() 
    endif() 
    endif() 
endmacro() 

tôi gọi macro này vào đầu gốc của tôi CMakeLists.txt (trước bất kỳadd_library() hoặc add_executable() gọi được thực hiện) và thêm một chút in debugging :

configure_msvc_runtime() 
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 "Initial build flags:") 
foreach(variable ${variables}) 
    message(STATUS " '${variable}': ${${variable}}") 
endforeach() 
message(STATUS "") 

Sau đó, tôi chạy CMake để tạo ra một giải pháp Visual Studio như sau:

và tôi nhận được các kết quả sau:

-- MSVC -> forcing use of dynamically-linked runtime. 
-- Initial build flags: 
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG 
-- 'CMAKE_C_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG 
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG 

Bây giờ, điều là khi tôi bắt đầu Visual Studio và kiểm tra các tính chất dự án dưới "C/C++, Code Generation", tôi thấy rằng " Cài đặt Thư viện thời gian chạy "không phù hợp với các tùy chọn được in trong trình bao. Trong cấu hình "Release", "MinSizeRel" và "RelWithDebInfo", tôi nhận được kết quả mong đợi ("Multi-threaded DLL/MD", nhưng cấu hình "Debug" vẫn hiển thị "Multi-threaded/MT".

Ngoài ra, khi tôi buộc sử dụng thời gian chạy tĩnh liên kết, tôi nhận được kết quả tương tự Nếu tôi chạy

cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static 

tôi nhận được các kết quả sau:.

-- MSVC -> forcing use of statically-linked runtime. 
-- Initial build flags: 
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1 
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG 
-- 'CMAKE_C_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG 
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1 
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG 
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG 

Tuy nhiên tất cả các cấu hình sản xuất "Multi- giá trị luồng/MT "cho cài đặt" Thư viện thời gian chạy ".

Ai đó có thể cho tôi biết tôi đang làm gì sai, hoặc nếu đây là lỗi trong CMake (2.8.7) hay gì đó?


Đối với những gì nó có giá trị, Nếu tôi tạo ra Visual Studio 2010 file dự án, tôi nhận được một giá trị khác nhau cho cấu hình "Debug", nhưng vẫn không phải là người tôi chọn. Trong mọi trường hợp, cài đặt xuất hiện trong phông chữ thông thường cho cấu hình "Gỡ lỗi" trong khi nó xuất hiện trong phông chữ in đậm cho các cấu hình khác, gợi ý rằng chúng là ghi đè. Hơn nữa, nếu tôi mở tệp dự án XML, tôi thấy rằng cấu hình "Gỡ lỗi" không có cài đặt cho thuộc tính "RuntimeLibrary" của phần tử "Công cụ" với thuộc tính "Tên = VCCLCompilerTool". Tất cả các cấu hình khác đều có cài đặt rõ ràng.

+0

vĩ đại giải pháp! – mattiash

Trả lời

10

Có vẻ như tất cả trong khi tôi đang làm việc về điều này, tôi quên xóa cấu hình CMake xấu mà tôi đang cố gắng thay thế.

Tiếp tục xuống xây dựng kịch bản, tôi đã rời bugger này chút:

set(CMAKE_CXX_FLAGS_DEBUG 
    "/DWIN32 /D_WINDOWS /EHsc /WX /wd4355 /wd4251 /wd4250 /wd4996" 
    CACHE STRING "Debug compiler flags" FORCE 
) 

Về cơ bản, tôi đã trọng kết quả của configure_msvc_runtime() vĩ mô với xây dựng cờ mà không thiết lập thời gian chạy MSVC.

Xin lỗi vì sự cố!

+0

Bạn thực sự đã lưu tôi với giải pháp của bạn để buộc các thư viện thời gian chạy tĩnh! – linello

5

Tôi lấy mã của bạn và tổng quát nó để làm việc cho mọi cấu hình hiện có và không chỉ cho Debug/Release/RelWithDebInfo/MinSizeRel.

Ngoài ra tôi đã làm cho nó để làm việc với gcc quá - check it out here

+0

là nó có thể chỉ định (hoặc ghi đè nếu nó được chỉ định đã) CRT tĩnh hoặc động liên kết từ dòng lệnh? Chỉ cần tránh sửa đổi các kịch bản libs của bên thứ ba, hãy xây dựng các script –

+0

@AndyT bạn có thể tạo một proxy CMakeLists.txt '' 'add_subdirectory'''ies lib của bên thứ ba - và bạn có thể đặt thời gian chạy ở đó - nhưng nếu bộ lib của bên thứ ba thời gian chạy trên chính nó thì nó sẽ có một tùy chọn cho điều đó ... – onqtam

Các vấn đề liên quan