摇动构建捕获目录
Shake build capturing directories
我最近将我的作品基于 make 的构建系统转换为 shake。我现在正在尝试使 shake 对目录结构中的更改更加健壮,这样我就不必重新生成构建系统。
我使用的每个项目都是基于 C 的,并且具有以下目录结构
- 来源
- 源文件夹 1
- 源文件夹 2
- 公司
- 包括文件夹 1
- 包括文件夹 2
我能够捕获所有源文件,但我无法开始工作的是捕获包含文件夹。我试图将根 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 中的技术。
我最近将我的作品基于 make 的构建系统转换为 shake。我现在正在尝试使 shake 对目录结构中的更改更加健壮,这样我就不必重新生成构建系统。
我使用的每个项目都是基于 C 的,并且具有以下目录结构
- 来源
- 源文件夹 1
- 源文件夹 2
- 公司
- 包括文件夹 1
- 包括文件夹 2
我能够捕获所有源文件,但我无法开始工作的是捕获包含文件夹。我试图将根 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 中的技术。