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

能否仅用宏包裹函数调用?需通过CMake配置且不可修改源码

Solution to Wrap Function Calls (Not Definitions) with Macros via CMake

Got it, let's tackle this problem. You want to replace all calls to foo() with bar() using a macro, but you're hitting redefinition errors because the macro also replaces the foo function definition. Linker wrapping isn't an option, and you can't modify the source code—all changes need to happen via CMake. Here's how to fix this:

The Core Idea

The key is to apply the macro only to source files that call foo, not to the file that defines foo. This way, the original foo definition stays intact, while all calls get replaced with bar.

Step-by-Step Implementation

1. Identify the Source File with foo's Definition

First, figure out which file contains the original int foo(int x) { ... } definition (let's say it's foo.c for this example).

2. Configure CMake to Apply the Macro Selectively

Add these lines to your CMakeLists.txt:

# Replace this with your actual target name
add_executable(your_target main.c foo.c bar.c)

# Apply the macro to all files: replace "foo" with "bar"
target_compile_definitions(your_target PRIVATE foo=bar)

# Exclude the foo definition file from the macro—keep "foo" as-is here
set_source_files_properties(foo.c PROPERTIES COMPILE_DEFINITIONS "")

How It Works

  • When compiling files like main.c, the foo=bar macro will turn int a = foo(2); into int a = bar(2);.
  • When compiling foo.c, we clear the compile definitions, so the original int foo(int x) { ... } remains unchanged.
  • You just need to ensure bar is properly defined (either in another source file like bar.c or a header included everywhere).

What If You Don't Know Where foo Is Defined?

If you can't pinpoint the definition file, there's a trick using preprocessor conditionals (though it's a bit hacky):

First, generate a small header file via CMake (so you don't modify existing source code):

configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/wrap_foo.h.in
    ${CMAKE_CURRENT_BINARY_DIR}/wrap_foo.h
    @ONLY
)

Create wrap_foo.h.in with this content:

#ifndef WRAP_FOO_SKIP
#define foo bar
#endif

Then adjust your CMake configuration to include this header and skip the macro for the definition file:

target_include_directories(your_target PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(your_target PRIVATE -include wrap_foo.h)

# Define WRAP_FOO_SKIP for the file that contains foo's definition
set_source_files_properties(foo.c PROPERTIES COMPILE_DEFINITIONS "WRAP_FOO_SKIP")

This way, in foo.c, the foo=bar macro gets skipped because WRAP_FOO_SKIP is defined, preserving the original function definition.

Why This Works Better Than Linker Wrapping

Since you can't use linker wrapping (like --wrap in GCC), this preprocessor-based approach with CMake file control gives you exact control over which files get the macro replacement, avoiding redefinition errors entirely—no source code edits needed.

内容的提问来源于stack exchange,提问作者mmichal10

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:36:14