1*da0073e9SAndroid Build Coastguard Worker #ifndef C10_UTIL_FLAGS_H_ 2*da0073e9SAndroid Build Coastguard Worker #define C10_UTIL_FLAGS_H_ 3*da0073e9SAndroid Build Coastguard Worker 4*da0073e9SAndroid Build Coastguard Worker /* Commandline flags support for C10. 5*da0073e9SAndroid Build Coastguard Worker * 6*da0073e9SAndroid Build Coastguard Worker * This is a portable commandline flags tool for c10, so we can optionally 7*da0073e9SAndroid Build Coastguard Worker * choose to use gflags or a lightweight custom implementation if gflags is 8*da0073e9SAndroid Build Coastguard Worker * not possible on a certain platform. If you have gflags installed, set the 9*da0073e9SAndroid Build Coastguard Worker * macro C10_USE_GFLAGS will seamlessly route everything to gflags. 10*da0073e9SAndroid Build Coastguard Worker * 11*da0073e9SAndroid Build Coastguard Worker * To define a flag foo of type bool default to true, do the following in the 12*da0073e9SAndroid Build Coastguard Worker * *global* namespace: 13*da0073e9SAndroid Build Coastguard Worker * C10_DEFINE_bool(foo, true, "An example."); 14*da0073e9SAndroid Build Coastguard Worker * 15*da0073e9SAndroid Build Coastguard Worker * To use it in another .cc file, you can use C10_DECLARE_* as follows: 16*da0073e9SAndroid Build Coastguard Worker * C10_DECLARE_bool(foo); 17*da0073e9SAndroid Build Coastguard Worker * 18*da0073e9SAndroid Build Coastguard Worker * In both cases, you can then access the flag via FLAGS_foo. 19*da0073e9SAndroid Build Coastguard Worker * 20*da0073e9SAndroid Build Coastguard Worker * It is recommended that you build with gflags. To learn more about the flags 21*da0073e9SAndroid Build Coastguard Worker * usage, refer to the gflags page here: 22*da0073e9SAndroid Build Coastguard Worker * 23*da0073e9SAndroid Build Coastguard Worker * https://gflags.github.io/gflags/ 24*da0073e9SAndroid Build Coastguard Worker * 25*da0073e9SAndroid Build Coastguard Worker * Note about Python users / devs: gflags is initiated from a C++ function 26*da0073e9SAndroid Build Coastguard Worker * ParseCommandLineFlags, and is usually done in native binaries in the main 27*da0073e9SAndroid Build Coastguard Worker * function. As Python does not have a modifiable main function, it is usually 28*da0073e9SAndroid Build Coastguard Worker * difficult to change the flags after Python starts. Hence, it is recommended 29*da0073e9SAndroid Build Coastguard Worker * that one sets the default value of the flags to one that's acceptable in 30*da0073e9SAndroid Build Coastguard Worker * general - that will allow Python to run without wrong flags. 31*da0073e9SAndroid Build Coastguard Worker */ 32*da0073e9SAndroid Build Coastguard Worker 33*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Export.h> 34*da0073e9SAndroid Build Coastguard Worker #include <string> 35*da0073e9SAndroid Build Coastguard Worker 36*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Registry.h> 37*da0073e9SAndroid Build Coastguard Worker 38*da0073e9SAndroid Build Coastguard Worker namespace c10 { 39*da0073e9SAndroid Build Coastguard Worker /** 40*da0073e9SAndroid Build Coastguard Worker * Sets the usage message when a commandline tool is called with "--help". 41*da0073e9SAndroid Build Coastguard Worker */ 42*da0073e9SAndroid Build Coastguard Worker C10_API void SetUsageMessage(const std::string& str); 43*da0073e9SAndroid Build Coastguard Worker 44*da0073e9SAndroid Build Coastguard Worker /** 45*da0073e9SAndroid Build Coastguard Worker * Returns the usage message for the commandline tool set by SetUsageMessage. 46*da0073e9SAndroid Build Coastguard Worker */ 47*da0073e9SAndroid Build Coastguard Worker C10_API const char* UsageMessage(); 48*da0073e9SAndroid Build Coastguard Worker 49*da0073e9SAndroid Build Coastguard Worker /** 50*da0073e9SAndroid Build Coastguard Worker * Parses the commandline flags. 51*da0073e9SAndroid Build Coastguard Worker * 52*da0073e9SAndroid Build Coastguard Worker * This command parses all the commandline arguments passed in via pargc 53*da0073e9SAndroid Build Coastguard Worker * and argv. Once it is finished, partc and argv will contain the remaining 54*da0073e9SAndroid Build Coastguard Worker * commandline args that c10 does not deal with. Note that following 55*da0073e9SAndroid Build Coastguard Worker * convention, argv[0] contains the binary name and is not parsed. 56*da0073e9SAndroid Build Coastguard Worker */ 57*da0073e9SAndroid Build Coastguard Worker C10_API bool ParseCommandLineFlags(int* pargc, char*** pargv); 58*da0073e9SAndroid Build Coastguard Worker 59*da0073e9SAndroid Build Coastguard Worker /** 60*da0073e9SAndroid Build Coastguard Worker * Checks if the commandline flags has already been passed. 61*da0073e9SAndroid Build Coastguard Worker */ 62*da0073e9SAndroid Build Coastguard Worker C10_API bool CommandLineFlagsHasBeenParsed(); 63*da0073e9SAndroid Build Coastguard Worker 64*da0073e9SAndroid Build Coastguard Worker } // namespace c10 65*da0073e9SAndroid Build Coastguard Worker 66*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 67*da0073e9SAndroid Build Coastguard Worker // Below are gflags and non-gflags specific implementations. 68*da0073e9SAndroid Build Coastguard Worker // In general, they define the following macros for one to declare (use 69*da0073e9SAndroid Build Coastguard Worker // C10_DECLARE) or define (use C10_DEFINE) flags: 70*da0073e9SAndroid Build Coastguard Worker // C10_{DECLARE,DEFINE}_{int,int64,double,bool,string} 71*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 72*da0073e9SAndroid Build Coastguard Worker 73*da0073e9SAndroid Build Coastguard Worker #ifdef C10_USE_GFLAGS 74*da0073e9SAndroid Build Coastguard Worker 75*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 76*da0073e9SAndroid Build Coastguard Worker // Begin gflags section: most functions are basically rerouted to gflags. 77*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 78*da0073e9SAndroid Build Coastguard Worker #include <gflags/gflags.h> 79*da0073e9SAndroid Build Coastguard Worker 80*da0073e9SAndroid Build Coastguard Worker // C10 uses hidden visibility by default. However, in gflags, it only uses 81*da0073e9SAndroid Build Coastguard Worker // export on Windows platform (with dllexport) but not on linux/mac (with 82*da0073e9SAndroid Build Coastguard Worker // default visibility). As a result, to ensure that we are always exporting 83*da0073e9SAndroid Build Coastguard Worker // global variables, we will redefine the GFLAGS_DLL_DEFINE_FLAG macro if we 84*da0073e9SAndroid Build Coastguard Worker // are building C10 as a shared library. 85*da0073e9SAndroid Build Coastguard Worker // This has to be done after the inclusion of gflags, because some early 86*da0073e9SAndroid Build Coastguard Worker // versions of gflags.h (e.g. 2.0 on ubuntu 14.04) directly defines the 87*da0073e9SAndroid Build Coastguard Worker // macros, so we need to do definition after gflags is done. 88*da0073e9SAndroid Build Coastguard Worker #ifdef GFLAGS_DLL_DEFINE_FLAG 89*da0073e9SAndroid Build Coastguard Worker #undef GFLAGS_DLL_DEFINE_FLAG 90*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_DLL_DEFINE_FLAG 91*da0073e9SAndroid Build Coastguard Worker #ifdef GFLAGS_DLL_DECLARE_FLAG 92*da0073e9SAndroid Build Coastguard Worker #undef GFLAGS_DLL_DECLARE_FLAG 93*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_DLL_DECLARE_FLAG 94*da0073e9SAndroid Build Coastguard Worker #define GFLAGS_DLL_DEFINE_FLAG C10_EXPORT 95*da0073e9SAndroid Build Coastguard Worker #define GFLAGS_DLL_DECLARE_FLAG C10_IMPORT 96*da0073e9SAndroid Build Coastguard Worker 97*da0073e9SAndroid Build Coastguard Worker // gflags before 2.0 uses namespace google and after 2.1 uses namespace gflags. 98*da0073e9SAndroid Build Coastguard Worker // Using GFLAGS_GFLAGS_H_ to capture this change. 99*da0073e9SAndroid Build Coastguard Worker #ifndef GFLAGS_GFLAGS_H_ 100*da0073e9SAndroid Build Coastguard Worker namespace gflags = google; 101*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_GFLAGS_H_ 102*da0073e9SAndroid Build Coastguard Worker 103*da0073e9SAndroid Build Coastguard Worker // Motivation about the gflags wrapper: 104*da0073e9SAndroid Build Coastguard Worker // (1) We would need to make sure that the gflags version and the non-gflags 105*da0073e9SAndroid Build Coastguard Worker // version of C10 are going to expose the same flags abstraction. One should 106*da0073e9SAndroid Build Coastguard Worker // explicitly use FLAGS_flag_name to access the flags. 107*da0073e9SAndroid Build Coastguard Worker // (2) For flag names, it is recommended to start with c10_ to distinguish it 108*da0073e9SAndroid Build Coastguard Worker // from regular gflags flags. For example, do 109*da0073e9SAndroid Build Coastguard Worker // C10_DEFINE_BOOL(c10_my_flag, true, "An example"); 110*da0073e9SAndroid Build Coastguard Worker // to allow one to use FLAGS_c10_my_flag. 111*da0073e9SAndroid Build Coastguard Worker // (3) Gflags has a design issue that does not properly expose the global flags, 112*da0073e9SAndroid Build Coastguard Worker // if one builds the library with -fvisibility=hidden. The current gflags (as of 113*da0073e9SAndroid Build Coastguard Worker // Aug 2018) only deals with the Windows case using dllexport, and not the Linux 114*da0073e9SAndroid Build Coastguard Worker // counterparts. As a result, we will explicitly use C10_EXPORT to export the 115*da0073e9SAndroid Build Coastguard Worker // flags defined in C10. This is done via a global reference, so the flag 116*da0073e9SAndroid Build Coastguard Worker // itself is not duplicated - under the hood it is the same global gflags flag. 117*da0073e9SAndroid Build Coastguard Worker #define C10_GFLAGS_DEF_WRAPPER(type, real_type, name, default_value, help_str) \ 118*da0073e9SAndroid Build Coastguard Worker DEFINE_##type(name, default_value, help_str); 119*da0073e9SAndroid Build Coastguard Worker 120*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int(name, default_value, help_str) \ 121*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DEF_WRAPPER(int32, gflags::int32, name, default_value, help_str) 122*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int32(name, default_value, help_str) \ 123*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_int(name, default_value, help_str) 124*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int64(name, default_value, help_str) \ 125*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DEF_WRAPPER(int64, gflags::int64, name, default_value, help_str) 126*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_double(name, default_value, help_str) \ 127*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DEF_WRAPPER(double, double, name, default_value, help_str) 128*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_bool(name, default_value, help_str) \ 129*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DEF_WRAPPER(bool, bool, name, default_value, help_str) 130*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_string(name, default_value, help_str) \ 131*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DEF_WRAPPER(string, ::fLS::clstring, name, default_value, help_str) 132*da0073e9SAndroid Build Coastguard Worker 133*da0073e9SAndroid Build Coastguard Worker // DECLARE_typed_var should be used in header files and in the global namespace. 134*da0073e9SAndroid Build Coastguard Worker #define C10_GFLAGS_DECLARE_WRAPPER(type, real_type, name) DECLARE_##type(name); 135*da0073e9SAndroid Build Coastguard Worker 136*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int(name) \ 137*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DECLARE_WRAPPER(int32, gflags::int32, name) 138*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int32(name) C10_DECLARE_int(name) 139*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int64(name) \ 140*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DECLARE_WRAPPER(int64, gflags::int64, name) 141*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_double(name) \ 142*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DECLARE_WRAPPER(double, double, name) 143*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_bool(name) C10_GFLAGS_DECLARE_WRAPPER(bool, bool, name) 144*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_string(name) \ 145*da0073e9SAndroid Build Coastguard Worker C10_GFLAGS_DECLARE_WRAPPER(string, ::fLS::clstring, name) 146*da0073e9SAndroid Build Coastguard Worker 147*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 148*da0073e9SAndroid Build Coastguard Worker // End gflags section. 149*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 150*da0073e9SAndroid Build Coastguard Worker 151*da0073e9SAndroid Build Coastguard Worker #else // C10_USE_GFLAGS 152*da0073e9SAndroid Build Coastguard Worker 153*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 154*da0073e9SAndroid Build Coastguard Worker // Begin non-gflags section: providing equivalent functionality. 155*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 156*da0073e9SAndroid Build Coastguard Worker 157*da0073e9SAndroid Build Coastguard Worker namespace c10 { 158*da0073e9SAndroid Build Coastguard Worker 159*da0073e9SAndroid Build Coastguard Worker class C10_API C10FlagParser { 160*da0073e9SAndroid Build Coastguard Worker public: success()161*da0073e9SAndroid Build Coastguard Worker bool success() { 162*da0073e9SAndroid Build Coastguard Worker return success_; 163*da0073e9SAndroid Build Coastguard Worker } 164*da0073e9SAndroid Build Coastguard Worker 165*da0073e9SAndroid Build Coastguard Worker protected: 166*da0073e9SAndroid Build Coastguard Worker template <typename T> 167*da0073e9SAndroid Build Coastguard Worker bool Parse(const std::string& content, T* value); 168*da0073e9SAndroid Build Coastguard Worker bool success_{false}; 169*da0073e9SAndroid Build Coastguard Worker }; 170*da0073e9SAndroid Build Coastguard Worker 171*da0073e9SAndroid Build Coastguard Worker C10_DECLARE_REGISTRY(C10FlagsRegistry, C10FlagParser, const std::string&); 172*da0073e9SAndroid Build Coastguard Worker 173*da0073e9SAndroid Build Coastguard Worker } // namespace c10 174*da0073e9SAndroid Build Coastguard Worker 175*da0073e9SAndroid Build Coastguard Worker // The macros are defined outside the c10 namespace. In your code, you should 176*da0073e9SAndroid Build Coastguard Worker // write the C10_DEFINE_* and C10_DECLARE_* macros outside any namespace 177*da0073e9SAndroid Build Coastguard Worker // as well. 178*da0073e9SAndroid Build Coastguard Worker 179*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_typed_var(type, name, default_value, help_str) \ 180*da0073e9SAndroid Build Coastguard Worker C10_EXPORT type FLAGS_##name = default_value; \ 181*da0073e9SAndroid Build Coastguard Worker namespace c10 { \ 182*da0073e9SAndroid Build Coastguard Worker namespace { \ 183*da0073e9SAndroid Build Coastguard Worker class C10FlagParser_##name : public C10FlagParser { \ 184*da0073e9SAndroid Build Coastguard Worker public: \ 185*da0073e9SAndroid Build Coastguard Worker explicit C10FlagParser_##name(const std::string& content) { \ 186*da0073e9SAndroid Build Coastguard Worker success_ = C10FlagParser::Parse<type>(content, &FLAGS_##name); \ 187*da0073e9SAndroid Build Coastguard Worker } \ 188*da0073e9SAndroid Build Coastguard Worker }; \ 189*da0073e9SAndroid Build Coastguard Worker } \ 190*da0073e9SAndroid Build Coastguard Worker RegistererC10FlagsRegistry g_C10FlagsRegistry_##name( \ 191*da0073e9SAndroid Build Coastguard Worker #name, \ 192*da0073e9SAndroid Build Coastguard Worker C10FlagsRegistry(), \ 193*da0073e9SAndroid Build Coastguard Worker RegistererC10FlagsRegistry::DefaultCreator<C10FlagParser_##name>, \ 194*da0073e9SAndroid Build Coastguard Worker "(" #type ", default " #default_value ") " help_str); \ 195*da0073e9SAndroid Build Coastguard Worker } 196*da0073e9SAndroid Build Coastguard Worker 197*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int(name, default_value, help_str) \ 198*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_typed_var(int, name, default_value, help_str) 199*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int32(name, default_value, help_str) \ 200*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_int(name, default_value, help_str) 201*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int64(name, default_value, help_str) \ 202*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_typed_var(int64_t, name, default_value, help_str) 203*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_double(name, default_value, help_str) \ 204*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_typed_var(double, name, default_value, help_str) 205*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_bool(name, default_value, help_str) \ 206*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_typed_var(bool, name, default_value, help_str) 207*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_string(name, default_value, help_str) \ 208*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_typed_var(std::string, name, default_value, help_str) 209*da0073e9SAndroid Build Coastguard Worker 210*da0073e9SAndroid Build Coastguard Worker // DECLARE_typed_var should be used in header files and in the global namespace. 211*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_typed_var(type, name) C10_API extern type FLAGS_##name 212*da0073e9SAndroid Build Coastguard Worker 213*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int(name) C10_DECLARE_typed_var(int, name) 214*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int32(name) C10_DECLARE_int(name) 215*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int64(name) C10_DECLARE_typed_var(int64_t, name) 216*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_double(name) C10_DECLARE_typed_var(double, name) 217*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_bool(name) C10_DECLARE_typed_var(bool, name) 218*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_string(name) C10_DECLARE_typed_var(std::string, name) 219*da0073e9SAndroid Build Coastguard Worker 220*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 221*da0073e9SAndroid Build Coastguard Worker // End non-gflags section. 222*da0073e9SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 223*da0073e9SAndroid Build Coastguard Worker 224*da0073e9SAndroid Build Coastguard Worker #endif // C10_USE_GFLAGS 225*da0073e9SAndroid Build Coastguard Worker 226*da0073e9SAndroid Build Coastguard Worker #endif // C10_UTIL_FLAGS_H_ 227