장난감 언어용 사용자 정의 컴파일러는 Cranelift를 사용하여 파일에 쓸 수 있는 개체 코드를 생성합니다 main.o
. 이 개체 파일을 실행 가능하게 만들려면 gcc -o main main.o
.
그러나 임시 객체 파일을 디스크에 쓰는 것을 피하기 위해 코드를 GCC로 직접 파이프하고 싶기 때문에 컴파일러가 객체 코드를 표준 출력에 쓰도록 했습니다. 옵션에 대상 파일 값이 없는 것으로 나타나므로 파일 이름 으로 사용이 -
작동하지 않습니다 .-x
일종의 쉘 리디렉션을 사용하는 것도 작동하지 않습니다: error .gcc -o main <(compiler)
with/usr/bin/ld: /proc/self/fd/11: file not recognized: Illegal seek
gcc -xc <(echo "int main(){}") -o main
-pipe
GCC를 사용하여 파이프로 연결된 개체 코드를 연결할 수 있는 방법이 있나요?
답변1
ld
검색 가능한 파일이 필요하므로 파이프를 사용할 수 없습니다. Korn <(...)
쉘 프로세스는 파이프로 확장된 경로를 대체합니다.
일반 검색 가능한 파일( 배후에서 생성됨) =(...)
에 대한 경로를 얻으려면 zsh 또는 Fish가 필요합니다 .(...|psub -f)
$TMPPREFIX
$TMPDIR
gcc -o main =(compiler) # zsh
gcc -o main (compiler|psub -f) # fish
ld
필요한 파일의 경로 .o
가 로 끝나는 경우 zsh
설정합니다 TMPSUFFIX=.o
.
다른 셸에서는 임시 파일을 수동으로 생성할 수 있으며, gcc
이를 호출하거나 compiler
삭제한 후 출력을 해당 파일로 리디렉션할 수도 있습니다. Korn/POSIX와 유사한 쉘에서:
file=$(mktemp) && {
rm -f -- "$file" &&
compiler >&3 3>&- 4<&- &&
gcc -o main /dev/fd/4 3>&-
} 3> "$file" 4<> "$file"
자체 처리를 위해 자체적으로 많은 임시 파일을 생성 하므로 gcc
여기서 추가 임시 파일 생성을 피하려고 하는 것은 의미가 없습니다.
답변2
당신은 할 수 없습니다관로컴파일러의 개체 파일입니다. 오류에서 알 수 있듯이 gcc가 이를 조사하려고 하기 때문에 작동하지 않으며 이는 파이프에 대해 지원되는 작업이 아닙니다. (gcc가 특정 어휘/파싱으로 작성되어 입력을 순차적으로 소비하는 것처럼 보이기 때문에 소스 코드에서만 작동합니다.)
그러니 익명의 임시 파일이 있어야 합니다!
gcc -o main =(yourcompiler)
문제를 해결할 것입니다:
<(...) 대신 =(...)을 사용하면 인수로 전달된 파일은 목록 프로세스의 출력이 포함된 임시 파일의 이름이 됩니다. 이것은 입력 파일에 대해 lseek를 수행하려는 프로그램의 < 형식 대신 사용할 수 있습니다(lseek(2) 참조).
그러나 이것은 더 일반적인 bash가 아닌 zsh의 기능일 뿐이므로 그것을 사용하고 싶은지, 아니면 그냥 이식 가능한 개체 파일을 작성하고 링크하는 것인지 모르겠습니다. 메이크파일이나 닌자 스크립트를 사용하는 사람처럼, 또는 발전기가 할 것입니다.
또한 컴파일러가 중간 코드를 입력으로 사용하는 경우 실제로 이를 llvm 백엔드로 변경하고 싶을 수도 있습니다. 이렇게 하면 플러그인으로 clang에 로드하고 소스 코드를 개체 파일로 직접 컴파일하거나 결합된 링크를 수행하고 즉시 컴파일을 실행할 수도 있습니다.