我目前正在尝试为Project-Euler
提供可靠的文件夹结构。
我目前的想法是这个结构:
--project-euler/
--resources
--primes.h
--primes.c
--factors.h
--factors.c
--...
--001_name_of_procect_one.c
--001_name_of_project_one.o
--002_name_of_project_two.c
--002_name_of_project_two.o
--...
我对这个结构的问题是我将所有项目都放在一个文件夹中,我不知道如何为这种结构编写Makefiles
。
我可以为每个项目创建一个单独的目录,但是我必须编写类似#include "../resources/primes.h"
的东西,我不知道这种方法。
在这种情况下使用的典型项目结构是什么?如何为所有小项目编写Makefile
,同时仍将它们保存在同一目录中?
编辑:我顺便使用clang
。
答案 0 :(得分:1)
如果将实用程序文件保存在resources
子目录中,则可以在主目录中创建单独的解决方案文件,其中包含顶部所需的头文件,例如:
#include "resources/primes.h"
并在底部包含实际代码
#include "resources/primes.c"
这样,您甚至不需要Makefile
,因为默认规则允许您直接从相应的源文件中创建每个目标:
make 002_name_of_project_two
make甚至不会生成目标文件,只生成可执行文件。
我个人的名字更喜欢项目文件的较短名称,例如p42.c
Makefile
仅用于点击make
或IDE的构建按钮。一个衬垫就足够了:
all: p42
但您可能希望添加一些依赖项,以便在仅更改实用程序源时重新编译目标。添加以下行:(在第二行的开头有一个TAB)
%: %.c $(wildcard resources/*)
clang $(CFLAGS) $(LFLAGS) -o $@ $<
您仍然应该为CFLAGS
环境变量添加适当的选项,以利用编译器捕获愚蠢错误的能力:-Wall -Wextra -Werror
gcc
和-Weverything
clang
。
答案 1 :(得分:0)
如果您使用g++
声明包含目录:
g++ -I../resources #rest of command line
答案 2 :(得分:0)
关于图书馆的这一扩展评论将是一个与通常思维相反的非利士人的回答。在早些年,我花了无数个小时来维护我可爱的图书馆,但这个好主意有些问题。这样的库总是正在进行中,但是当项目签署并交付时,您不敢更改库以防止破坏以前的项目,因此必须将其冻结。然后,您将拥有几个版本的库。现在,假设旧项目需要mods,这需要改变库函数?您仍然无法使用当前版本,因为您必须重新进行以前的产品测试和保证。另一个反对意见是,我认为一些好的库函数在下一个项目中从来都不是我想要的。整件事变成了维护的噩梦,我放弃了它。我现在发现,在Project Euler问题中我可能需要一个阶乘函数。在一种情况下,简单的unsigned
函数将是好的。在另一种情况下,我需要uint64_t
在范围内。在另一个方面,这将是unsigned
或uint64_t
模数的常数。变化是无穷无尽的,当函数可能需要数百万次调用时,一般的单功能适合所有方法是不合适的。所以我只是使用复制/粘贴解决方案从其他问题中挑选我需要的位。