2017-04-08 23 views
0

在基於自動工具的版本中,我想用生成的C文件替換版本控制的C文件。生成的C文件和自動工具

這個假,Hello World示例作品排序的:

#!/bin/sh -ex 
cat > configure.ac <<EOF 
AC_INIT([hello], [0.01]) 
AC_PREREQ([2.68]) 
AC_CONFIG_SRCDIR([hello.c]) 
AC_CONFIG_AUX_DIR([build-aux]) 
AM_INIT_AUTOMAKE([1.11]) 
AC_CONFIG_FILES([Makefile]) 
AC_PROG_CC 
AC_OUTPUT 
EOF 

cat > autogen.sh <<EOF 
touch NEWS README AUTHORS ChangeLog COPYING 
autoreconf -i 
EOF 
chmod +x autogen.sh 

printf " 
bin_PROGRAMS = hello 
hello_SOURCES = hello.c 

hello.c: generate 
\t./generate 
" > Makefile.am 

cat > hello.c <<EOF 
#include <stdio.h> 
int main() 
{ 
    puts("hello world"); 
    return 0; 
} 
EOF 

cat > generate <<EOF0 
#!/bin/sh 
cat > hello.c <<EOF 
#include <stdio.h> 
int main() 
{ 
    puts("HELLO WORLD"); 
    return 0; 
} 
EOF 
EOF0 
chmod +x generate 


./autogen.sh 
./configure 
make -j$(nproc) 

,除了它阻止我做一個徹頭徹尾的樹建立如:

mkdir B 
cd B 
../configure 
make 

,我可以正常嗎在基於autotools的包中。 如何生成C文件,以便樹外構建繼續工作?

回答

2

重要的是要記住,make並不真正瞭解目錄;大多數情況下,一切都是一個字符串。這並不總是那麼明顯,但當你試圖編寫一個可以處理源代碼外部構建的構建系統時,它往往會讓你感到困難。

您提供了一個構建規則,其中hello.c取決於您的generate腳本,原則上這很好。 Make甚至會在源代碼內部正確處理依賴性處理,在源目錄中查找generate腳本。但構建規則明確中的配方運行./generate,當您執行源外構建時,該配置不存在。此外,您在依賴關係和構建規則之間斷開連接:'generate'與'./generate'不同。

主要有兩種備選方案:

  1. 在你的構建規則,只對自動make變量(例如$<)依靠指依賴。當make執行源外構建時,它會使用可行路徑初始化自動變量。

  2. 通過顯式路徑引用源目錄中的文件。

要單獨使用選項(1),您將需要解決的如何,當它是(大概)運行generate腳本問題不在路徑。你可以通過shell來間接運行它。你想在這種情況下,生成規則將

hello.c: generate 
    $(SHELL) $< 

這應該爲無論是在源或外的源建設工作。應該由Autotools提供$(SHELL) make變量。

要使用選項(2),在另一方面,你可能會依靠$(srcdir)$(top_srcdir)

# Note that the dependency name will always contain a '/': 
hello.c: $(srcdir)/generate 
    $< 

(您也可以命名生成腳本,與路徑,在構建配方,但通常最好避免重複自己)。自動工具還提供$(srcdir)$(top_srcdir)變量。前者引用源代碼樹中與我們當前構建的構建樹目錄相對應的目錄;後者引用包含configure腳本的源代碼樹目錄。

在這兩者中,我認爲(1)更多的是源於外部構建的精神,但沒有太大的差別。