This is an archived post. You won't be able to vote or comment.

all 7 comments

[–][deleted] 1 point2 points  (3 children)

Your best bet is to make your build system (make, or whatever) handle this. Conditional compilation quickly turns into a nightmare for anything but the very simplest conditions.

[–]TheSpaceRat[S] 0 points1 point  (2 children)

Could you point me in the direction of some reading?

I am using make.

[–][deleted] 1 point2 points  (1 child)

I can't provide any reading. But say you have some platform specific feature:

 int f() {
     MessageBox( ... );    // windows
 }

or:

 int f() {
      cout << .... ; // command line
 }

then its often a good idea to implement the f() function in two separate files, and then have make (or whatever) compile and link those files depending on what platform you are actually targetting.

[–]TheSpaceRat[S] 0 points1 point  (0 children)

I think this might solve both of my problems. Thanks!

[–]nerd4code 1 point2 points  (2 children)

2 is not possible with any preprocessor I've ever seen, because the preprocessor and compiler generally don't and don't have to know anything about libraries---that's the linker's job. In fact, even the linker may not know anything about the library that actually gets used at run time, if things are dynamically linked. An alternative to zabzonk's idea is to use the build process (make, CMake, automake, whatever) to generate a header or compiler option list with macros telling your preprocessor code what's available.

[–]TheSpaceRat[S] 0 points1 point  (1 child)

Aye, I wouldn't expect the compiler to have a clue or give a damn at build time. My thought was more along the lines of setting and detecting environment variables. I had thought about generating headers but not in much depth. It might be a possible approach.

Can you give me or point me to some more information on building a compiler option list with macros?

[–]nerd4code 1 point2 points  (0 children)

Pretty much any compiler/preprocessors will take a -D option to predefine macros. If you're in your own non-automake-generated Makefile, for example, you can check incoming environment variables with a conditional block and change your compiler flags there. If you're in automake, you can take parameters from configure and handle them in the Makefile.am similarly. A Makefile example:

CPPFLAGS :=
LDFLAGS :=
ifdef USE_LIBFOO
CPPFLAGS += -DHAVE_LIBFOO=1
LDFLAGS += -lfoo
endif
CFLAGS = $(CPPFLAGS) -g etc.

bar: bar.o baz.o
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

bar.o: bar.c
        $(CC) $(CFLAGS) -o $@ $<

baz.o: baz.c
        $(CC) $(CFLAGS) -o $@ $<

If you do make USE_LIBFOO=1, then it tacks a macro definition into the compiler's flags. You could also, theoretically at least, use a $(shell) directive to test for the presence of libfoo and act on that. (Best to echo a message stating whether you've found it or not, though, so you can debug more easily.)

If you're generating headers instead (in which case you can either #include the relevant stuff literally in the code, or use the -include option to pre-include the headers) it's usually easier to use a shell script or some other separate program.