Automatically detect C99 flags for supported compilers.
[platform/upstream/iotivity.git] / build_common / iotivityconfig / compiler / configuration.py
1 # ------------------------------------------------------------------------
2 # Copyright 2015 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #      http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 # ------------------------------------------------------------------------
16
17 class Configuration:
18     """Compiler-specific configuration abstract base class"""
19
20     def __init__(self, context):
21         """
22         Initialize the Configuration object
23
24         Arguments:
25         context -- the scons configure context
26         """
27
28         if type(self) is Configuration:
29             raise TypeError('abstract class cannot be instantiated')
30
31         self._context = context      # scons configure context
32         self._env     = context.env  # scons environment
33
34     def check_c99_flags(self):
35         """
36         Check if command line flag is required to enable C99
37         support.
38
39         Returns 1 if no flag is required, 0 if no flag was
40         found, and the actual flag if one was found.
41
42         CFLAGS will be updated with appropriate C99 flag,
43         accordingly.
44         """
45
46         return self._check_flags(self._c99_flags(),
47                                  self._c99_test_program(),
48                                  '.c',
49                                  'CFLAGS')
50
51     def check_cxx11_flags(self):
52         """
53         Check if command line flag is required to enable C++11
54         support.
55
56         Returns 1 if no flag is required, 0 if no flag was
57         found, and the actual flag if one was found.
58
59         CXXFLAGS will be updated with appropriate C++11 flag,
60         accordingly.
61         """
62
63         return self._check_flags(self._cxx11_flags(),
64                                  self._cxx11_test_program(),
65                                  '.cpp',
66                                  'CXXFLAGS')
67
68     # --------------------------------------------------------------
69     # Check if flag is required to build the given test program.
70     #
71     # Arguments:
72     # test_flags     -- list of flags that may be needed to build
73     #                   test_program
74     # test_program   -- program used used to determine if one of the
75     #                   given flags is required to for a successful
76     #                   build
77     # test_extension -- file extension associated with the test
78     #                   program, e.g. '.cpp' for C++ and '.c' for C
79     # flags_key      -- key used to retrieve compiler flags that may
80     #                   be updated by this check from the SCons
81     #                   environment
82     # --------------------------------------------------------------
83     def _check_flags(self,
84                      test_flags,
85                      test_program,
86                      test_extension,
87                      flags_key):
88         # Check if no additional flags are required.
89         ret = self._context.TryCompile(test_program,
90                                        test_extension)
91
92         if ret is 0:
93             # Try flags known to enable compiler features needed by
94             # the test program.
95
96             last_flags = self._env[flags_key]
97             for flag in test_flags:
98                 self._env.Append(**{flags_key : flag})
99                 ret = self._context.TryCompile(test_program,
100                                                test_extension)
101
102                 if ret:
103                     # Found a flag!
104                     return flag
105                 else:
106                     # Restore original compiler flags for next flag
107                     # test.
108                     self._env.Replace(**{flags_key : last_flags})
109
110         return ret
111
112     # ------------------------------------------------------------
113     # Return test program to be used when checking for basic C99
114     # support.
115     #
116     # Subclasses should implement this template method or use the
117     # default test program found in the DefaultConfiguration class
118     # through composition.
119     # ------------------------------------------------------------
120     def _c99_test_program(self):
121         raise NotImplementedError('unimplemented method')
122
123     # --------------------------------------------------------------
124     # Get list of flags that could potentially enable C99 support.
125     #
126     # Subclasses should implement this template method if flags are
127     # needed to enable C99 support.
128     # --------------------------------------------------------------
129     def _c99_flags(self):
130         raise NotImplementedError('unimplemented method')
131
132     # ------------------------------------------------------------
133     # Return test program to be used when checking for basic C++11
134     # support.
135     #
136     # Subclasses should implement this template method or use the
137     # default test program found in the DefaultConfiguration class
138     # through composition.
139     # ------------------------------------------------------------
140     def _cxx11_test_program(self):
141         raise NotImplementedError('unimplemented method')
142
143     # --------------------------------------------------------------
144     # Get list of flags that could potentially enable C++11 support.
145     #
146     # Subclasses should implement this template method if flags are
147     # needed to enable C++11 support.
148     # --------------------------------------------------------------
149     def _cxx11_flags(self):
150         raise NotImplementedError('unimplemented method')