BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_ident.h
Go to the documentation of this file.
1/// @file bsls_ident.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_ident.h -*-C++-*-
8#ifndef INCLUDED_BSLS_IDENT
9#define INCLUDED_BSLS_IDENT
10
11/// @defgroup bsls_ident bsls_ident
12/// @brief Provide macros for inserting SCM Ids into source files.
13/// @addtogroup bsl
14/// @{
15/// @addtogroup bsls
16/// @{
17/// @addtogroup bsls_ident
18/// @{
19///
20/// <h1> Outline </h1>
21/// * <a href="#bsls_ident-purpose"> Purpose</a>
22/// * <a href="#bsls_ident-classes"> Classes </a>
23/// * <a href="#bsls_ident-macros"> Macros </a>
24/// * <a href="#bsls_ident-description"> Description </a>
25/// * <a href="#bsls_ident-macro-summary"> Macro Summary </a>
26/// * <a href="#bsls_ident-usage"> Usage </a>
27///
28/// # Purpose {#bsls_ident-purpose}
29/// Provide macros for inserting SCM Ids into source files.
30///
31/// # Classes {#bsls_ident-classes}
32///
33///
34/// # Macros {#bsls_ident-macros}
35///
36/// - BSLS_IDENT(identifier): inset `identifier` into `.comment` section
37/// - BSLS_IDENT_RCSID(tag, identifier): alternatively, use add `tag` as static
38/// - BSLS_IDENT_PRAGMA_ONCE: encapsulate `_Pragma("once")`
39///
40/// @see bsls_buildtarget
41///
42/// # Description {#bsls_ident-description}
43/// The purpose of this component is to provide macros for
44/// inserting SCM (Source Control Management) Ids into source files. SCM Ids
45/// are useful for identifying source revisions in binaries. Additional
46/// information about SCM Ids may be obtained from the following man pages:
47/// `man ident` `man strings` (`strings -a` produces more verbose output)
48/// `man mcs` (Solaris-only)
49///
50/// Note that these SCM Ids are only present if the `BSLS_IDENT_ON` macro is
51/// defined at compilation time. By default, this macro is *not* defined, and
52/// ident strings are *not* added to object files.
53///
54/// SCM systems may replace Ids with their expanded forms. Note that we will
55/// replace the key symbol `$` with `(DOLLAR)` to avoid any expansion within
56/// this header file's documentation.
57///
58/// SCM Ids usually take the form "(DOLLAR)Id: (DOLLAR)" which is expanded,
59/// automatically, by the source control system into an identifier which maps to
60/// specific source revision:
61/// @code
62/// '(DOLLAR)Id: bsls_ident.h 141104 2010-09-17 00:30:47Z mgiroux (DOLLAR)'
63/// @endcode
64/// This specifies that the file was checked in on 2010-09-17 at the specified
65/// time by user `mgiroux`, and can be retrieved from the SCM system using
66/// revision `141104`.
67///
68/// `BSLS_IDENT_PRAGMA_ONCE` can optionally be used in headers and encapsulates
69/// a non-standard pragma (_Pragma("once")) supported on a number of platforms
70/// and which indicates that a header should be included and parsed only once.
71/// Use of this macro can help reduce compile times by eliminating extraneous
72/// I/O when headers are included more than once in the same translation unit.
73/// Note that this macro should *not* be used for any header that cannot use
74/// include guards: this is unusual, but can happen for certain low-level
75/// headers.
76///
77/// ## Macro Summary {#bsls_ident-macro-summary}
78///
79///
80/// The following are the macros provided by this component.
81///
82/// * `BSLS_IDENT(identifier)`
83/// > This macro inserts the specified `identifier` into the object's
84/// > `.comment` section, if supported on the current platform.
85///
86/// * `BSLS_IDENT_RCSID(tag, identifier)`
87/// > This macro inserts the specified `identifier` into the object, using
88/// > `BSLS_IDENT`, if possible on the current platform. If `BSLS_IDENT` is
89/// > not available, the specified `tag` may be used to declare a static char
90/// > array containing the `tag`.
91///
92/// * `BSLS_IDENT_PRAGMA_ONCE`
93/// > This macro encapsulates the `_Pragma("once")` functionality if available
94/// > on the current platform. If available, this functions in the same way
95/// > as redundant include guards, avoiding re-opening already-included header
96/// > files.
97///
98/// ## Usage {#bsls_ident-usage}
99///
100///
101/// The following example shows how we first include `bsls_ident.h` and then
102/// use the `BSLS_IDENT` macro. For header (`.h`) files this macro should be
103/// placed directly after the include guards, e.g., `bsls_somefile.h`:
104/// @code
105/// // bsls_somefile.h -*-C++-*-
106/// #ifndef INCLUDED_BSLS_SOMEFILE
107/// #define INCLUDED_BSLS_SOMEFILE
108///
109/// #include <bsls_ident.h>
110/// BSLS_IDENT("(DOLLAR)Id: (DOLLAR)") // In real usage, replace '(DOLLAR)'
111/// // with `$`.
112///
113/// // ...
114///
115/// #endif // INCLUDED_BSLS_SOMEFILE
116/// @endcode
117/// For implementation (`.cpp`) files the `BSLS_IDENT` macro should be placed
118/// directly after the comment line for the file name and the language, and
119/// the include for the component header e.g., `bsls_somefile.cpp`:
120/// @code
121/// // bsls_somefile.cpp -*-C++-*-
122/// #include <bsls_somefile.h>
123///
124/// #include <bsls_ident.h>
125/// BSLS_IDENT("(DOLLAR)Id: (DOLLAR)") // In real usage, replace '(DOLLAR)'
126/// // with `$`.
127/// @endcode
128/// @}
129/** @} */
130/** @} */
131
132/** @addtogroup bsl
133 * @{
134 */
135/** @addtogroup bsls
136 * @{
137 */
138/** @addtogroup bsls_ident
139 * @{
140 */
141
142// ============================================================================
143// COMMAND LINE BUILD ENVIRONMENT
144// ============================================================================
145
146/// Enforce a consistent build environment for command line build flags.
147///
148/// \note Note that these configuration macros are defined in `bsls_buildtarget.h` while
149/// the basic consistency rules are enforced in this component as the most
150/// fundamental component header necessarily included before all other BDE
151/// headers.
152
153/// This macro contributes towards enforcing the principle that components
154/// include the header for components that they depend on. As component
155/// headers evolve, sometimes dependencies are removed. When that happens
156/// the `#include` for the dependency could be safely removed, but might
157/// break code above that was erroneously depending on that transitive
158/// `#include`. To avoid breaking code above, we retain the `#include`
159/// directive, but guard it in group that is disabled we the test
160/// `#ifdef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES`. To confirm that we have
161/// a clean build that does not rely on such known transitive `#includes`,
162/// recompile with the `BDE_FORCE_DONT_ALLOW_TRANSITIVE_INCLUDES` macro
163/// predefined.
164#undef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
165#ifdef BDE_FORCE_DONT_ALLOW_TRANSITIVE_INCLUDES
166 #define BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
167#endif
168
169/// This macro controls whether we allow features which we must continue to
170/// support for our clients but do not want to rely on in our own code base.
171/// Clients who want to continue using these features need take no special
172/// steps. In order to make sure an entire code base does not rely on these
173/// features, recompile with the `BDE_FORCE_OMIT_INTERNAL_DEPRECATED` macro
174/// predefined. Examples of such features are: including `<stdheader>` as
175/// opposed to `<bsl_stdheader.h>`, or using `DEBUG` instead of `e_DEBUG`.
176#undef BDE_OMIT_INTERNAL_DEPRECATED
177#ifdef BDE_FORCE_OMIT_INTERNAL_DEPRECATED
178 #define BDE_OMIT_INTERNAL_DEPRECATED
179 #if !defined(BDE_DONT_ALLOW_TRANSITIVE_INCLUDES)
180 #define BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
181 // When we don't want to rely on legacy features, we also want to make sure
182 // we are not picking up macros or type aliases via (direct or transitive)
183 // includes of headers that have migrated from 'bde' to 'bsl' libraries.
184 #endif
185#endif // BDE_OMIT_INTERNAL_DEPRECATED
186
187/// Ensure that either `BSLS_IDENT_ON` or `BSLS_IDENT_OFF` is defined according
188/// to the command line configuration. Enabling `BSLS_IDENT` by default causes
189/// significant bloat - see internal ticket D29644737.
190#if !defined(BSLS_IDENT_ON) && !defined(BSLS_IDENT_OFF)
191 #define BSLS_IDENT_OFF
192#elif defined(BSLS_IDENT_ON) && defined(BSLS_IDENT_OFF)
193 #error Command line cannot define both `BSLS_IDENT_ON` and `BSLS_IDENT_OFF`
194#endif
195
196// ============================================================================
197// COMPONENT-SPECIFIC IMPLEMENTATION MACROS
198// ============================================================================
199
200// multi-level indirection to force macro expansion before concatenation
201// (order of concatenation/macro expansion unspecified in ISO standard)
202#define BSLS_IDENT_JOIN2(x,y) x ## y
203#define BSLS_IDENT_JOIN(x,y) BSLS_IDENT_JOIN2(x,y)
204
205
206// ============================================================================
207// MACRO DEFINITIONS
208// ============================================================================
209
210/// `BSLS_IDENT()` - insert string into .comment binary segment (if supported)
211
212#if defined(__GNUC__)
213 #if !defined(_AIX)
214 // does not work with AIX `as`; might work with GNU `as` (gas) (not tested)
215 // gcc has no pragma equivalent for `#ident`
216 #define _BSLS_IDENT(str) __asm__(#str);
217 #define BSLS_IDENT(str) _BSLS_IDENT(.ident str)
218 #endif
219#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
220 #define _BSLS_IDENT(str) _Pragma(#str)
221 #define BSLS_IDENT(str) _BSLS_IDENT(ident str)
222#elif defined(__IBMC__) || defined(__IBMCPP__)
223 #define _BSLS_IDENT(str) _Pragma(#str)
224 #define BSLS_IDENT(str) _BSLS_IDENT(comment (user, str))
225#elif defined(_MSC_VER) // Microsoft Visual Studio Compiler
226 // Microsoft linker ignores `__pragma(comment (user, "str"))`
227 // http://msdn.microsoft.com/en-us/library/7f0aews7.aspx
228 #if 0 // disable `SYSUTIL_IDENT()` with Microsoft compiler
229 #define _BSLS_IDENT(str) __pragma(comment (user, #str))
230 #define BSLS_IDENT(str) _BSLS_IDENT(str)
231 #endif
232#elif defined(__HP_cc) || defined(__HP_aCC)
233 #define _BSLS_IDENT(str) _Pragma(#str)
234 #define BSLS_IDENT(str) _BSLS_IDENT(versionid str)
235#endif
236
237#ifndef BSLS_IDENT
238 #define BSLS_IDENT(str)
239#endif
240
241
242/// `BSLS_IDENT_RCSID()` - insert ident str (specific to platform/compiler)
243
244#define BSLS_IDENT_RCSID(tag,str) BSLS_IDENT(str)
245
246/// `BSLS_IDENT_PRAGMA_ONCE` - macro to avoid multiple inclusion
247
248#if defined(__GNUC__)
249 #define BSLS_IDENT_PRAGMA_ONCE _Pragma("once")
250#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
251 // Sun Studio does not support `#pragma once`. Instead, it natively detects
252 // if the entire non-comment portion of a file is wrapped by `#ifndef`, and
253 // if so, optimizes away reopens of the file if the `#ifndef` condition is
254 // `false`.
255 #define BSLS_IDENT_PRAGMA_ONCE
256#elif defined(__IBMC__) || defined(__IBMCPP__)
257 #define BSLS_IDENT_PRAGMA_ONCE _Pragma("once")
258#elif defined(_MSC_VER)
259 #define BSLS_IDENT_PRAGMA_ONCE __pragma(once)
260#elif defined(__HP_cc) || defined(__HP_aCC)
261 #define BSLS_IDENT_PRAGMA_ONCE _Pragma("once")
262#else
263 #define BSLS_IDENT_PRAGMA_ONCE
264#endif
265
266
267// ============================================================================
268// COMPLETE THE BUILD ENVIRONMENT
269// ============================================================================
270
271// Timestamp compilation with the expansion of the `BUILDID` macro, if provided
272// as a command-ine argument. Such timestamping occurs once per object file.
273// Use `BSLS_IDENT()` so the timestamp occurs in .comment section only if
274// supported. Timestamping occurs even if `BSLS_IDENT` functionality is
275// otherwise disabled by the `BSLS_IDENT_OFF` command line flag.
276// Example usage in a Makefile target:
277// $(CC) -c -DBUILDID="$(@F) `date +%Y%m%d_%H%M%S`" -o file.o file.
278#ifdef BUILDID
279 #define _BSLS_IDENT_BUILDID_IMP2(str) BSLS_IDENT(#str)
280 #define _BSLS_IDENT_BUILDID_IMP(str) _BSLS_IDENT_BUILDID_IMP2(str)
281 _BSLS_IDENT_BUILDID_IMP($cc: BUILDID $)
282 #undef _BSLS_IDENT_BUILDID_IMP
283 #undef _BSLS_IDENT_BUILDID_IMP2
284#endif
285
286// Enforce the empty defintion of the `BSLS_IDENT` and `BSLS_IDENT_RCSID`
287// macros when `BSLS_IDENT_OFF` is supplied on the command line.
288#ifdef BSLS_IDENT_OFF
289 #undef BSLS_IDENT
290 #undef BSLS_IDENT_RCSID
291 #define BSLS_IDENT(str)
292 #define BSLS_IDENT_RCSID(tag,str)
293#endif // !BSLS_IDENT_OFF
294
296
297// Clean up implementation detail macros defined for this component.
298#undef BSLS_IDENT_JOIN
299#undef BSLS_IDENT_JOIN2
300
301#endif // INCLUDED_BSLS_IDENT
302
303// ----------------------------------------------------------------------------
304// Copyright 2013 Bloomberg Finance L.P.
305//
306// Licensed under the Apache License, Version 2.0 (the "License");
307// you may not use this file except in compliance with the License.
308// You may obtain a copy of the License at
309//
310// http://www.apache.org/licenses/LICENSE-2.0
311//
312// Unless required by applicable law or agreed to in writing, software
313// distributed under the License is distributed on an "AS IS" BASIS,
314// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
315// See the License for the specific language governing permissions and
316// limitations under the License.
317// ----------------------------- END-OF-FILE ----------------------------------
318
319/** @} */
320/** @} */
321/** @} */
#define BSLS_IDENT_JOIN2(x, y)
Definition bsls_ident.h:202
#define BSLS_IDENT_RCSID(tag, str)
BSLS_IDENT_RCSID() - insert ident str (specific to platform/compiler)
Definition bsls_ident.h:244
#define BSLS_IDENT_PRAGMA_ONCE
BSLS_IDENT_PRAGMA_ONCE - macro to avoid multiple inclusion
Definition bsls_ident.h:263
#define BSLS_IDENT_OFF
Definition bsls_ident.h:191
#define BSLS_IDENT_JOIN(x, y)
Definition bsls_ident.h:203
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238