%.o: Fast/**/%.cpp $(FAST_HEADERS)
g++ $@ -o $<
由于**,这永远不会适用。您还颠倒了$@ 和$<。你可以使用
Fast/tests/%.o: Fast/tests/%.cpp | $(FAST_HEADERS)
Fast/src/%.o: Fast/src/%.cpp | $(FAST_HEADERS)
%.o: %.cpp
g++ -o $@ $<
真正的问题
也就是说,让我们找出链接器消息的问题所在。老实说,我花了 更多时间 在这里“不经意间”找到它。首先,我显然是按文档使用的,主要是:
还有一些邮件列表/SO 帖子:
老实说,我学到的唯一有形的东西就是
但是,其他记录在案的标志 BOOST_TEST_DYN_LINK 和 BOOST_TEST_NO_MAIN 的效果为零。经过一些试验和错误以及预处理器#error 调试后,我发现这些符号在包含后都只是undef-ined
#include <boost/test/included/unit_test.hpp>
我没有立即认出/included/ 部分。一时兴起,我想改成:
#include <boost/test/unit_test.hpp>
这行得通,但现在main 是未定义。所以,我想出了一个以下重构的 makefile 和一个额外的 Fast/tests/module.cpp 来定义 main.毫无疑问,这一切还不是完全最优的。例如。我认为,由于您要链接动态库,因此应该定义 BOOST_TEST_DYN_LINK,但如果没有那个¯\(ツ)/¯,它似乎可以正常工作。
因此,此处显示的部分 Makefile 旨在启发您在需要时如何完成特定的高级任务。
test: # make default target
FAST_HEADERS := $(wildcard Fast/**/*.h)
FAST_TEST_SOURCES := $(filter-out Fast/src/main.cpp, $(wildcard Fast/src/*.cpp Fast/tests/*.cpp))
FAST_TEST_OBJECTS := ${FAST_TEST_SOURCES:.cpp=.o}
CPPFLAGS+= $(INCLUDES)
CPPFLAGS+= -D BOOST_TEST_DYN_LINK
CXXFLAGS+= -std=c++11 $(CPPFLAGS)
LDFLAGS+= -lboost_unit_test_framework
Fast/tests/test_%.o: CPPFLAGS+=-DBOOST_TEST_NO_MAIN
Fast/tests/%.o: Fast/tests/%.cpp | $(FAST_HEADERS)
Fast/src/%.o: Fast/src/%.cpp | $(FAST_HEADERS)
%.o: %.cpp
g++ $(CXXFLAGS) -o $@ -c $<
fast_test: $(FAST_TEST_OBJECTS)
g++ $(CXXFLAGS) $^ $(LDFLAGS) -o $@
test: fast_test
./$<
.PHONY: test
使用make -Bsn 进行测试显示了标志如何组合:
g++ -std=c++11 -D BOOST_TEST_DYN_LINK -o Fast/src/size.o -c Fast/src/size.cpp
g++ -std=c++11 -D BOOST_TEST_DYN_LINK -o Fast/src/repeats.o -c Fast/src/repeats.cpp
g++ -std=c++11 -D BOOST_TEST_DYN_LINK -DBOOST_TEST_NO_MAIN -o Fast/tests/test_size.o -c Fast/tests/test_size.cpp
g++ -std=c++11 -D BOOST_TEST_DYN_LINK -DBOOST_TEST_NO_MAIN -o Fast/tests/test_repeats.o -c Fast/tests/test_repeats.cpp
g++ -std=c++11 -D BOOST_TEST_DYN_LINK -o Fast/tests/module.o -c Fast/tests/module.cpp
g++ -std=c++11 -D BOOST_TEST_DYN_LINK Fast/src/size.o Fast/src/repeats.o Fast/tests/test_size.o Fast/tests/test_repeats.o Fast/tests/module.o
-lboost_unit_test_framework -o fast_test
./fast_test
例如的输出./fast_test -l all:
Running 2 test cases...
Entering test module "Fast_Tests"
Fast/tests/test_size.cpp(3): Entering test case "test_size"
Fast/tests/test_size.cpp(8): info: check sz.n == n && sz.m == m has passed
Fast/tests/test_size.cpp(3): Leaving test case "test_size"; testing time: 136us
Fast/tests/test_repeats.cpp(3): Entering test case "test_repeats"
Fast/tests/test_repeats.cpp(7): info: check r.rep == n has passed
Fast/tests/test_repeats.cpp(3): Leaving test case "test_repeats"; testing time: 125us
Leaving test module "Fast_Tests"; testing time: 311us
*** No errors detected
松散的结局
我只保留了 Size/Repeats 标头的“测试驱动”实现。如果您为真实代码更改依赖对象,则需要链接依赖对象。
对于我没有解释的 GNU Make 功能,请参阅 https://www.gnu.org/software/make/manual/
代码转储:
-
文件Makefile
test: # make default target
FAST_HEADERS := $(wildcard Fast/**/*.h)
FAST_TEST_SOURCES := $(filter-out Fast/src/main.cpp, $(wildcard Fast/src/*.cpp Fast/tests/*.cpp))
FAST_TEST_OBJECTS := ${FAST_TEST_SOURCES:.cpp=.o}
CPPFLAGS+= $(INCLUDES)
CPPFLAGS+= -D BOOST_TEST_DYN_LINK
CXXFLAGS+= -std=c++11 $(CPPFLAGS)
LDFLAGS+= -lboost_unit_test_framework
Fast/tests/test_%.o: CPPFLAGS+=-DBOOST_TEST_NO_MAIN
Fast/tests/%.o: Fast/tests/%.cpp | $(FAST_HEADERS)
Fast/src/%.o: Fast/src/%.cpp | $(FAST_HEADERS)
%.o: %.cpp
g++ $(CXXFLAGS) -o $@ -c $<
fast_test: $(FAST_TEST_OBJECTS)
g++ $(CXXFLAGS) $^ $(LDFLAGS) -o $@
test: fast_test
./$<
.PHONY: test
-
文件Fast/include/repeats.h
#pragma once
struct Repeats {
explicit Repeats(int n) : rep(n){}
int const rep;
};
-
文件Fast/include/size.h
#pragma once
struct Size {
explicit Size(int n, int m)
: n(n)
, m(m)
{
}
int const n, m;
};
-
文件Fast/include/test_config.h
#include <boost/test/unit_test.hpp>
#include "../include/size.h"
#include "../include/repeats.h"
-
文件Fast/src/main.cpp
-
文件Fast/src/repeats.cpp
-
文件Fast/src/size.cpp
-
文件Fast/tests/module.cpp
#define BOOST_TEST_MODULE Fast_Tests
#include <boost/test/included/unit_test.hpp>
-
文件Fast/tests/test_repeats.cpp
#include "../include/test_config.h"
BOOST_AUTO_TEST_CASE(test_repeats)
{
int n = 30;
Repeats r = Repeats(n);
BOOST_REQUIRE(r.rep == n);
}
-
文件Fast/tests/test_size.cpp
#include "../include/test_config.h"
BOOST_AUTO_TEST_CASE(test_size)
{
int n = 20;
int m = 30;
Size sz = Size(n, m);
BOOST_REQUIRE(sz.n == n && sz.m == m);
}