我目前正在编写一本c ++教科书;我希望在本书中有单独的练习文件夹和根目录中的单个makefile,以便在根目录中我可以输入
make directoryName
它将编译该目录中的所有源,并将二进制文件输出到根目录中。以下是我到目前为止的情况:
FLAGS= -Wall -Wextra -Wfloat-equal
OUT=helloworld.out
%: $(wildcard $@/*.cpp)
g++ $@/$(wildcard *.cpp) -o $(OUT) $(FLAGS)
但是当我尝试运行它时,我得到的只是
pc-157-231:Section2$ make helloWorld
make: `helloWorld' is up to date.
任何帮助表示赞赏
修改 注意;问题不在于我没有改变目标文件;我做了......
答案 0 :(得分:1)
您的问题是,$@
之类的自动GNU变量只在规则的正文中有一个值。来自GNU make documentation。
[自动变量]无法在规则的先决条件列表中直接访问。一个常见错误是尝试在先决条件列表中使用
$@
;这不行。 (source)
另外,您不需要规则中的$(wildcard ...)
函数(在正文和先决条件列表中),尽管这也不是错误:
通配符扩展在规则中自动发生。 (source)
答案 1 :(得分:0)
我已经写了一个make的替代品,这使得这很容易,但它是非常实验性/非正式支持等。您可以从https://github.com/dascandy/bob下载。
你可能会把它写成:
FLAGS= -Wall -Wextra -Wfloat-equal
# Take all cpp files in a folder & compile it to executable with that folder name as name.
(.*)/.*\.cpp => \1.out
g++ -o $@ $^ $(FLAGS)
或者使用中间对象(对于大型项目更好,但对于小型练习可能没用)
FLAGS= -Wall -Wextra -Wfloat-equal
# Read as, compile any CPP file to a file with the same root but .o as extension
(.*)\.cpp => \1.o
g++ -c -o $@ $^ $(FLAGS)
# read as, take all objects in a subfolder together and compile into executable with folder name as name.
(.*)/.*\.o => \1.out
g++ -o $@ $^
该工具本身需要安装Boost.Filesystem。
如果您想拥有一个编译所有可执行文件的默认目标,请添加以下行:
.*.out => all
echo -n
(回声是因为它希望所有规则都有命令)