不必要的Ada依赖重编译(GCC 5.3.0)

问题描述:

在最近的GCC更新之后,我们注意到我们的一些预编译的通用函数在每次构建应用程序时都会被重新编译。它似乎与我们使用gnat.adc文件来存储编译指示相关。我有一个解决方法,但它并不漂亮,我希望有人能告诉我我是否做错了什么。不必要的Ada依赖重编译(GCC 5.3.0)

目录结构:

~/adatest 
    -dependency 
     dependency.ads 
     dependency.adb 
     gnat.adc 
    -dependent 
     dependent.adb 
     gnat.adc 

文件:

--dependency.ads 
package dependency is 
    procedure donothing; 
end dependency; 


--dependency.adb 
with ada.text_io; 
package body dependency is 
    procedure donothing is 
begin 
    ada.text_io.put_line("Doing nothing"); 
end; 
end dependency; 

--dependent.adb 
with dependency; 
procedure dependent is 
begin 
    dependency.donothing; 
end dependent; 

gnat.adc文件都是空的。

编译:

cd ~/adatest/dependency 
/usr/gnat/bin/gnatmake -m dependency.adb 
ls 
    dependency.adb dependency.ads dependency.ali dependency.o gnat.adc 
cd ../dependent/ 
/usr/gnat/bin/gnatmake -m dependent.adb -I../dependency 
ls 
    dependency.ali dependency.o dependent dependent.adb dependent.ali dependent.o gnat.adc 

所以编译依赖重新编译的依赖,即使依赖已经编译。使用gnatmake的详细标志,我可以看到为什么:

gcc -c -I../dependency dependent.adb 
    "~/adatest/dependency/dependency.ali" being checked ... 
    -> "gnat.adc" time stamp mismatch 

看来,存储在dependency.ali(这是依赖目录的gnat.adc的时间戳)的gnat.adc时间戳被针对的时间戳比较依赖目录的gnat.adc,导致不匹配和重新编译。删除gnat.adc文件会停止重新编译,但我们需要在我们的实际程序中使用这些编译指示。它看起来像我们以前的GCC版本(4.8.2)没有存储gnat.adc时间戳,所以从未发生过这个问题。

无论如何,我们目前的解决方法是将所有gnat.adc文件重命名为gnat.adc.tmp,然后使用gnatmake的配置文件参数(-gnatec = gnat.adc.tmp)指定文件。 .tmp扩展名会阻止文件在.ali中编入索引,从而解决问题。尽管如此,我并不喜欢这种混合物,并希望有一个更清洁的解决方案。

+0

你必须小心哪些编译指示是分区范围的,哪些不是。 –

这似乎是指定库目录的问题。在目录dependent,和编译后,在目录dependency

$ gnatmake -m -A../dependency dependent.adb 

即,使用-Adir(如当没有任何运行中的gnatmake输出描述)。然后,

$ ls 
dependent dependent.adb dependent.ali dependent.o gnat.adc