开发者

Automatically choosing object files for compilation

I have recently begun writing unit tests (using GoogleTest) for a C++ project. Building the main project is fairly simple: I use GCC's -MM and -MD flags to automatically generate dependencies for my object files, then I link all of the object files together for the output executable. No surpirses.

But as I'm writing 开发者_JAVA技巧unit tests, is there a way to have make or GCC figure out which object files are needed to compile each test? Right now, I have a fairly naive solution (if you can call it that) which compiles ALL available object files together for EVERY unit test, which is obviously wasteful (in terms of both time and space). Is there a way (with make, gcc, sed, or whatever else) to divine which object files are needed for a given unit test in a fashion similar to how dependencies are generated for the original source files?


It sounds like you have two groups of source files: one that actually implements your program, and another that's all the unit tests. I assume each unit test has its own main function, and unit tests never need to call each other.

If all that's true, you can put all the files from the first group in a static library, and link each of the unit tests against that library. The linker will automatically pull from the library only the object files that are needed.

In concrete Makefile terms:

LIBRARY_OBJECTS = a.o b.o c.o d.o # etc
UNIT_TESTS = u1 u2 u3 u4 # etc
UNIT_TEST_OBJECTS = $(UNIT_TESTS:=.o)

libprogram.a: $(LIBRARY_OBJECTS)
        ar cr $@ $?

$(UNIT_TESTS): %: %.o libprogram.a
        $(CC) $(CFLAGS) -o $@ $< -lprogram


You should look to a higher abstraction of project management, like Cmake or GNU Automake.


In your Makefile

     SOURCES.cpp = a.cpp b.cpp ...
     OBJECTS = $(SOURCES.cpp:%.cpp=%.o)

     all: program

     program: $(OBJECTS)
          $(LINK) -o $@ $(OBJECTS)


Maybe, depending on how orderly your test system is.

If there's a nice one-to-one relationship between header and source files, then you can use some text-converting functions (or a call to sed) to convert the machine-generated rule you already have:

foo.o: foo.cc foo.h bar.h gaz.h

into a rule for the corresponding test:

unit_test_foo: unit_test_foo.o foo.o stub_bar.o stub_gaz.o

Or if you use a lot of stubs without corresponding headers (which is a warning sign) you can link with every stub except stub_foo.o. These object files are small and don't change often, so it's cheap.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜