提问人:TOOL 提问时间:8/30/2023 最后编辑:UpAndAdamTOOL 更新时间:9/4/2023 访问量:36
在 nushell 编译脚本中链接时,Clang 找不到 .o 文件
Clang can't find .o files when linking in nushell compilation script
问:
我目前正在尝试在 Nushell 中为 c++ 项目编写构建脚本。
这是一个相当简单的设置,首先构建一个库,然后构建一个 exe,并在另一个脚本中构建并链接该库。在构建库时,我的问题更加明显,所以我只展示这一点。
该库的构建脚本主要是关于定义标志和调用其他文件中定义的构建命令:
# Build script for stowy physics engine
source ../common.nu
def main [buildType: string = 'debug'] {
let isRelease = $buildType == 'release'
# Setup flags
let compilerFlags = [ '-std=c++20' (if $isRelease { '-O3' } else { '-g3' })]
const includeFlags = ['-Isrc']
const linkerFlags = ['-shared']
let defines = ['-DSTWEXPORT' (if $isRelease { '-DNDEBUG'} else { '-DDEBUG' })]
build stowy_physics_engine 'src/' '../bin/' $compilerFlags $includeFlags $linkerFlags $defines $buildType library
}
这就是 common.nu 的样子:
# Builds the assembly according to the parameters
def build [
assemblyName: string,
sourceDirectory: path,
binaryDirectory: path,
compilerFlags: list<string>,
includeFlags: list<string>,
linkerFlags: list<string>,
defines: list<string>,
buildType: string = 'debug', # The optimisation level of the build. Can be 'release' or 'debug'.
targetType: string = 'executable', # The type of target. Can be 'executable' or 'library'.
] {
let isRelease = $buildType == 'release'
let assemblyExtension = if $targetType == 'executable' {
if ($env.OS | str contains 'Windows') { '.exe' } else { '' }
} else if $targetType == 'library' {
if ($env.OS | str contains 'Windows') { '.dll' } else { '.so' }
} else {
return 'Invalid targetType'
}
let assemblyOutputFile = $'($binaryDirectory)/($assemblyName)($assemblyExtension)'
let cppFiles = glob **/*.cpp
let relativeCppFiles = ($cppFiles | path relative-to $sourceDirectory | path parse)
# Build every .cpp to .o and get a list of every .o
let objectFiles = $relativeCppFiles | each {|relativeCppFile| (
# Convert from path object to string
let inputFile = ($relativeCppFile | path join);
let outputFile = ($relativeCppFile | upsert extension 'o' | path join);
# Recreate the folder structure of .cpp files for the .o in the binary directory
let inputDirectory = ($relativeCppFile | get parent);
mkdir ($'($binaryDirectory)/($inputDirectory)');
# concatenate the .o file with the bin directory
let outputFileWithDir = $'($binaryDirectory)/($outputFile)'; # ex: ../bin/math/Vector2.o
let sourceFileWithDir = $'($sourceDirectory)/($inputFile)'; # ex: src/math/Vector2.cpp
clang++ -c -o $outputFileWithDir $sourceFileWithDir $defines $includeFlags $compilerFlags;
$outputFileWithDir
)}
let startTime = date now
clang++ -o $assemblyOutputFile $objectFiles $linkerFlags $includeFlags $defines $compilerFlags
print $'Built and linked ($assemblyName) successfully.'
}
正如你所看到的,它通过递归搜索找到每个文件,并通过调用clang来构建每个文件(我的目标是使用ccache缓存这个构建步骤)。.cpp
然后,在循环之后,我将每个文件交给 clang 以链接(或在 linux 上,但我还没有在那里测试过)。.o
.dll
.so
我的问题是,当我在启动此命令之前清空 bin 目录时,似乎在编译真正完成之前调用了 link 命令,并且找不到任何 ..o
Building stowy_physics_engine in debug...
Building C:\dev\cpp\build_system_tests\bin/collision\BroadPhaseGrid.o...
...
Building C:\dev\cpp\build_system_tests\bin/math\Vector2.o...
Built objects in 266ms 309µs 700ns
Linking...
clang++: error: no such file or directory: 'C:\dev\cpp\build_system_tests\bin/collision\BroadPhaseGrid.o'
...
clang++: error: no such file or directory: 'C:\dev\cpp\build_system_tests\bin/math\Vector2.o'
clang++: error: no input files
知道是什么原因导致的吗?
答:
1赞
TOOL
9/4/2023
#1
我能够通过调用并打印输出来解决这个问题:clang
run-external
print --no-newline (run-external --redirect-combine clang++ '-c' '-o' $outputFileWithDir $sourceFileWithDir $defines $includeFlags $compilerFlags);
评论