STM32单元测试中__attribute__((weak))引发未定义引用的问题求助
I’ve run into similar headaches with weak symbols, MinGW, and CMock for STM32 unit tests—let’s break down why you’re seeing that "undefined reference" error and how to fix it.
Why This Happens
Your current setup has a few key issues that are tripping up the linker:
Mismatched weak attribute placement
You added__attribute__((weak))only to the function declaration, not the definition. In GCC (which MinGW uses), this creates a conflict: the declaration marks the symbol as weak, but the definition is treated as a strong symbol. The linker gets confused by this inconsistency, especially if your CMake link order isn’t prioritizing your mock implementation.Link order misalignment
CMake’s link order directly affects how the resolver picks symbols. If your mock library is linked after the HAL library, the linker will grab the HAL’s strong definition first. But if you’re not linking the HAL library in your unit test (common for isolated tests), the inconsistent weak/strong declaration leaves the linker unable to find a valid implementation ofHAL_TIM_IC_Init.Potentially inverted weak symbol logic
You mentioned needing to "override HAL functions"—but marking your mock as weak does the opposite: it lets the HAL’s strong definition take precedence. If your goal is to replace HAL functions with mocks, you should be making the HAL’s functions weak, not your mocks. That said, let’s cover fixes for both your current setup and the more logical override approach.
Fixes to Try
1. Fix the Weak Attribute Placement
Move the __attribute__((weak)) to the function definition to ensure the symbol is consistently marked as weak. This tells the linker to use this implementation if no strong definition exists:
#if defined (__IAR_SYSTEMS_ICC__) #pragma weak HAL_TIM_IC_Init #else // Keep the declaration clean (no weak attribute needed here) HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef* htim); #endif // Apply weak attribute directly to the definition HAL_StatusTypeDef __attribute__((weak)) HAL_TIM_IC_Init(TIM_HandleTypeDef* htim) { // Your mock implementation here }
2. Adjust CMake Link Order
Ensure your mock library is linked before the HAL library (if you need to include HAL in your tests). This lets the linker see your weak mock first, and fall back to it if the HAL’s strong definition isn’t present:
target_link_libraries(your_test_target PRIVATE your_cmock_library # Prioritize mock library stm32_hal_library # Link HAL after mock )
3. Invert Weak Symbols for Proper Overrides (Recommended)
If your real goal is to replace HAL functions with mocks, flip the weak attribute to the HAL side:
- Modify the HAL function declaration (in the HAL header) to be weak:
HAL_StatusTypeDef __attribute__((weak)) HAL_TIM_IC_Init(TIM_HandleTypeDef* htim); - Leave your mock function as a strong (normal) definition:
HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef* htim) { // Your mock implementation here }
This way, the linker will always pick your strong mock definition over the HAL’s weak one, avoiding multiple definition errors while giving you the override behavior you need.
4. Temporary Workaround: Allow Multiple Definitions
If you need a quick fix to unblock testing, add a linker flag to ignore multiple definitions (note: this is a band-aid, not a long-term solution):
target_link_options(your_test_target PRIVATE -Wl,--allow-multiple-definition )
This tells the linker to use the first symbol it encounters, but it can hide other subtle issues, so use it sparingly.
内容的提问来源于stack exchange,提问作者Le Hoang Long

