1

I'm having a project that does lots of this

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
// do some legacy stuff
#else
// do current stuff
#endif

where KERNEL_VERSION is defined as

#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))

I'd like to eliminate the defines that are not relevant for the current version, but tools like sunifdef don't evaluate the KERNEL_VERSION macro, so something like

 sunifdef --replace -DKERNEL_VERSION\(a,b,c\)=\(\(\(a\)\<\<16\)+\(\(b\)\<\<8\)+\(c\)\) -DLINUX_VERSION_CODE=3.13.1 *

fails with the message

sunifdef: error 0x04200: Garbage in argument "-DKERNEL_VERSION(a,b,c)=(((a)<<16)+((b)<<8)+(c))"

How do I get around this?

3
  • you probably shouldn't look for a workaround, and trust the developers who wrote the code. probably it doesn't work with older kernel versions. Commented Sep 18, 2013 at 22:19
  • That's not what I'm trying to do, I want to remove the code for older versions to clean up the file. Commented Sep 18, 2013 at 22:20
  • Ugh, this a pre-pre-processor. Oracle took care of that. Commented Sep 18, 2013 at 22:33

3 Answers 3

2

With sunifdef 3.1.3, you can't do it, as you demonstrated. Nor can you do it with earlier versions of coan such as 4.2.2.

However, with coan 5.2 (the current version), you can almost do what you are after.

$ cat legacy.c
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
do(some,legacy,stuff)
#else
do(current,stuff)
#endif
$ coan source -DLINUX_VERSION_CODE=0x020635 legacy.c
coan: /Users/jleffler/soq/legacy.c: line 1: warning 0x0041c: "-DKERNEL_VERSION(a,b,c)=(((a) << 16) + ((b) << 8) + (c))" has been assumed for the current file
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
do(current,stuff)
$ coan source -DLINUX_VERSION_CODE=0x020624 legacy.c
coan: /Users/jleffler/soq/legacy.c: line 1: warning 0x0041c: "-DKERNEL_VERSION(a,b,c)=(((a) << 16) + ((b) << 8) + (c))" has been assumed for the current file
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
do(some,legacy,stuff)
$

This is close to what you want, but not quite. It gives 'correct' output, but maybe not 'helpful' output. It gives you the code that would be compiled for the LINUX_VERSION_CODE specified on the command line, whereas you'd probably like the conditionals based on LINUX_VERSION_CODE and KERNEL_VERSION that are not false to survive into the output.

Sign up to request clarification or add additional context in comments.

Comments

2

The successor to sunifdef seems to be coan, and the following command seemed to work (on one simple file):

coan source "-DLINUX_VERSION=KERNEL_VERSION(2,18,1)" \
            "-DKERNEL_VERSION(a,b,c)=((a)*0x10000 + (b)*0x100 + (c))" \
            testfile.c

I think using the KERNEL_VERSION macro to define LINUX_VERSION is prettier, but you might prefer Chris Dodd's version in hex. Two dots in a number is definitely not going to work.

Comments

0

The error is coming from the fact that you can't define macros with arguments on the command line with -D -- you can only define simple macros. However, you shouldn't NEED to define KERNEL_VERSION on the command line as the #define in the source should be fine. You should only need
-DLINUX_VERSION_CODE=0x30d01 -- you need to define it as a single integer constant (hex is easiest) rather than withs dots.

1 Comment

Complete preprocessors do support defining macros with arguments on the command line. What the OP tried to do would have worked if it was an argument to gcc or clang instead of sunifdef.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.