简体   繁体   English

链接器:未定义的const C结构的引用,它位于静态lib中

[英]Linker: Undefined Reference for const C structs which are located in static lib

I've following problem: 我有以下问题:

Header File "can_settings.h": 头文件“can_settings.h”:

#ifndef CAN_SETTINGS_H_
#define CAN_SETTINGS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "can.h"

extern const CAN_InitTypeDef can_initstruct;

extern const CAN_FilterInitTypeDef can_filter_acceptall;
extern CAN_FilterInitTypeDef can_filter_1;
extern CAN_FilterInitTypeDef can_filter_2;


#ifdef __cplusplus
}
#endif

#endif

Source File "can_settings.c": 源文件“can_settings.c”:

#include "can_settings.h"

const CAN_InitTypeDef can_initstruct = {
#ifdef SYSCLK_FREQ_72MHz
    // APB1_freq = 36 MHz
    /* .CAN_Prescaler = */ 24,
    /* .CAN_Mode = */ CAN_Mode_Normal,
    /* .CAN_SJW = */ CAN_SJW_1tq,
    /* .CAN_BS1 = */ CAN_BS1_8tq,
    /* .CAN_BS2 = */ CAN_BS2_3tq,
#elif defined SYSCLK_FREQ_24MHz
    // APB1_freq = 24 MHz
    /* .CAN_Prescaler = */ 16,
    /* .CAN_Mode = */ CAN_Mode_Normal,
    /* .CAN_SJW = */ CAN_SJW_1tq,
    /* .CAN_BS1 = */ CAN_BS1_8tq,
    /* .CAN_BS2 = */ CAN_BS2_3tq,
#endif
    /* .CAN_TTCM = */ DISABLE,
    /* .CAN_ABOM = */ DISABLE,
    /* .CAN_AWUM = */ DISABLE,
    /* .CAN_NART = */ DISABLE,
    /* .CAN_RFLM = */ DISABLE,
    /* .CAN_TXFP = */ ENABLE,
};

const CAN_FilterInitTypeDef can_filter_acceptall = {
    /* .CAN_FilterIdHigh = */ 0x0000,
    /* .CAN_FilterIdLow = */ 0x0000,
    /* .CAN_FilterMaskIdHigh = */ 0x0000,
    /* .CAN_FilterMaskIdLow = */ 0x0000,
    /* .CAN_FilterFIFOAssignment = */ 0,
    /* .CAN_FilterNumber = */ 0,
    /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
    /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
    /* .CAN_FilterActivation = */ ENABLE
};

const CAN_FilterInitTypeDef can_filter_1 = {
        /* .CAN_FilterIdHigh = */ 0x0000,
        /* .CAN_FilterIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterMaskIdHigh = */ 0x14FC << 3,
        /* .CAN_FilterMaskIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterFIFOAssignment = */ 0,
        /* .CAN_FilterNumber = */ 0,
        /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
        /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
        /* .CAN_FilterActivation = */ ENABLE
};

const CAN_FilterInitTypeDef can_filter_2 = {
        /* .CAN_FilterIdHigh = */ 0x0000,
        /* .CAN_FilterIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterMaskIdHigh = */ 0x1400 << 3,
        /* .CAN_FilterMaskIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterFIFOAssignment = */ 0,
        /* .CAN_FilterNumber = */ 1,
        /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
        /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
        /* .CAN_FilterActivation = */ ENABLE
};

The linker returns undefined reference to 'can_initstruct' can_filter_acceptall' 'can_filter_1' 'can_filter_2'... The files can_settings.{c, h} are built as a static library and are used in my main application(only C) and in my CAN low level driver (C++). 链接器返回未定义的引用'can_initstruct'can_filter_acceptall''can_filter_1''can_filter_2'...文件can_settings。{c,h}构建为静态库,用于我的主应用程序(仅限C)和我的CAN低级驱动程序(C ++)。 All static libraries are built before my low level drivers and main application have been built. 所有静态库都是在我的低级驱动程序和主应用程序构建之前构建的。 With objdump I dumped the static CAN settings library and all the above structs are listed in the .rodata section as it should be. 使用objdump我转储了静态CAN设置库,所有上述结构都列在.rodata部分中。 What I'm doing wrong...? 我做错了什么......?

If you're using GCC, be sure that you specify the libraries in the correct order. 如果您正在使用GCC,请确保以正确的顺序指定库。 See Why does the order in which libraries are linked sometimes cause errors in GCC? 请参阅为什么库链接的顺序有时会导致GCC错误? for a detailed description. 详细说明。

However, if you don't want to bother with the library sequence, simply specify the sequence twice instead of just one time. 但是,如果您不想打扰库序列,只需指定序列两次而不是一次。 Applied on the accepted answer of the above question, this would mean: 应用于上述问题的公认答案,这意味着:

gcc prog.o libA.a libB.a libA.a libB.a -o prog.x

As an alternative, use the -Wl,--start-group ... -Wl,--end-group flags of GCC ( GCC: what are the --start-group and --end-group command line options? ). 作为替代方案,使用-Wl,--start-group ... -Wl,--end-group GCC的-Wl,--end-group标志( GCC:什么是--start-group和--end-group命令行选项? ) 。

Ok, I got it. 好,我知道了。 The order you specify object files and libraries is VERY important in GCC! 您在GCC中指定目标文件和库的顺序非常重要! The linker searches thinks in the order that they appear, so if you have a source file that contains a call to a library function, you need to put it BEFORE the library, or the linker won't know that it has to resolve it. 链接器搜索以它们出现的顺序进行思考,因此如果您有一个包含对库函数调用的源文件,则需要将它放在库之前,否则链接器将不知道它必须解析它。 And I did it the wrong way... 我做错了......

Thx eckes for the hint. 谢谢你的暗示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM