摇动构建捕获目录

Shake build capturing directories

我最近将我的作品基于 make 的构建系统转换为 shake。我现在正在尝试使 shake 对目录结构中的更改更加健壮,这样我就不必重新生成构建系统。

我使用的每个项目都是基于 C 的,并且具有以下目录结构

我能够捕获所有源文件,但我无法开始工作的是捕获包含文件夹。我试图将根 inc 文件夹和子文件夹捕获到构建系统中的变量中。我一直在使用以下设置

includes = getDirectoryDir "inc"

这将给我包含的子文件夹但不是根文件夹公司。我认为我可以解决这个问题,但公司不会被跟踪。

我想要的是

includes = getDirectoryDirAndRoot "inc"

这将捕获每个子目录和根目录,并在构建系统中跟踪它们。

除此之外我也尝试使用

gcc -o out includes

但我需要在 include 中的每个元素前加上“-I”,我似乎无法理解。

我想在 shake 中如何做到这一点,在 make 中我可以通过使用 make shell 函数和几个字符串操作函数来完成所有这些。

看看 addOracle 和它的兄弟 addOracleCache。这应该允许您依赖文件本身之外的信息,例如要包含的目录。

But I would need to have every element in includes prepended with "-I" which I can't seem to figure out.

你可以在这里使用Haskell。如果您有一个目录列表 directories :: [FilePath],您可以使用

将它们转换为编译器标志
asIncludes :: [FilePath] -> [String]
asIncludes = fmap ("I" ++)

我觉得这个问题可以双向解读,而且两种解读都有用(你甚至可能都想要),所以我给出两个答案:

答案1:如果inc目录中的任何文件发生变化,您希望重新编译C文件。

"*.c" *> \out -> do headerFiles <- getDirectoryFiles "inc" "**/*.h" need headerFiles ...

此代码段获取 inc 目录(或其子目录)中所有头文件的列表,并引入对它们的依赖。如果任何头文件更改,此规则将重新运行。

答案 2: 你想获取要传递给 gcc.

的目录列表

"*.c" *> \out -> do includeDirs <- getDirectoryDirs "inc" cmd "gcc -c" [out] "-Iinc" (map ("-Iinc/" ++) includeDirs) ...

此代码段获取 inc 下的目录名称,然后使用 map 在它们前面加上 -Iinc/。它还直接传递 -Iinc 。如果 inc 下的目录列表更改,则此规则将重建。但是,如果这些目录中包含的头文件发生更改,则不会重建任何内容。您可以使用 gcc -MD 系列标志添加对使用的头文件的依赖性,如 Shake user manual 中所述,或使用答案 1 中的技术。