You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在macOS中使用CMake构建多语言项目的方法咨询

Is Your CMake Implementation Correct?

Your approach is conceptually sound, but there are a few bugs and opportunities for improvement that will make this more reliable and maintainable.

Key Issues in the Current Code

Let's break down the problems first:

  • Typo in Objective-C file handling: In the .m case, you're using ${SRC_FILE} (uppercase) instead of the loop variable ${src_file} (lowercase). This variable is undefined, so those files won't get the correct OBJC_FLAGS applied.
  • Incorrect regex patterns: The MATCHES checks use patterns like .cpp$, but in regular expressions, the dot (.) matches any character. This means a file named mycpp.txt would incorrectly match .cpp$. You need to escape the dot to match it literally, using double backslashes (since CMake escapes backslashes in strings). The correct pattern for .cpp is "\\.cpp$".
  • Potential scope/quoting issues: While not a critical bug here, wrapping the regex pattern in quotes prevents unexpected behavior if your patterns ever include spaces or special characters.

Better Approach: Use CMake's Built-in Language Flags

Instead of manually checking file extensions and setting per-file properties, CMake has native support for language-specific compilation flags. This is the recommended method because it's less error-prone, automatically applies to all files of the corresponding language, and integrates better with CMake's default behavior.

Here's how to rewrite your flags using CMake's standard variables:

# Append your custom flags to CMake's default flags (don't overwrite them!)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64 -fmessage-length=0 -std=c++11")
set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} -fobjc-arc")
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -std=gnu++11 -stdlib=libc++")

Why This Is Better:

  • No manual extension checks: CMake automatically detects the language for each file based on its extension (.c → C, .cpp → C++, .m → Objective-C, .mm → Objective-C++).
  • Preserves default flags: By appending your flags to ${CMAKE_C_FLAGS} instead of overwriting, you keep CMake's default compiler flags (like optimization flags for different build types).
  • Maintainable: Adding new files later doesn't require updating any helper functions—they'll get the correct flags automatically.

Corrected Version of Your Original Function (If You Still Need Per-File Control)

If you have specific cases where you need per-file flags (e.g., overriding global flags for a single file), here's the fixed version of your function:

set(CPP_FLAGS "-x c++ -arch x86_64 -fmessage-length=0 -std=c++11")
set(OBJCPP_FLAGS "-x objective-c++ -std=gnu++11 -stdlib=libc++ ")
set(OBJC_FLAGS "-x objective-c -fobjc-arc")
set(C_FLAGS "-x c -arch x86_64")

function(set_src_files_according_to_language in_source_files)
    foreach(src_file ${in_source_files})
        if(${src_file} MATCHES "\\.cpp$")
            set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "${CPP_FLAGS}")
        elseif(${src_file} MATCHES "\\.mm$")
            set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "${OBJCPP_FLAGS}")
        elseif(${src_file} MATCHES "\\.m$")
            set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "${OBJC_FLAGS}")
        elseif(${src_file} MATCHES "\\.c$")
            set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "${C_FLAGS}")
        endif()
    endforeach()
endfunction()
  • Fixed the typo in the .m case.
  • Updated regex patterns to escape dots correctly.
  • Removed the redundant SRC argument from endforeach (it's optional and inconsistent with the loop variable name).

Content of the question originates from Stack Exchange, asked by Zohar81

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:22:30