merge of '3585034766082dee6be36ed64f840eaeee7eb14e'
[openembedded.git] / classes / icecc.bbclass
1 # IceCream distributed compiling support
2 #
3 # We need to create a tar.bz2 of our toolchain and set
4 # ICECC_VERSION, ICECC_CXX and ICEC_CC
5 #
6
7 def icc_determine_gcc_version(gcc):
8     """
9     Hack to determine the version of GCC
10
11     'i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5363)'
12     """
13     return os.popen("%s --version" % gcc ).readline().split()[2]
14
15 def create_env(bb,d):
16     """
17     Create a tar.bz of the current toolchain
18     """
19
20     # Constin native-native compilation no environment needed if
21     # host prefix is empty (let us duplicate the query for ease)
22     prefix = bb.data.expand('${HOST_PREFIX}', d)
23     if len(prefix) == 0:
24         return ""
25
26     import tarfile
27     import socket
28     import time
29     import os
30     ice_dir = bb.data.expand('${CROSS_DIR}', d)
31     prefix  = bb.data.expand('${HOST_PREFIX}' , d)
32     distro  = bb.data.expand('${DISTRO}', d)
33     target_sys = bb.data.expand('${TARGET_SYS}',  d)
34     float   = bb.data.getVar('${TARGET_FPU}', d) or "hard"
35     name    = socket.gethostname()
36
37     # Stupid check to determine if we have built a libc and a cross
38     # compiler.
39     try:
40         os.stat(os.path.join(ice_dir, target_sys, 'lib', 'ld-linux.so.2'))
41         os.stat(os.path.join(ice_dir, target_sys, 'bin', 'g++'))
42     except:
43         return ""
44
45     VERSION = icc_determine_gcc_version( os.path.join(ice_dir,target_sys,"bin","g++") )
46     cross_name = prefix + distro + target_sys + float +VERSION+ name
47     tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.bz2')
48
49     try:
50         os.stat(tar_file)
51         return tar_file
52     except:
53         try:
54             os.makedirs(os.path.join(ice_dir,'ice'))
55         except:
56             pass
57
58     # FIXME find out the version of the compiler
59     # Consider using -print-prog-name={cc1,cc1plus}
60     # and            -print-file-name=specs
61
62     # We will use the GCC to tell us which tools to use
63     #  What we need is:
64     #        -gcc
65     #        -g++
66     #        -as
67     #        -cc1
68     #        -cc1plus
69     #  and we add them to /usr/bin
70
71     tar = tarfile.open(tar_file, 'w:bz2')
72
73     # Now add the required files
74     tar.add(os.path.join(ice_dir,target_sys,'bin','gcc'),
75             os.path.join("usr","bin","gcc") )
76     tar.add(os.path.join(ice_dir,target_sys,'bin','g++'),
77             os.path.join("usr","bin","g++") )
78     tar.add(os.path.join(ice_dir,target_sys,'bin','as'),
79             os.path.join("usr","bin","as") )
80
81     # Now let us find cc1 and cc1plus
82     cc1 = os.popen("%s -print-prog-name=cc1" % data.getVar('CC', d, True)).read()[:-1]
83     cc1plus = os.popen("%s -print-prog-name=cc1plus" % data.getVar('CC', d, True)).read()[:-1]
84     spec = os.popen("%s -print-file-name=specs" % data.getVar('CC', d, True)).read()[:-1]
85
86     # CC1 and CC1PLUS should be there...
87     tar.add(cc1, os.path.join('usr', 'bin', 'cc1'))
88     tar.add(cc1plus, os.path.join('usr', 'bin', 'cc1plus'))
89
90     # spec - if it exists
91     if os.path.exists(spec):
92         tar.add(spec)
93
94     tar.close()
95     return tar_file
96
97
98 def create_path(compilers, type, bb, d):
99     """
100     Create Symlinks for the icecc in the staging directory
101     """
102     import os
103
104     staging = os.path.join(bb.data.expand('${STAGING_DIR}', d), "ice", type)
105     icecc   = bb.data.getVar('ICECC_PATH', d)
106
107     # Create the dir if necessary
108     try:
109         os.stat(staging)
110     except:
111         os.makedirs(staging)
112
113
114     for compiler in compilers:
115         gcc_path = os.path.join(staging, compiler)
116         try:
117             os.stat(gcc_path)
118         except:
119             os.symlink(icecc, gcc_path)
120
121     return staging + ":"
122
123
124 def use_icc_version(bb,d):
125     # Constin native native
126     prefix = bb.data.expand('${HOST_PREFIX}', d)
127     if len(prefix) == 0:
128         return "no"
129
130
131     blacklist = [ "cross", "native" ]
132
133     for black in blacklist:
134         if bb.data.inherits_class(black, d):
135             return "no"
136
137     return "yes"
138
139 def icc_path(bb,d,compile):
140     native = bb.data.expand('${PN}', d)
141     blacklist = [ "ulibc", "glibc", "ncurses" ]
142     for black in blacklist:
143         if black in native:
144             return ""
145
146     blacklist = [ "cross", "native" ]
147     for black in blacklist:
148         if bb.data.inherits_class(black, d):
149             compile = False
150
151     prefix = bb.data.expand('${HOST_PREFIX}', d)
152     if compile and len(prefix) != 0:
153         return create_path( [prefix+"gcc", prefix+"g++"], "cross", bb, d )
154     elif not compile or len(prefix) == 0:
155         return create_path( ["gcc", "g++"], "native", bb, d)
156
157
158 def icc_version(bb,d):
159     return create_env(bb,d)
160
161
162 #
163 # set the IceCream  environment variables
164 do_configure_prepend() {
165     export PATH=${@icc_path(bb,d,False)}$PATH
166     export ICECC_CC="gcc"
167     export ICECC_CXX="g++"
168 }
169
170 do_compile_prepend() {
171     export PATH=${@icc_path(bb,d,True)}$PATH
172     export ICECC_CC="${HOST_PREFIX}gcc"
173     export ICECC_CXX="${HOST_PREFIX}g++"
174
175     if [ "${@use_icc_version(bb,d)}" = "yes" ]; then
176         export ICECC_VERSION="${@icc_version(bb,d)}"
177     fi
178 }