Splaty
Splaty

Reputation: 634

Compilation error when linking global array of structs

I'm trying to define an array of structs in somedriver_cardSpecific.c, declare it in somedriver.h, then use it in somedriver.c. But I get a compilation error in somedriver.c:

error: array '__mod_i2c__somedriver_idtable_device_table' assumed to have one element [-Werror]
 extern const typeof(name) __mod_##type##__##name##_device_table

in expansion of macro 'MODULE_DEVICE_TABLE'
 MODULE_DEVICE_TABLE(i2c, somedriver_idtable);

Here are the relevant bits of code:

somedriver_cardSpecific.c

#include <linux/i2c.h>

#include "somedriver.h"

struct i2c_device_id somedriver_idtable[] = {
    { "somedevice_1",   0 },
    { "somedevice_2",   1 },
    { },
};

somedriver.h

#include <linux/i2c.h>

extern struct i2c_device_id somedriver_idtable[];

somedriver.c

#include "somedriver.h"

MODULE_DEVICE_TABLE(i2c, somedriver_idtable);

Not sure why I'm getting that compilation error. Am I doing this linkage wrong: does the definition of somedriver_idtable need a definite size? or is it a constraint of the MODULE_DEVICE_TABLE macro?

If you're wondering why in this Linux device driver I'm separating the i2c_device_id table from the MODULE_DEVICE_TABLE: I'm trying to re-factor the code so later boards that have different amounts of i2c devices can just create their own somedriver_cardSpecific.c file and compile/link that.

Thank you for the help.

EDIT: The macro is defined in Linux kernel: linux/module.h. http://lxr.free-electrons.com/source/include/linux/module.h#L212

210 #ifdef MODULE
211 /* Creates an alias so file2alias.c can find device table. */
212 #define MODULE_DEVICE_TABLE(type, name)                                 \
213 extern const typeof(name) __mod_##type##__##name##_device_table         \
214   __attribute__ ((unused, alias(__stringify(name))))
215 #else  /* !MODULE */
216 #define MODULE_DEVICE_TABLE(type, name)
217 #endif

Upvotes: 1

Views: 240

Answers (2)

Splaty
Splaty

Reputation: 634

Here's what ended up working for me:

  1. I cleaned the build directory. Building on top of old builds caused failures with these files, not sure why.
  2. As @IanAbbott mentioned, I moved the MODULE_DEVICE_TABLE() macro to be within the same file as the i2c_device_id table definition. As Ian and Fabio mentioned the macro needs to see the size of the table and cannot see that with just the extern. I didn't want to have future coders needing to define the size with every new board so I chose to keep them together. Here's how that will look:

somedriver_cardSpecific.c

#include <linux/module.h>    
#include <linux/i2c.h>
#include "somedriver.h"

struct i2c_device_id somedriver_idtable[] = {
    { "somedevice_1",   0 },
    { "somedevice_2",   1 },
    { },
};
MODULE_DEVICE_TABLE(i2c, somedriver_idtable);

somedriver.h

#include <linux/i2c.h>

extern struct i2c_device_id somedriver_idtable[];

Driver still works fine. I hope that helps someone who comes across same problem.

Upvotes: 0

Fabio Ceconello
Fabio Ceconello

Reputation: 16049

You're getting an error just because you have the flag to treat all warnings as errors on. One way to solve that would be to disable such flag, but I'd recommend as a better approach to declare explicitly the array size [3] both in the header and in the .c, this should make the warning go away and the error with it.

Upvotes: 1

Related Questions