Автоматический выбор объектных файлов для компиляции - PullRequest
0 голосов
/ 27 июля 2010

Я недавно начал писать модульные тесты (используя GoogleTest ) для проекта C ++.Создать основной проект довольно просто: я использую флаги GCC -MM и -MD, чтобы автоматически генерировать зависимости для моих объектных файлов, затем я связываю все объектные файлы вместе для выходного исполняемого файла.Никаких сюрпризов.

Но когда я пишу модульные тесты, есть ли способ заставить make или GCC выяснить, какие объектные файлы необходимы для компиляции каждого теста?Прямо сейчас у меня есть довольно наивное решение (если можно так его назвать), которое компилирует ВСЕ доступные объектные файлы вместе для КАЖДОГО модульного теста, что явно расточительно (с точки зрения времени и пространства).Есть ли способ (с помощью make, gcc, sed или чего-либо еще) определить, какие объектные файлы необходимы для данного модульного теста способом, аналогичным тому, как генерируются зависимости для исходных файлов?

Ответы [ 4 ]

1 голос
/ 27 июля 2010

Похоже, у вас есть две группы исходных файлов: одна фактически реализует вашу программу, а другая - все модульные тесты.Я предполагаю, что каждый модульный тест имеет свою собственную функцию main, и модульные тесты никогда не должны вызывать друг друга.

Если все это правда, вы можете поместить все файлы из первой группы в статическую библиотекусвяжите каждый из модульных тестов с этой библиотекой.Компоновщик автоматически извлечет из библиотеки только те объектные файлы, которые необходимы.

В конкретных терминах Makefile:

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
1 голос
/ 27 июля 2010

Вам следует взглянуть на более высокую абстракцию управления проектами, например Cmake или GNU Automake .

0 голосов
/ 27 июля 2010

Возможно, в зависимости от того, насколько упорядочена ваша тестовая система.

Если между заголовочными и исходными файлами есть хорошие взаимно-однозначные отношения, вы можете использовать некоторые функции преобразования текста (или вызов sed) для преобразования сгенерированного машиной правила, которое у вас уже есть:

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

в правило для соответствующего теста:

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

Или, если вы используете много заглушек без соответствующих заголовков (что является предупреждающим знаком), вы можете связать их с каждой заглушкой , кроме stub_foo.o. Эти объектные файлы невелики и не часто меняются, поэтому они дешевы.

0 голосов
/ 27 июля 2010

В вашем Makefile

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

     all: program

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