mirror of
https://github.com/gflags/gflags.git
synced 2025-04-19 19:53:45 +00:00
Compare commits
275 commits
Author | SHA1 | Date | |
---|---|---|---|
|
52e94563eb | ||
|
c1f63a168d | ||
|
70c01a642f | ||
|
b364def945 | ||
|
58cf1ef6d0 | ||
|
3c4399ba46 | ||
|
03a4842c9c | ||
|
82793e3f38 | ||
|
c196ce6baa | ||
|
3df39f3a03 | ||
|
a738fdf933 | ||
|
b7fd838331 | ||
|
986e8eed00 | ||
|
9ca7e9ee7a | ||
|
4ace06d024 | ||
|
827c769e5f | ||
|
5d5a6c5501 | ||
|
a386bd0f20 | ||
|
cb68d9eeb8 | ||
|
ae2fae5645 | ||
|
1c86423887 | ||
|
8843f88b69 | ||
|
4405871443 | ||
|
f7388c6655 | ||
|
84968c6bb2 | ||
|
1137acc9e0 | ||
|
ef8e134d48 | ||
|
addd749114 | ||
|
2e227c3daa | ||
|
d9b184bd00 | ||
|
6c8f50b567 | ||
|
6d224d34b6 | ||
|
0b7f8db2c6 | ||
|
f40e43a628 | ||
|
57c5913fb8 | ||
|
2cac878761 | ||
|
28f50e0fed | ||
|
1005485222 | ||
|
be65295633 | ||
|
524b83d026 | ||
|
34819405ab | ||
|
00fcadd9b8 | ||
|
498cfa8b13 | ||
|
e171aa2d15 | ||
|
3d2a101c9e | ||
|
af502c8176 | ||
|
0f439e8407 | ||
|
83fecd3ed0 | ||
|
8411df715c | ||
|
4c0bbc0604 | ||
|
0c7012d647 | ||
|
b051bace27 | ||
|
7e70988188 | ||
|
754d3329a6 | ||
|
82456f220f | ||
|
3e2e349307 | ||
|
c0b1add45f | ||
|
f1ea012a41 | ||
|
b0c4cd29e4 | ||
|
04c8ce76e2 | ||
|
d4a050d173 | ||
|
48677f930d | ||
|
6e536553ef | ||
|
cad38c919c | ||
|
2c49763b73 | ||
|
660603a3df | ||
|
679df49798 | ||
|
48cdc79332 | ||
|
518267d34f | ||
|
f7228d77b5 | ||
|
8b39845d6f | ||
|
9ab4d115cb | ||
|
e292e0452f | ||
|
6d1c363dde | ||
|
77592648e3 | ||
|
23348465a0 | ||
|
60784b53e3 | ||
|
57ceb0ecc8 | ||
|
7d36353579 | ||
|
aa2d0f7b4e | ||
|
4663c80d3a | ||
|
46f73f88b1 | ||
|
66d4386d0e | ||
|
6348ea9d7e | ||
|
3d5bc48dc8 | ||
|
74603f5ed3 | ||
|
4a694e8736 | ||
|
21c7bcd895 | ||
|
95ffb27c9c | ||
|
80ebb424a5 | ||
|
652651b421 | ||
|
9314597d4b | ||
|
48f409438b | ||
|
30dbc81fb5 | ||
|
8935ef4526 | ||
|
20858a49e0 | ||
|
ac6834e979 | ||
|
22ed2ce6c8 | ||
|
f8a0efe03a | ||
|
2f336a2a87 | ||
|
971dd2a4fa | ||
|
c6b937797c | ||
|
84ab952375 | ||
|
78c66b3726 | ||
|
b872d6b5d4 | ||
|
37c4c58371 | ||
|
37e2867335 | ||
|
8f2c22a03f | ||
|
ea6144e243 | ||
|
86d67a3f49 | ||
|
c94a60e2f6 | ||
|
3e7ef74a07 | ||
|
18469830ae | ||
|
3886da50e1 | ||
|
6c0ee003e8 | ||
|
3064f63a6e | ||
|
14c0e93755 | ||
|
cce68f0c9c | ||
|
f4eace1331 | ||
|
408061b469 | ||
|
7d31c02de8 | ||
|
a69b2544d6 | ||
|
15394d356c | ||
|
e58e5303d6 | ||
|
435f949dbb | ||
|
22e4a534c1 | ||
|
c713d2e789 | ||
|
b16653edf0 | ||
|
ec4b5daadf | ||
|
f0be9c88ca | ||
|
78cab6c649 | ||
|
4667f41317 | ||
|
a5a1b28767 | ||
|
7ba9921866 | ||
|
30519426c3 | ||
|
3c0ad4fc9e | ||
|
a1e461d61d | ||
|
46ea10f071 | ||
|
fe57e5af4d | ||
|
fa2663839c | ||
|
5ef4c3c076 | ||
|
2e4159fbe5 | ||
|
3e946c9ebc | ||
|
546819b1d9 | ||
|
0c17f1ee02 | ||
|
ac1a925c2b | ||
|
d701ceac73 | ||
|
7ae23fd1e7 | ||
|
8de80b9a2d | ||
|
eff38cbc18 | ||
|
9353bca5e9 | ||
|
81d8a9234b | ||
|
eaf05340dc | ||
|
74bcd20c0e | ||
|
45341954bc | ||
|
5e3070670f | ||
|
687b2c56d2 | ||
|
58441994df | ||
|
1c8285fd63 | ||
|
ea1cc83b50 | ||
|
12d810d8e6 | ||
|
389ef3f737 | ||
|
752c63249b | ||
|
f9e69b3531 | ||
|
7a21c16f00 | ||
|
a4382e5f37 | ||
|
2de6bf3904 | ||
|
91e16eeff1 | ||
|
b686469597 | ||
|
e50698c200 | ||
|
18cb422451 | ||
|
799e910c74 | ||
|
abe4b10c33 | ||
|
221f327749 | ||
|
2a3454c104 | ||
|
545e9df567 | ||
|
6bd636c964 | ||
|
dd48d704c5 | ||
|
9ef0d5220e | ||
|
02f3189788 | ||
|
92865cee87 | ||
|
8ac4bc41aa | ||
|
b90a325ef3 | ||
|
3ae911f3e7 | ||
|
16651b7870 | ||
|
762f9cbb65 | ||
|
7a69001868 | ||
|
3f968fc16b | ||
|
40b85b18de | ||
|
f9fa30506c | ||
|
b572a72daa | ||
|
03bebcb065 | ||
|
366e9d335c | ||
|
4f100cb6a0 | ||
|
d78b00d2de | ||
|
9db828953a | ||
|
4e61c45ef9 | ||
|
f0523f14a9 | ||
|
4a56d614cf | ||
|
58345b18d9 | ||
|
d4e971c10b | ||
|
16a168763e | ||
|
f4f524df1f | ||
|
73178f0051 | ||
|
e1d15b3340 | ||
|
ed1d91f912 | ||
|
71c656e0e9 | ||
|
73b67041d8 | ||
|
2e5b884fce | ||
|
7eb3d365e3 | ||
|
ccff5658e0 | ||
|
33fc9997bd | ||
|
c3fd5432c3 | ||
|
745082dbd3 | ||
|
73bb1e87c9 | ||
|
5f29c4b940 | ||
|
d7a69edf66 | ||
|
9e937e80fb | ||
|
a9b983a827 | ||
|
f9e1ffaa39 | ||
|
a4bae965eb | ||
|
14e1138441 | ||
|
2861b1c269 | ||
|
06ccc16dec | ||
|
a819f0f019 | ||
|
64ac2e30b6 | ||
|
51f1db7431 | ||
|
35fcdb3b2f | ||
|
3398e7b0c9 | ||
|
13cf9e1b39 | ||
|
afbf3f22ff | ||
|
7fc7826cc1 | ||
|
4b771465b1 | ||
|
76c53b710e | ||
|
2b8deaa5e0 | ||
|
7b5b080a06 | ||
|
64cf9f3249 | ||
|
67dc01d3e0 | ||
|
04c73f86c3 | ||
|
02e8c78f9d | ||
|
957aa3aa62 | ||
|
0133710d47 | ||
|
d8d218ac6f | ||
|
957f0d291c | ||
|
63b9776eee | ||
|
3a49eafd20 | ||
|
6e390924d3 | ||
|
2614f123fd | ||
|
eb89101a1a | ||
|
2a40e19137 | ||
|
376ef823be | ||
|
76cbe0d003 | ||
|
2b81a76bed | ||
|
659b440f9e | ||
|
a93de007a6 | ||
|
05b155ff59 | ||
|
cd7aece14e | ||
|
b8c6fef385 | ||
|
bf889786c2 | ||
|
e160474c52 | ||
|
6828323bc6 | ||
|
31f0e290d6 | ||
|
3c30390ac4 | ||
|
e9144aa159 | ||
|
44d1d163cc | ||
|
d9d06b99a4 | ||
|
55490439d0 | ||
|
e65f49a4cd | ||
|
dc2b2c7fec | ||
|
cac974eb07 | ||
|
44a58145e3 | ||
|
07031f9703 | ||
|
cf0619e458 | ||
|
eb3b78a4ff | ||
|
0c15028124 |
47 changed files with 1991 additions and 713 deletions
51
.github/workflows/test.yml
vendored
Normal file
51
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
name: Build and Run Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: test-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
# - windows-latest
|
||||
cmake:
|
||||
- '4.0'
|
||||
- '3.31'
|
||||
fail-fast: false
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout Project
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@802fa1a2c4e212495c05bf94dba2704a92a472be # v2.0.2
|
||||
with:
|
||||
cmake-version: ${{ matrix.cmake }}
|
||||
- name: Setup Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@3b1f8f94a2f8254bd26914c4ab9474d4f0015f67 # v6
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
cmake -B build -G Ninja \
|
||||
-D CMAKE_CXX_COMPILER=clang++ \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D GFLAGS_BUILD_SHARED_LIBS=ON \
|
||||
-D GFLAGS_BUILD_STATIC_LIBS=ON \
|
||||
-D GFLAGS_BUILD_TESTING=ON
|
||||
- name: Build Tests
|
||||
run: cmake --build build --config Release
|
||||
- name: Run Tests
|
||||
run: cd build && ctest
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,3 +1,8 @@
|
|||
/xcode/
|
||||
/build/
|
||||
/builds/
|
||||
/build-*/
|
||||
/_build/
|
||||
.DS_Store
|
||||
CMakeCache.txt
|
||||
DartConfiguration.tcl
|
||||
|
@ -12,3 +17,9 @@ CMakeFiles/
|
|||
/test/gflags_unittest_main.cc
|
||||
/test/gflags_unittest-main.cc
|
||||
/packages/
|
||||
CMakeLists.txt.user
|
||||
/bazel-bin
|
||||
/bazel-genfiles
|
||||
/bazel-gflags
|
||||
/bazel-out
|
||||
/bazel-testlogs
|
||||
|
|
26
BUILD
Normal file
26
BUILD
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Bazel (http://bazel.io/) BUILD file for gflags.
|
||||
#
|
||||
# See INSTALL.md for instructions for adding gflags to a Bazel workspace.
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
exports_files([
|
||||
"src/gflags_completions.sh",
|
||||
"COPYING.txt",
|
||||
])
|
||||
|
||||
config_setting(
|
||||
name = "x64_windows",
|
||||
values = {"cpu": "x64_windows"},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "android",
|
||||
values = {"crosstool_top": "//external:android/crosstool"},
|
||||
)
|
||||
|
||||
load(":bazel/gflags.bzl", "gflags_library", "gflags_sources")
|
||||
|
||||
(hdrs, srcs) = gflags_sources(namespace=["google", "gflags"])
|
||||
gflags_library(hdrs=hdrs, srcs=srcs, threads=0)
|
||||
gflags_library(hdrs=hdrs, srcs=srcs, threads=1)
|
554
CMakeLists.txt
554
CMakeLists.txt
|
@ -1,29 +1,110 @@
|
|||
cmake_minimum_required (VERSION 2.8.4 FATAL_ERROR)
|
||||
## CMake configuration file of gflags project
|
||||
##
|
||||
## This CMakeLists.txt defines some gflags specific configuration variables
|
||||
## using the "gflags_define" utility macro. The default values of these variables
|
||||
## can be overridden either on the CMake command-line using the -D option of
|
||||
## the cmake command or in a super-project which includes the gflags source
|
||||
## tree by setting the GFLAGS_<varname> CMake variables before adding the
|
||||
## gflags source directory via CMake's "add_subdirectory" command. Only when
|
||||
## the non-cached variable GFLAGS_IS_SUBPROJECT has a value equivalent to FALSE,
|
||||
## these configuration variables are added to the CMake cache so they can be
|
||||
## edited in the CMake GUI. By default, GFLAGS_IS_SUBPROJECT is set to TRUE when
|
||||
## the CMAKE_SOURCE_DIR is not identical to the directory of this CMakeLists.txt
|
||||
## file, i.e., the top-level directory of the gflags project source tree.
|
||||
##
|
||||
## When this project is a subproject (GFLAGS_IS_SUBPROJECT is TRUE), the default
|
||||
## settings are such that only the static single-threaded library is built without
|
||||
## installation of the gflags files. The "gflags::gflags" target is in this case an ALIAS
|
||||
## library target for the "gflags_nothreads_static" library target. Targets which
|
||||
## depend on the gflags library should link to the "gflags::gflags" library target.
|
||||
##
|
||||
## Example CMakeLists.txt of user project which requires separate gflags installation:
|
||||
## cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
##
|
||||
## project(Foo)
|
||||
##
|
||||
## find_package(gflags REQUIRED)
|
||||
##
|
||||
## add_executable(foo src/foo.cc)
|
||||
## target_link_libraries(foo gflags::gflags)
|
||||
##
|
||||
## Example CMakeLists.txt of user project which requires separate single-threaded static gflags installation:
|
||||
## cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
##
|
||||
## project(Foo)
|
||||
##
|
||||
## find_package(gflags COMPONENTS nothreads_static)
|
||||
##
|
||||
## add_executable(foo src/foo.cc)
|
||||
## target_link_libraries(foo gflags::gflags)
|
||||
##
|
||||
## Example CMakeLists.txt of super-project which contains gflags source tree:
|
||||
## cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
##
|
||||
## project(Foo)
|
||||
##
|
||||
## add_subdirectory(gflags)
|
||||
##
|
||||
## add_executable(foo src/foo.cc)
|
||||
## target_link_libraries(foo gflags::gflags)
|
||||
##
|
||||
## Variables to configure the source files:
|
||||
## - GFLAGS_IS_A_DLL
|
||||
## - GFLAGS_NAMESPACE
|
||||
## - GFLAGS_ATTRIBUTE_UNUSED
|
||||
## - GFLAGS_INTTYPES_FORMAT
|
||||
##
|
||||
## Variables to configure the build:
|
||||
## - GFLAGS_SOVERSION
|
||||
## - GFLAGS_BUILD_SHARED_LIBS
|
||||
## - GFLAGS_BUILD_STATIC_LIBS
|
||||
## - GFLAGS_BUILD_gflags_LIB
|
||||
## - GFLAGS_BUILD_gflags_nothreads_LIB
|
||||
## - GFLAGS_BUILD_TESTING
|
||||
## - GFLAGS_BUILD_PACKAGING
|
||||
##
|
||||
## Variables to configure the installation:
|
||||
## - GFLAGS_INCLUDE_DIR
|
||||
## - GFLAGS_LIBRARY_INSTALL_DIR or LIB_INSTALL_DIR or LIB_SUFFIX
|
||||
## - GFLAGS_INSTALL_HEADERS
|
||||
## - GFLAGS_INSTALL_SHARED_LIBS
|
||||
## - GFLAGS_INSTALL_STATIC_LIBS
|
||||
|
||||
cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy (SET CMP0042 NEW)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy (SET CMP0048 NEW)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0063)
|
||||
cmake_policy (SET CMP0063 NEW)
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# includes
|
||||
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
include (utils)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# package information
|
||||
set (PACKAGE_NAME "gflags")
|
||||
set (PACKAGE_VERSION "2.1.2")
|
||||
set (PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set (PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
|
||||
set (PACKAGE_BUGREPORT "https://github.com/schuhschuh/gflags/issues")
|
||||
set (PACKAGE_NAME "gflags")
|
||||
set (PACKAGE_VERSION "2.2.2")
|
||||
set (PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set (PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
|
||||
set (PACKAGE_BUGREPORT "https://github.com/gflags/gflags/issues")
|
||||
set (PACKAGE_DESCRIPTION "A commandline flags library that allows for distributed flags.")
|
||||
set (PACKAGE_URL "http://gflags.github.io/gflags")
|
||||
|
||||
project (${PACKAGE_NAME} CXX)
|
||||
if (CMAKE_VERSION VERSION_LESS 100)
|
||||
project (${PACKAGE_NAME} VERSION ${PACKAGE_VERSION} LANGUAGES CXX)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.4)
|
||||
# C language still needed because the following required CMake modules
|
||||
# (or their dependencies, respectively) are not correctly handling
|
||||
# the case where only CXX is enabled.
|
||||
# - CheckTypeSize.cmake (fixed in CMake 3.1, cf. http://www.cmake.org/Bug/view.php?id=14056)
|
||||
# - FindThreads.cmake (--> CheckIncludeFiles.cmake <--)
|
||||
# the case where only CXX is enabled
|
||||
# - CheckTypeSize.cmake (fixed in CMake 3.1, cf. https://cmake.org/Bug/view.php?id=14056)
|
||||
# - FindThreads.cmake (fixed in CMake 3.4, cf. https://cmake.org/Bug/view.php?id=14905)
|
||||
enable_language (C)
|
||||
endif ()
|
||||
|
||||
|
@ -34,17 +115,45 @@ version_numbers (
|
|||
PACKAGE_VERSION_PATCH
|
||||
)
|
||||
|
||||
set (PACKAGE_SOVERSION "${PACKAGE_VERSION_MAJOR}")
|
||||
# shared library ABI version number, can be overridden by package maintainers
|
||||
# using -DGFLAGS_SOVERSION=XXX on the command-line
|
||||
if (GFLAGS_SOVERSION)
|
||||
set (PACKAGE_SOVERSION "${GFLAGS_SOVERSION}")
|
||||
else ()
|
||||
# TODO: Change default SOVERSION back to PACKAGE_VERSION_MAJOR with the
|
||||
# next increase of major version number (i.e., 3.0.0 -> SOVERSION 3)
|
||||
# The <major>.<minor> SOVERSION should be used for the 2.x releases
|
||||
# versions only which temporarily broke the API by changing the default
|
||||
# namespace from "google" to "gflags".
|
||||
set (PACKAGE_SOVERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")
|
||||
endif ()
|
||||
|
||||
# when gflags is included as subproject (e.g., as Git submodule/subtree) in the source
|
||||
# tree of a project that uses it, no variables should be added to the CMake cache;
|
||||
# users may set the non-cached variable GFLAGS_IS_SUBPROJECT before add_subdirectory(gflags)
|
||||
if (NOT DEFINED GFLAGS_IS_SUBPROJECT)
|
||||
if ("^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
|
||||
set (GFLAGS_IS_SUBPROJECT FALSE)
|
||||
else ()
|
||||
set (GFLAGS_IS_SUBPROJECT TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# prefix for package variables in CMake configuration file
|
||||
string (TOUPPER "${PACKAGE_NAME}" PACKAGE_PREFIX)
|
||||
|
||||
# convert file path on Windows with back slashes to path with forward slashes
|
||||
# otherwise this causes an issue with the cmake_install.cmake script
|
||||
file (TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# options
|
||||
if (NOT GFLAGS_NAMESPACE)
|
||||
# maintain binary backwards compatibility with gflags library version <= 2.0,
|
||||
# but at the same time enable the use of the preferred new "gflags" namespace
|
||||
set (GFLAGS_NAMESPACE "google;${PACKAGE_NAME}" CACHE STRING "Name(s) of library namespace (separate multiple options by semicolon)")
|
||||
mark_as_advanced (GFLAGS_NAMESPACE)
|
||||
endif ()
|
||||
set (GFLAGS_NAMESPACE_SECONDARY "${GFLAGS_NAMESPACE}")
|
||||
|
||||
# maintain binary backwards compatibility with gflags library version <= 2.0,
|
||||
# but at the same time enable the use of the preferred new "gflags" namespace
|
||||
gflags_define (STRING NAMESPACE "Name(s) of library namespace (separate multiple options by semicolon)" "google;${PACKAGE_NAME}" "${PACKAGE_NAME}")
|
||||
gflags_property (NAMESPACE ADVANCED TRUE)
|
||||
set (GFLAGS_NAMESPACE_SECONDARY "${NAMESPACE}")
|
||||
list (REMOVE_DUPLICATES GFLAGS_NAMESPACE_SECONDARY)
|
||||
if (NOT GFLAGS_NAMESPACE_SECONDARY)
|
||||
message (FATAL_ERROR "GFLAGS_NAMESPACE must be set to one (or more) valid C++ namespace identifier(s separated by semicolon \";\").")
|
||||
|
@ -57,48 +166,59 @@ endforeach ()
|
|||
list (GET GFLAGS_NAMESPACE_SECONDARY 0 GFLAGS_NAMESPACE)
|
||||
list (REMOVE_AT GFLAGS_NAMESPACE_SECONDARY 0)
|
||||
|
||||
option (BUILD_SHARED_LIBS "Request build of shared libraries." OFF)
|
||||
option (BUILD_STATIC_LIBS "Request build of static libraries (default if BUILD_SHARED_LIBS is OFF)." OFF)
|
||||
option (BUILD_gflags_LIB "Request build of the multi-threaded gflags library." ON)
|
||||
option (BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library." ON)
|
||||
option (BUILD_PACKAGING "Enable build of distribution packages using CPack." OFF)
|
||||
option (BUILD_TESTING "Enable build of the unit tests and their execution using CTest." OFF)
|
||||
option (BUILD_NC_TESTS "Request addition of negative compilation tests." OFF)
|
||||
option (INSTALL_HEADERS "Request packaging of headers and other development files." ON)
|
||||
# cached build options when gflags is not a subproject, otherwise non-cached CMake variables
|
||||
# usage: gflags_define(BOOL <name> <doc> <default> [<subproject default>])
|
||||
gflags_define (BOOL BUILD_SHARED_LIBS "Request build of shared libraries." OFF OFF)
|
||||
gflags_define (BOOL BUILD_STATIC_LIBS "Request build of static libraries (default if BUILD_SHARED_LIBS is OFF)." OFF ON)
|
||||
gflags_define (BOOL BUILD_gflags_LIB "Request build of the multi-threaded gflags library." ON OFF)
|
||||
gflags_define (BOOL BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library." ON ON)
|
||||
gflags_define (BOOL BUILD_PACKAGING "Enable build of distribution packages using CPack." OFF OFF)
|
||||
gflags_define (BOOL BUILD_TESTING "Enable build of the unit tests and their execution using CTest." OFF OFF)
|
||||
gflags_define (BOOL INSTALL_HEADERS "Request installation of headers and other development files." ON OFF)
|
||||
gflags_define (BOOL INSTALL_SHARED_LIBS "Request installation of shared libraries." ON ON)
|
||||
gflags_define (BOOL INSTALL_STATIC_LIBS "Request installation of static libraries." ON OFF)
|
||||
gflags_define (BOOL REGISTER_BUILD_DIR "Request entry of build directory in CMake's package registry." OFF OFF)
|
||||
gflags_define (BOOL REGISTER_INSTALL_PREFIX "Request entry of installed package in CMake's package registry." ON OFF)
|
||||
gflags_define (BOOL EXPORT_NAMESPACE_SET "Request export namespace targets set." ON ON)
|
||||
gflags_define (BOOL EXPORT_NONAMESPACE_SET "Request export nonamespace targets set." ON OFF)
|
||||
|
||||
mark_as_advanced (CLEAR CMAKE_INSTALL_PREFIX)
|
||||
mark_as_advanced (CMAKE_CONFIGURATION_TYPES
|
||||
BUILD_STATIC_LIBS
|
||||
BUILD_NC_TESTS
|
||||
INSTALL_HEADERS)
|
||||
if (APPLE)
|
||||
mark_as_advanced(CMAKE_OSX_ARCHITECTURES
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET
|
||||
CMAKE_OSX_SYSROOT)
|
||||
endif ()
|
||||
gflags_property (BUILD_STATIC_LIBS ADVANCED TRUE)
|
||||
gflags_property (INSTALL_HEADERS ADVANCED TRUE)
|
||||
gflags_property (INSTALL_SHARED_LIBS ADVANCED TRUE)
|
||||
gflags_property (INSTALL_STATIC_LIBS ADVANCED TRUE)
|
||||
|
||||
if (NOT GFLAGS_IS_SUBPROJECT)
|
||||
foreach (varname IN ITEMS CMAKE_INSTALL_PREFIX)
|
||||
gflags_property (${varname} ADVANCED FALSE)
|
||||
endforeach ()
|
||||
foreach (varname IN ITEMS CMAKE_CONFIGURATION_TYPES CMAKE_OSX_ARCHITECTURES CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT)
|
||||
gflags_property (${varname} ADVANCED TRUE)
|
||||
endforeach ()
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
|
||||
gflags_set (CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
if (CMAKE_CONFIGURATION_TYPES)
|
||||
gflags_property (CMAKE_BUILD_TYPE STRINGS "${CMAKE_CONFIGURATION_TYPES}")
|
||||
endif ()
|
||||
endif () # NOT GFLAGS_IS_SUBPROJECT
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
|
||||
set (BUILD_STATIC_LIBS ON)
|
||||
endif ()
|
||||
if (NOT BUILD_gflags_LIB AND NOT BUILD_gflags_nothreads_LIB)
|
||||
message (FATAL_ERROR "At least one of BUILD_gflags_LIB and BUILD_gflags_nothreads_LIB must be ON.")
|
||||
message (FATAL_ERROR "At least one of [GFLAGS_]BUILD_gflags_LIB and [GFLAGS_]BUILD_gflags_nothreads_LIB must be ON.")
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
|
||||
set_property (CACHE CMAKE_BUILD_TYPE PROPERTY VALUE Release)
|
||||
gflags_define (STRING INCLUDE_DIR "Name of include directory of installed header files relative to CMAKE_INSTALL_PREFIX/include/" "${PACKAGE_NAME}")
|
||||
gflags_property (INCLUDE_DIR ADVANCED TRUE)
|
||||
file (TO_CMAKE_PATH "${INCLUDE_DIR}" INCLUDE_DIR)
|
||||
if (IS_ABSOLUTE INCLUDE_DIR)
|
||||
message (FATAL_ERROR "[GFLAGS_]INCLUDE_DIR must be a path relative to CMAKE_INSTALL_PREFIX/include/")
|
||||
endif ()
|
||||
|
||||
if (NOT GFLAGS_INCLUDE_DIR)
|
||||
set (GFLAGS_INCLUDE_DIR "${PACKAGE_NAME}" CACHE STRING "Name of include directory of installed header files")
|
||||
mark_as_advanced (GFLAGS_INCLUDE_DIR)
|
||||
else ()
|
||||
if (IS_ABSOLUTE GFLAGS_INCLUDE_DIR)
|
||||
message (FATAL_ERROR "GFLAGS_INCLUDE_DIR must be a path relative to CMAKE_INSTALL_PREFIX/include")
|
||||
endif ()
|
||||
if (GFLAGS_INCLUDE_DIR MATCHES "^\\.\\.[/\\]")
|
||||
message (FATAL_ERROR "GFLAGS_INCLUDE_DIR must not start with parent directory reference (../)")
|
||||
endif ()
|
||||
if (INCLUDE_DIR MATCHES "^\\.\\.[/\\]")
|
||||
message (FATAL_ERROR "[GFLAGS_]INCLUDE_DIR must not start with parent directory reference (../)")
|
||||
endif ()
|
||||
set (GFLAGS_INCLUDE_DIR "${INCLUDE_DIR}")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# system checks
|
||||
|
@ -114,12 +234,22 @@ endif ()
|
|||
|
||||
if (MSVC)
|
||||
set (HAVE_SYS_TYPES_H 1)
|
||||
set (HAVE_STDINT_H 1)
|
||||
set (HAVE_STDDEF_H 1) # used by CheckTypeSize module
|
||||
set (HAVE_INTTYPES_H 0)
|
||||
set (HAVE_UNISTD_H 0)
|
||||
set (HAVE_SYS_STAT_H 1)
|
||||
set (HAVE_SHLWAPI_H 1)
|
||||
if (MSVC_VERSION VERSION_LESS 1600)
|
||||
check_include_file_cxx ("stdint.h" HAVE_STDINT_H)
|
||||
bool_to_int (HAVE_STDINT_H) # used in #if directive
|
||||
else ()
|
||||
set (HAVE_STDINT_H 1)
|
||||
endif ()
|
||||
if (MSVC_VERSION VERSION_LESS 1800)
|
||||
check_include_file_cxx ("inttypes.h" HAVE_INTTYPES_H)
|
||||
bool_to_int (HAVE_INTTYPES_H) # used in #if directive
|
||||
else ()
|
||||
set (HAVE_INTTYPES_H 1)
|
||||
endif ()
|
||||
else ()
|
||||
foreach (fname IN ITEMS unistd stdint inttypes sys/types sys/stat fnmatch)
|
||||
string (TOUPPER "${fname}" FNAME)
|
||||
|
@ -128,19 +258,19 @@ else ()
|
|||
check_include_file_cxx ("${fname}.h" HAVE_${FNAME}_H)
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (NOT HAVE_FNMATCH_H AND OS_WINDOWS)
|
||||
check_include_file_cxx ("shlwapi.h" HAVE_SHLWAPI_H)
|
||||
endif ()
|
||||
# the following are used in #if directives not #ifdef
|
||||
bool_to_int (HAVE_STDINT_H)
|
||||
bool_to_int (HAVE_SYS_TYPES_H)
|
||||
bool_to_int (HAVE_INTTYPES_H)
|
||||
if (NOT HAVE_FNMATCH_H AND OS_WINDOWS)
|
||||
check_include_file_cxx ("shlwapi.h" HAVE_SHLWAPI_H)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set (GFLAGS_INTTYPES_FORMAT "" CACHE STRING "Format of integer types: \"C99\" (uint32_t), \"BSD\" (u_int32_t), \"VC7\" (__int32)")
|
||||
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY STRINGS "C99;BSD;VC7")
|
||||
mark_as_advanced (GFLAGS_INTTYPES_FORMAT)
|
||||
if (NOT GFLAGS_INTTYPES_FORMAT)
|
||||
gflags_define (STRING INTTYPES_FORMAT "Format of integer types: \"C99\" (uint32_t), \"BSD\" (u_int32_t), \"VC7\" (__int32)" "")
|
||||
gflags_property (INTTYPES_FORMAT STRINGS "C99;BSD;VC7")
|
||||
gflags_property (INTTYPES_FORMAT ADVANCED TRUE)
|
||||
if (NOT INTTYPES_FORMAT)
|
||||
set (TYPES uint32_t u_int32_t)
|
||||
if (MSVC)
|
||||
list (INSERT TYPES 0 __int32)
|
||||
|
@ -152,29 +282,30 @@ if (NOT GFLAGS_INTTYPES_FORMAT)
|
|||
endif ()
|
||||
endforeach ()
|
||||
if (HAVE_uint32_t)
|
||||
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE C99)
|
||||
gflags_set (INTTYPES_FORMAT C99)
|
||||
elseif (HAVE_u_int32_t)
|
||||
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE BSD)
|
||||
gflags_set (INTTYPES_FORMAT BSD)
|
||||
elseif (HAVE___int32)
|
||||
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7)
|
||||
gflags_set (INTTYPES_FORMAT VC7)
|
||||
else ()
|
||||
mark_as_advanced (CLEAR GFLAGS_INTTYPES_FORMAT)
|
||||
gflags_property (INTTYPES_FORMAT ADVANCED FALSE)
|
||||
message (FATAL_ERROR "Do not know how to define a 32-bit integer quantity on your system!"
|
||||
" Neither uint32_t, u_int32_t, nor __int32 seem to be available."
|
||||
" Set GFLAGS_INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.")
|
||||
" Set [GFLAGS_]INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.")
|
||||
endif ()
|
||||
endif ()
|
||||
# use of special characters in strings to circumvent bug #0008226
|
||||
if ("^${GFLAGS_INTTYPES_FORMAT}$" STREQUAL "^WIN$")
|
||||
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7)
|
||||
if ("^${INTTYPES_FORMAT}$" STREQUAL "^WIN$")
|
||||
gflags_set (INTTYPES_FORMAT VC7)
|
||||
endif ()
|
||||
if (NOT GFLAGS_INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$")
|
||||
message (FATAL_ERROR "Invalid value for GFLAGS_INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"")
|
||||
if (NOT INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$")
|
||||
message (FATAL_ERROR "Invalid value for [GFLAGS_]INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"")
|
||||
endif ()
|
||||
set (GFLAGS_INTTYPES_FORMAT "${INTTYPES_FORMAT}")
|
||||
set (GFLAGS_INTTYPES_FORMAT_C99 0)
|
||||
set (GFLAGS_INTTYPES_FORMAT_BSD 0)
|
||||
set (GFLAGS_INTTYPES_FORMAT_VC7 0)
|
||||
set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" 1)
|
||||
set ("GFLAGS_INTTYPES_FORMAT_${INTTYPES_FORMAT}" 1)
|
||||
|
||||
if (MSVC)
|
||||
set (HAVE_strtoll 0)
|
||||
|
@ -186,26 +317,29 @@ else ()
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package (Threads)
|
||||
if (Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
|
||||
set (HAVE_PTHREAD 1)
|
||||
check_type_size (pthread_rwlock_t RWLOCK LANGUAGE CXX)
|
||||
if (BUILD_gflags_LIB)
|
||||
set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package (Threads)
|
||||
if (Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
|
||||
set (HAVE_PTHREAD 1)
|
||||
check_type_size (pthread_rwlock_t RWLOCK LANGUAGE CXX)
|
||||
else ()
|
||||
set (HAVE_PTHREAD 0)
|
||||
endif ()
|
||||
if (UNIX AND NOT HAVE_PTHREAD)
|
||||
if (CMAKE_HAVE_PTHREAD_H)
|
||||
set (what "library")
|
||||
else ()
|
||||
set (what ".h file")
|
||||
endif ()
|
||||
message (FATAL_ERROR "Could not find pthread${what}. Check the log file"
|
||||
"\n\t${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"\nor disable the build of the multi-threaded gflags library (BUILD_gflags_LIB=OFF).")
|
||||
endif ()
|
||||
else ()
|
||||
set (HAVE_PTHREAD 0)
|
||||
endif ()
|
||||
|
||||
if (UNIX AND NOT HAVE_PTHREAD AND BUILD_gflags_LIB)
|
||||
if (CMAKE_HAVE_PTHREAD_H)
|
||||
set (what "library")
|
||||
else ()
|
||||
set (what ".h file")
|
||||
endif ()
|
||||
message (FATAL_ERROR "Could not find pthread${what}. Check the log file"
|
||||
"\n\t${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"\nor disable the build of the multi-threaded gflags library (BUILD_gflags_LIB=OFF).")
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# source files - excluding root subdirectory and/or .in suffix
|
||||
set (PUBLIC_HDRS
|
||||
|
@ -228,6 +362,7 @@ else ()
|
|||
endif ()
|
||||
|
||||
set (PRIVATE_HDRS
|
||||
"defines.h"
|
||||
"config.h"
|
||||
"util.h"
|
||||
"mutex.h"
|
||||
|
@ -246,34 +381,64 @@ endif ()
|
|||
|
||||
# ----------------------------------------------------------------------------
|
||||
# configure source files
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (GFLAGS_ATTRIBUTE_UNUSED "__attribute((unused))")
|
||||
else ()
|
||||
set (GFLAGS_ATTRIBUTE_UNUSED)
|
||||
if (NOT DEFINED GFLAGS_ATTRIBUTE_UNUSED)
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (GFLAGS_ATTRIBUTE_UNUSED "__attribute((unused))")
|
||||
else ()
|
||||
set (GFLAGS_ATTRIBUTE_UNUSED)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# whenever we build a shared library (DLL on Windows), configure the public
|
||||
# headers of the API for use of this library rather than the optionally
|
||||
# headers of the API for use of this shared library rather than the optionally
|
||||
# also build statically linked library; users can override GFLAGS_DLL_DECL
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (GFLAGS_IS_A_DLL 1)
|
||||
else ()
|
||||
set (GFLAGS_IS_A_DLL 0)
|
||||
# in particular, this done by setting the INTERFACE_COMPILE_DEFINITIONS of
|
||||
# static libraries to include an empty definition for GFLAGS_DLL_DECL
|
||||
if (NOT DEFINED GFLAGS_IS_A_DLL)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (GFLAGS_IS_A_DLL 1)
|
||||
else ()
|
||||
set (GFLAGS_IS_A_DLL 0)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
configure_headers (PUBLIC_HDRS ${PUBLIC_HDRS})
|
||||
configure_sources (PRIVATE_HDRS ${PRIVATE_HDRS})
|
||||
configure_sources (GFLAGS_SRCS ${GFLAGS_SRCS})
|
||||
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/src")
|
||||
include_directories ("${PROJECT_BINARY_DIR}/include")
|
||||
include_directories ("${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# output directories
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin")
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
|
||||
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib")
|
||||
if (NOT GFLAGS_IS_SUBPROJECT)
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin")
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
|
||||
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib")
|
||||
endif ()
|
||||
# Set postfixes for generated libraries based on buildtype.
|
||||
set(CMAKE_RELEASE_POSTFIX "")
|
||||
set(CMAKE_DEBUG_POSTFIX "_debug")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# installation directories
|
||||
if (OS_WINDOWS AND NOT MINGW)
|
||||
set (RUNTIME_INSTALL_DIR "bin")
|
||||
set (LIBRARY_INSTALL_DIR "lib")
|
||||
set (INCLUDE_INSTALL_DIR "include")
|
||||
set (CONFIG_INSTALL_DIR "lib/cmake/${PACKAGE_NAME}")
|
||||
set (PKGCONFIG_INSTALL_DIR)
|
||||
else ()
|
||||
set (RUNTIME_INSTALL_DIR bin)
|
||||
# The LIB_INSTALL_DIR and LIB_SUFFIX variables are used by the Fedora
|
||||
# package maintainers. Also package maintainers of other distribution
|
||||
# packages need to be able to specify the name of the library directory.
|
||||
if (NOT GFLAGS_LIBRARY_INSTALL_DIR AND LIB_INSTALL_DIR)
|
||||
set (GFLAGS_LIBRARY_INSTALL_DIR "${LIB_INSTALL_DIR}")
|
||||
endif ()
|
||||
gflags_define (PATH LIBRARY_INSTALL_DIR "Directory of installed libraries, e.g., \"lib64\"" "lib${LIB_SUFFIX}")
|
||||
gflags_property (LIBRARY_INSTALL_DIR ADVANCED TRUE)
|
||||
set (INCLUDE_INSTALL_DIR include)
|
||||
set (CONFIG_INSTALL_DIR ${LIBRARY_INSTALL_DIR}/cmake/${PACKAGE_NAME})
|
||||
set (PKGCONFIG_INSTALL_DIR ${LIBRARY_INSTALL_DIR}/pkgconfig)
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# add library targets
|
||||
|
@ -281,72 +446,110 @@ set (TARGETS)
|
|||
# static vs. shared
|
||||
foreach (TYPE IN ITEMS STATIC SHARED)
|
||||
if (BUILD_${TYPE}_LIBS)
|
||||
string (TOLOWER "${TYPE}" type)
|
||||
# whether or not targets are a DLL
|
||||
if (OS_WINDOWS AND "^${TYPE}$" STREQUAL "^SHARED$")
|
||||
set (GFLAGS_IS_A_DLL 1)
|
||||
else ()
|
||||
set (GFLAGS_IS_A_DLL 0)
|
||||
endif ()
|
||||
string (TOLOWER "${TYPE}" type)
|
||||
# filename suffix for static libraries on Windows for MSVC toolchain only
|
||||
if (OS_WINDOWS AND NOT MINGW AND "^${TYPE}$" STREQUAL "^STATIC$")
|
||||
set (type_suffix "_${type}")
|
||||
else ()
|
||||
set (type_suffix "")
|
||||
endif ()
|
||||
# multi-threaded vs. single-threaded
|
||||
foreach (opts IN ITEMS "" _nothreads)
|
||||
if (BUILD_gflags${opts}_LIB)
|
||||
add_library (gflags${opts}-${type} ${TYPE} ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
|
||||
if (opts MATCHES "nothreads")
|
||||
set (defines "GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL};NOTHREADS")
|
||||
else ()
|
||||
set (defines "GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL}")
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
target_link_libraries (gflags${opts}-${type} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
endif ()
|
||||
set_target_properties (
|
||||
gflags${opts}-${type} PROPERTIES COMPILE_DEFINITIONS "${defines}"
|
||||
OUTPUT_NAME "gflags${opts}"
|
||||
VERSION "${PACKAGE_VERSION}"
|
||||
SOVERSION "${PACKAGE_SOVERSION}"
|
||||
set (target_name "gflags${opts}_${type}")
|
||||
add_library (${target_name} ${TYPE} ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
|
||||
set_target_properties (${target_name} PROPERTIES
|
||||
OUTPUT_NAME "gflags${opts}${type_suffix}"
|
||||
VERSION "${PACKAGE_VERSION}"
|
||||
SOVERSION "${PACKAGE_SOVERSION}"
|
||||
)
|
||||
set (include_dirs "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>")
|
||||
if (INSTALL_HEADERS)
|
||||
list (APPEND include_dirs "$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>")
|
||||
endif ()
|
||||
target_include_directories (${target_name}
|
||||
PUBLIC "${include_dirs}"
|
||||
PRIVATE "${PROJECT_SOURCE_DIR}/src;${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}"
|
||||
)
|
||||
target_compile_definitions (${target_name} PUBLIC GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL})
|
||||
if (opts MATCHES "nothreads")
|
||||
target_compile_definitions (${target_name} PRIVATE NO_THREADS)
|
||||
elseif (CMAKE_USE_PTHREADS_INIT)
|
||||
target_link_libraries (${target_name} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
if (HAVE_SHLWAPI_H)
|
||||
target_link_libraries (gflags${opts}-${type} shlwapi.lib)
|
||||
target_link_libraries (${target_name} shlwapi.lib)
|
||||
endif ()
|
||||
if (NOT TARGET gflags${opts})
|
||||
add_custom_target (gflags${opts})
|
||||
list (APPEND TARGETS ${target_name})
|
||||
# add convenience make target for build of both shared and static libraries
|
||||
if (NOT GFLAGS_IS_SUBPROJECT)
|
||||
if (NOT TARGET gflags${opts})
|
||||
add_custom_target (gflags${opts})
|
||||
endif ()
|
||||
add_dependencies (gflags${opts} ${target_name})
|
||||
endif ()
|
||||
add_dependencies (gflags${opts} gflags${opts}-${type})
|
||||
list (APPEND TARGETS gflags${opts}-${type})
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# installation
|
||||
if (OS_WINDOWS)
|
||||
set (RUNTIME_INSTALL_DIR Bin)
|
||||
set (LIBRARY_INSTALL_DIR Lib)
|
||||
set (INCLUDE_INSTALL_DIR Include)
|
||||
set (CONFIG_INSTALL_DIR CMake)
|
||||
else ()
|
||||
set (RUNTIME_INSTALL_DIR bin)
|
||||
# The LIB_INSTALL_DIR and LIB_SUFFIX variables are used by the Fedora
|
||||
# package maintainers. Also package maintainers of other distribution
|
||||
# packages need to be able to specify the name of the library directory.
|
||||
if (NOT LIB_INSTALL_DIR)
|
||||
set (LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
|
||||
endif ()
|
||||
set (LIBRARY_INSTALL_DIR "${LIB_INSTALL_DIR}"
|
||||
CACHE PATH "Directory of installed libraries, e.g., \"lib64\""
|
||||
)
|
||||
mark_as_advanced (LIBRARY_INSTALL_DIR)
|
||||
set (INCLUDE_INSTALL_DIR include)
|
||||
set (CONFIG_INSTALL_DIR ${LIBRARY_INSTALL_DIR}/cmake/${PACKAGE_NAME})
|
||||
# add ALIAS target for use in super-project, prefer static over shared, single-threaded over multi-threaded
|
||||
if (GFLAGS_IS_SUBPROJECT)
|
||||
foreach (type IN ITEMS static shared)
|
||||
foreach (opts IN ITEMS "_nothreads" "")
|
||||
if (TARGET gflags${opts}_${type})
|
||||
# Define "gflags" alias for super-projects treating targets of this library as part of their own project
|
||||
# (also for backwards compatibility with gflags 2.2.1 which only defined this alias)
|
||||
add_library (gflags ALIAS gflags${opts}_${type})
|
||||
# Define "gflags::gflags" alias for projects that support both find_package(gflags) and add_subdirectory(gflags)
|
||||
add_library (gflags::gflags ALIAS gflags${opts}_${type})
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (TARGET gflags::gflags)
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# installation rules
|
||||
set (EXPORT_NAME ${PACKAGE_NAME}-targets)
|
||||
file (RELATIVE_PATH INSTALL_PREFIX_REL2CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_INSTALL_DIR}" "${CMAKE_INSTALL_PREFIX}")
|
||||
configure_file (cmake/config.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-install.cmake" @ONLY)
|
||||
configure_file (cmake/version.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake" @ONLY)
|
||||
|
||||
install (TARGETS ${TARGETS} DESTINATION ${LIBRARY_INSTALL_DIR} EXPORT gflags-lib)
|
||||
if (BUILD_SHARED_LIBS AND INSTALL_SHARED_LIBS)
|
||||
foreach (opts IN ITEMS "" _nothreads)
|
||||
if (BUILD_gflags${opts}_LIB)
|
||||
install (TARGETS gflags${opts}_shared
|
||||
EXPORT ${EXPORT_NAME}
|
||||
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
|
||||
)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
if (BUILD_STATIC_LIBS AND INSTALL_STATIC_LIBS)
|
||||
foreach (opts IN ITEMS "" _nothreads)
|
||||
if (BUILD_gflags${opts}_LIB)
|
||||
install (TARGETS gflags${opts}_static
|
||||
EXPORT ${EXPORT_NAME}
|
||||
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
|
||||
)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (INSTALL_HEADERS)
|
||||
install (FILES ${PUBLIC_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/${GFLAGS_INCLUDE_DIR})
|
||||
install (
|
||||
|
@ -358,24 +561,57 @@ if (INSTALL_HEADERS)
|
|||
FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake"
|
||||
DESTINATION ${CONFIG_INSTALL_DIR}
|
||||
)
|
||||
install (EXPORT gflags-lib DESTINATION ${CONFIG_INSTALL_DIR} FILE ${PACKAGE_NAME}-export.cmake)
|
||||
if (EXPORT_NAMESPACE_SET)
|
||||
install (
|
||||
EXPORT ${EXPORT_NAME}
|
||||
NAMESPACE ${PACKAGE_NAME}::
|
||||
DESTINATION ${CONFIG_INSTALL_DIR}
|
||||
)
|
||||
endif ()
|
||||
if (EXPORT_NONAMESPACE_SET)
|
||||
install (
|
||||
EXPORT ${EXPORT_NAME}
|
||||
FILE ${PACKAGE_NAME}-nonamespace-targets.cmake
|
||||
DESTINATION ${CONFIG_INSTALL_DIR}
|
||||
)
|
||||
endif ()
|
||||
if (UNIX)
|
||||
install (PROGRAMS src/gflags_completions.sh DESTINATION ${RUNTIME_INSTALL_DIR})
|
||||
endif ()
|
||||
if (PKGCONFIG_INSTALL_DIR)
|
||||
configure_file ("cmake/package.pc.in" "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}.pc" @ONLY)
|
||||
install (FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# support direct use of build tree
|
||||
set (INSTALL_PREFIX_REL2CONFIG_DIR .)
|
||||
export (TARGETS ${TARGETS} FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-export.cmake")
|
||||
export (PACKAGE gflags)
|
||||
if (EXPORT_NAMESPACE_SET)
|
||||
export (
|
||||
TARGETS ${TARGETS}
|
||||
NAMESPACE ${PACKAGE_NAME}::
|
||||
FILE "${PROJECT_BINARY_DIR}/${EXPORT_NAME}.cmake"
|
||||
)
|
||||
endif ()
|
||||
if (EXPORT_NONAMESPACE_SET)
|
||||
export (
|
||||
TARGETS ${TARGETS}
|
||||
FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-nonamespace-targets.cmake"
|
||||
)
|
||||
endif ()
|
||||
if (REGISTER_BUILD_DIR)
|
||||
export (PACKAGE ${PACKAGE_NAME})
|
||||
endif ()
|
||||
if (REGISTER_INSTALL_PREFIX)
|
||||
register_gflags_package(${CONFIG_INSTALL_DIR})
|
||||
endif ()
|
||||
configure_file (cmake/config.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake" @ONLY)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# testing - MUST follow the generation of the build tree config file
|
||||
if (BUILD_TESTING)
|
||||
include (CTest)
|
||||
enable_testing ()
|
||||
add_subdirectory (test)
|
||||
endif ()
|
||||
|
||||
|
@ -389,10 +625,14 @@ if (BUILD_PACKAGING)
|
|||
"\n BUILD_SHARED_LIBS=ON"
|
||||
"\n BUILD_STATIC_LIBS=OFF"
|
||||
"\n INSTALL_HEADERS=OFF"
|
||||
"\n INSTALL_SHARED_LIBS=ON"
|
||||
"\nRecommended options for generation of development package:"
|
||||
"\n BUILD_SHARED_LIBS=ON"
|
||||
"\n BUILD_STATIC_LIBS=ON"
|
||||
"\n INSTALL_HEADERS=ON")
|
||||
"\n INSTALL_HEADERS=ON"
|
||||
"\n INSTALL_SHARED_LIBS=ON"
|
||||
"\n INSTALL_STATIC_LIBS=ON"
|
||||
)
|
||||
endif ()
|
||||
|
||||
# default package generators
|
||||
|
@ -423,7 +663,7 @@ if (BUILD_PACKAGING)
|
|||
set (CPACK_PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION_MAJOR}")
|
||||
set (CPACK_PACKAGE_VERSION_MINOR "${PACKAGE_VERSION_MINOR}")
|
||||
set (CPACK_PACKAGE_VERSION_PATCH "${PACKAGE_VERSION_PATCH}")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "A commandline flags library that allows for distributed flags.")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE_DESCRIPTION}")
|
||||
set (CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_BINARY_DIR}/README.txt")
|
||||
set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_LIST_DIR}/COPYING.txt")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_BINARY_DIR}/README.txt")
|
||||
|
@ -435,7 +675,7 @@ if (BUILD_PACKAGING)
|
|||
# RPM package information -- used in cmake/package.cmake.in also for DEB
|
||||
set (CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
|
||||
set (CPACK_RPM_PACKAGE_LICENSE "BSD")
|
||||
set (CPACK_RPM_PACKAGE_URL "http://schuhschuh.github.com/gflags")
|
||||
set (CPACK_RPM_PACKAGE_URL "${PACKAGE_URL}")
|
||||
set (CPACK_RPM_CHANGELOG_FILE "${CMAKE_CURRENT_LIST_DIR}/ChangeLog.txt")
|
||||
|
||||
if (INSTALL_HEADERS)
|
||||
|
@ -504,3 +744,11 @@ if (BUILD_PACKAGING)
|
|||
include (CPack)
|
||||
|
||||
endif () # BUILD_PACKAGING
|
||||
|
||||
if (NOT GFLAGS_IS_SUBPROJECT AND NOT TARGET uninstall)
|
||||
configure_file (
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" @ONLY
|
||||
)
|
||||
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
endif ()
|
||||
|
|
|
@ -1,3 +1,61 @@
|
|||
* Sun Nov 11 2018 - Andreas Schuh <andreas.schuh.84@gmail.com>
|
||||
|
||||
- gflags: version 2.2.2
|
||||
Fixed 267: Support build with GCC option "-fvisibility=hidden".
|
||||
Fixed 262: Declare FLAGS_no##name variables as static to avoid "previous extern" warning.
|
||||
Fixed 261: Declare FlagRegisterer c’tor explicit template instanations as extern in header
|
||||
Fixed 257: Build with _UNICODE support on Windows.
|
||||
Fixed 233/234/235: Move CMake defines that are unused by Bazel to separate header; makes config.h private again
|
||||
Fixed 228: Build with recent MinGW versions that define setenv.
|
||||
Fixed 226: Remove obsolete and unused CleanFileName code
|
||||
Merged 266: Various PVS Studio and GCC warnings.
|
||||
Merged 258: Fix build with some Clang variants that define "restrict" macro.
|
||||
Merged 252: Update documentation on how to use Bazel.
|
||||
Merged 249: Use "_debug" postfix for debug libraries.
|
||||
Merged 247: CMake "project" VERSION; no enable_testing(); "gflags::" import target prefix.
|
||||
Merged 246: Add Bazel-on-Windows support.
|
||||
Merged 239: Use GFLAGS_NAMESPACE instead of "gflags" in test executable.
|
||||
Merged 237: Removed unused functions; fixes compilation with -Werror compiler option.
|
||||
Merged 232: Fix typo in Bazel's BUILD definition
|
||||
Merged 230: Remove using ::fLS::clstring.
|
||||
Merged 221: Add convenience 'uninstall' target
|
||||
|
||||
* Tue Jul 11 2017 - Andreas Schuh <andreas.schuh.84@gmail.com>
|
||||
|
||||
- gflags: version 2.2.1
|
||||
- Link to online documentation in README
|
||||
- Merged 194: Include utils by file instead of CMAKE_MODULE_PATH search
|
||||
- Merged 195: Remove unused program_name variable
|
||||
- Merged 196: Enable language C for older CMake versions when needed
|
||||
- Merged 202: Changed include directory in bazel build
|
||||
- Merged 207: Mark single argument constructors in mutex.h as explicit
|
||||
- Merged 209: Use inttypes.h on VC++ 2013 and later
|
||||
- Merged 212: Fix statically linked gflags library with MSVC
|
||||
- Merged 213: Modify installation paths on Windows for vcpkg
|
||||
- Merged 215: Fix static initialization order fiasco caused by global registry lock
|
||||
- Merged 216: Fix use of ARGC in CMake macros
|
||||
- Merged 222: Static code analyzer error regarding strncmp with empty kRootDir
|
||||
- Merged 224: Check HAVE_STDINT_H or HAVE_INTTYPES_H for older MSVC versions
|
||||
|
||||
* Fri Nov 25 2016 - Andreas Schuh <andreas.schuh.84@gmail.com>
|
||||
|
||||
- gflags: version 2.2.0
|
||||
- Merged 178: Implicitly convert dashes in option names to underscores
|
||||
- Merged 159: CI builds and automatic tests with Travis CI and AppVeyor
|
||||
- Merged 158: Use enum for flag value types
|
||||
- Merged 126: File name postfix for static libraries on Windows
|
||||
- Closed issue 120: Configure and install gflags.pc file for pkg-config users
|
||||
- Fixed issue 127: snprintf already defined when building with MSVC 2015
|
||||
- Fixed issue 51/138: Memory leaks reported by valgrind
|
||||
- Fixed issue 173: Validate flags only once
|
||||
- Fixed issue 168: Unsigned and signed comparison in gflags_reporting.cc
|
||||
- Fixed issues 176/153: Add -lpthread link argument to Bazel build, refactor BUILD rules
|
||||
- Fixed issue 89: Add GFLAGS_IS_A_DLL to imported CMake target INTERFACE_COMPILE_DEFINITIONS
|
||||
- Fixed issue 104: Set INTERFACE_INCLUDE_DIRECTORIES of exported CMake targets
|
||||
- Fixed issue 174: Missing gflags-targets.cmake file after installation
|
||||
- Fixed issue 186: Error linking to gflags IMPLIB with MSVC using CMake
|
||||
- Closed issue 106: Add example project to test use of gflags library
|
||||
|
||||
* Tue Mar 24 2014 - Andreas Schuh <andreas.schuh.84@gmail.com>
|
||||
|
||||
- gflags: version 2.1.2
|
||||
|
@ -108,8 +166,8 @@
|
|||
- BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
|
||||
- BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
|
||||
- PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
|
||||
- PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
|
||||
- PORTABILITY: #include more headers to satify new gcc's (csilvers)
|
||||
- PORTABILITY: Update deb.sh for more recently debuilds (csilvers)
|
||||
- PORTABILITY: #include more headers to satisfy new gcc's (csilvers)
|
||||
- INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
|
||||
|
||||
* Fri Oct 3 2008 - Google Inc. <opensource@google.com>
|
||||
|
@ -189,7 +247,7 @@
|
|||
- google-gflags: version 0.5
|
||||
- Include all m4 macros in the distribution (csilvers)
|
||||
- Python: Fix broken data_files field in setup.py (sidlon)
|
||||
- Python: better string serliaizing and unparsing (abo, csimmons)
|
||||
- Python: better string serializing and unparsing (abo, csimmons)
|
||||
- Fix checks for NaN and inf to work with Mac OS X (csilvers)
|
||||
|
||||
* Thu Apr 19 2007 - Google Inc. <opensource@google.com>
|
||||
|
|
73
INSTALL.md
73
INSTALL.md
|
@ -1,18 +1,48 @@
|
|||
Installing a binary distribution package
|
||||
========================================
|
||||
# Installing a binary distribution package
|
||||
|
||||
No official binary distribution packages are provided by the gflags developers.
|
||||
There may, however, be binary packages available for your OS. Please consult
|
||||
also the package repositories of your Linux distribution.
|
||||
There may, however, be binary packages available for your operating system.
|
||||
Please consult also the package repositories of your Linux distribution.
|
||||
|
||||
For example on Debian/Ubuntu Linux, gflags can be installed using the
|
||||
following command:
|
||||
On Debian/Ubuntu Linux, gflags can be installed using the following command:
|
||||
|
||||
sudo apt-get install gflags
|
||||
sudo apt-get install libgflags-dev
|
||||
|
||||
On macOS, [Homebrew](https://brew.sh/) includes a formula for gflags:
|
||||
|
||||
brew install gflags
|
||||
|
||||
|
||||
Compiling the source code
|
||||
=========================
|
||||
# Compiling the source code with Bazel
|
||||
|
||||
To use gflags in a [Bazel](http://bazel.io) project, map it in as an external
|
||||
dependency by editing your WORKSPACE file:
|
||||
|
||||
git_repository(
|
||||
name = "com_github_gflags_gflags",
|
||||
commit = "<INSERT COMMIT SHA HERE>",
|
||||
remote = "https://github.com/gflags/gflags.git",
|
||||
)
|
||||
|
||||
You can then add `@com_github_gflags_gflags//:gflags` to the `deps` section of a
|
||||
`cc_binary` or `cc_library` rule, and `#include <gflags/gflags.h>` to include it
|
||||
in your source code.
|
||||
|
||||
|
||||
# Compiling the source code with vcpkg
|
||||
|
||||
You can download and install gflags using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install gflags
|
||||
|
||||
The gflags port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
|
||||
# Compiling the source code with CMake
|
||||
|
||||
The build system of gflags is since version 2.1 based on [CMake](http://cmake.org).
|
||||
The common steps to build, test, and install software are therefore:
|
||||
|
@ -44,11 +74,24 @@ the name of this package and the obtained version of the software.
|
|||
$ make install (optional)
|
||||
|
||||
In the following, only gflags-specific CMake settings available to
|
||||
configure the build and installation are documented.
|
||||
configure the build and installation are documented. Note that most of these
|
||||
variables are for advanced users and binary package maintainers only.
|
||||
They usually do not have to be modified.
|
||||
|
||||
|
||||
CMake Option | Description
|
||||
---------------------- | -------------------------------------------------------
|
||||
CMAKE_INSTALL_PREFIX | Installation directory, e.g., "/usr/local" on Unix and "C:\Program Files\gflags" on Windows.
|
||||
GFLAGS_NAMESPACE | Name of the C++ namespace to be used by the gflags library. Note that the public source header files are installed in a subdirectory named after this namespace. To maintain backwards compatibility with the Google Commandline Flags, set this variable to "google". The default is "gflags".
|
||||
GFLAGS_INCLUDE_DIR | Name of include subdirectory where headers are installed into.
|
||||
CMake Option | Description
|
||||
--------------------------- | -------------------------------------------------------
|
||||
CMAKE_INSTALL_PREFIX | Installation directory, e.g., "/usr/local" on Unix and "C:\Program Files\gflags" on Windows.
|
||||
BUILD_SHARED_LIBS | Request build of dynamic link libraries.
|
||||
BUILD_STATIC_LIBS | Request build of static link libraries. Implied if BUILD_SHARED_LIBS is OFF.
|
||||
BUILD_PACKAGING | Enable binary package generation using CPack.
|
||||
BUILD_TESTING | Build tests for execution by CTest.
|
||||
BUILD_NC_TESTS | Request inclusion of negative compilation tests (requires Python).
|
||||
BUILD_CONFIG_TESTS | Request inclusion of package configuration tests (requires Python).
|
||||
BUILD_gflags_LIBS | Request build of multi-threaded gflags libraries (if threading library found).
|
||||
BUILD_gflags_nothreads_LIBS | Request build of single-threaded gflags libraries.
|
||||
GFLAGS_NAMESPACE | Name of the C++ namespace to be used by the gflags library. Note that the public source header files are installed in a subdirectory named after this namespace. To maintain backwards compatibility with the Google Commandline Flags, set this variable to "google". The default is "gflags".
|
||||
GFLAGS_INTTYPES_FORMAT | String identifying format of built-in integer types.
|
||||
GFLAGS_INCLUDE_DIR | Name of headers installation directory relative to CMAKE_INSTALL_PREFIX.
|
||||
LIBRARY_INSTALL_DIR | Name of library installation directory relative to CMAKE_INSTALL_PREFIX.
|
||||
INSTALL_HEADERS | Request installation of public header files.
|
||||
|
|
4
MODULE.bazel
Normal file
4
MODULE.bazel
Normal file
|
@ -0,0 +1,4 @@
|
|||
module(
|
||||
name = "gflags",
|
||||
compatibility_level = 1,
|
||||
)
|
76
README.md
76
README.md
|
@ -1,16 +1,72 @@
|
|||
[](https://github.com/gflags/gflags/actions/workflows/test.yml)
|
||||
|
||||
The documentation of the gflags library is available online at https://gflags.github.io/gflags/.
|
||||
|
||||
|
||||
11 November 2018
|
||||
----------------
|
||||
|
||||
I've just released gflags 2.2.2.
|
||||
|
||||
This maintenance release improves life of Bazel users (no more "config.h" leaking into global include paths),
|
||||
fixes build with recent MinGW versions, and silences a number of static code analyzer and compiler warnings.
|
||||
The build targets exported by the CMake configuration of this library are now also prefixed by the package
|
||||
name "gflags::" following a more recent (unwritten) CMake convention. The unprefixed target names are still
|
||||
supported to avoid that dependent projects have to be modified due to this change in imported target names.
|
||||
|
||||
Please report any further issues with this release using the GitHub issue tracker.
|
||||
|
||||
|
||||
11 July 2017
|
||||
------------
|
||||
|
||||
I've just released gflags 2.2.1.
|
||||
|
||||
This maintenance release primarily fixes build issues on Windows and
|
||||
false alarms reported by static code analyzers.
|
||||
|
||||
Please report any further issues with this release using the GitHub issue tracker.
|
||||
|
||||
|
||||
25 November 2016
|
||||
----------------
|
||||
|
||||
I've finally released gflags 2.2.0.
|
||||
|
||||
This release adds support for use of the gflags library as external dependency
|
||||
not only in projects using CMake, but also [Bazel](https://bazel.build/),
|
||||
or [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/).
|
||||
One new minor feature is added in this release: when a command flag argument
|
||||
contains dashes, these are implicitly converted to underscores.
|
||||
This is to allow those used to separate words of the flag name by dashes
|
||||
to do so, while the flag variable names are required to use underscores.
|
||||
|
||||
Memory leaks reported by valgrind should be resolved by this release.
|
||||
This release fixes build errors with MS Visual Studio 2015.
|
||||
|
||||
Please report any further issues with this release using the GitHub issue tracker.
|
||||
|
||||
|
||||
24 March 2015
|
||||
-------------
|
||||
|
||||
Released gflags 2.1.2 with fixes of ABI incompatibilities to 2.0 caused
|
||||
by namespace change. The deprecated "google" namespace is yet kept as primary
|
||||
namespace while sybmols are imported into the new "gflags" namespace by default.
|
||||
This can be configured using GFLAGS_NAMESPACE and GLAGS_INCLUDE_DIR. Problems
|
||||
with the (patched) CMake modules FindThreads.cmake and CheckTypeSize.cmake
|
||||
are resolved by re-enabling the C language again even though gflags is C++.
|
||||
I've just released gflags 2.1.2.
|
||||
|
||||
Finalized move of gflags project from Google Code to GitHub.
|
||||
Email addresses of original issue reporters got lost in the process.
|
||||
Given the age of most issue reports, this should be neglibable.
|
||||
This release completes the namespace change fixes. In particular,
|
||||
it restores binary ABI compatibility with release version 2.0.
|
||||
The deprecated "google" namespace is by default still kept as
|
||||
primary namespace while symbols are imported into the new "gflags" namespace.
|
||||
This can be overridden using the CMake variable GFLAGS_NAMESPACE.
|
||||
|
||||
Other fixes of the build configuration are related to the (patched)
|
||||
CMake modules FindThreads.cmake and CheckTypeSize.cmake. These have
|
||||
been removed and instead the C language is enabled again even though
|
||||
gflags is written in C++ only.
|
||||
|
||||
This release also marks the complete move of the gflags project
|
||||
from Google Code to GitHub. Email addresses of original issue
|
||||
reporters got lost in the process. Given the age of most issue reports,
|
||||
this should be negligible.
|
||||
|
||||
Please report any further issues using the GitHub issue tracker.
|
||||
|
||||
|
@ -57,7 +113,7 @@ prefixed by "bugfix/", respectively.
|
|||
Binary and source [packages](https://github.com/schuhschuh/gflags/releases) are available on GitHub.
|
||||
|
||||
|
||||
14 January 2013
|
||||
14 January 2014
|
||||
---------------
|
||||
|
||||
The migration of the build system to CMake is almost complete.
|
||||
|
|
6
WORKSPACE
Normal file
6
WORKSPACE
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright 2006 Google Inc. All Rights Reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the COPYING.txt file.
|
||||
|
||||
# Bazel (http://bazel.io/) WORKSPACE file for gflags.
|
||||
workspace(name="com_github_gflags_gflags")
|
5
bazel/expanded_template/BUILD
Normal file
5
bazel/expanded_template/BUILD
Normal file
|
@ -0,0 +1,5 @@
|
|||
cc_binary(
|
||||
name = "expand_template",
|
||||
srcs = ["expand_template.cc"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
63
bazel/expanded_template/expand_template.cc
Normal file
63
bazel/expanded_template/expand_template.cc
Normal file
|
@ -0,0 +1,63 @@
|
|||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
struct Substitution {
|
||||
std::basic_regex<char> regex;
|
||||
std::string replacement;
|
||||
};
|
||||
|
||||
// Simple app that does a regex search-and-replace on a template
|
||||
// and outputs the result.
|
||||
//
|
||||
// To invoke:
|
||||
// expand_template
|
||||
// --template PATH
|
||||
// --output PATH
|
||||
// regex0;replacement0
|
||||
// regex1;replacement1
|
||||
// ...
|
||||
//
|
||||
// Since it's only used as a private implementation detail of a rule and not
|
||||
// user invoked we don't bother with error checking.
|
||||
int main(int argc, const char** argv) {
|
||||
// Parse args.
|
||||
const char* template_path = nullptr;
|
||||
const char* output_path = nullptr;
|
||||
std::vector<Substitution> substitutions;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
const char* arg = argv[i];
|
||||
if (strcmp(arg, "--template") == 0) {
|
||||
template_path = argv[++i];
|
||||
} else if (strcmp(arg, "--output") == 0) {
|
||||
output_path = argv[++i];
|
||||
} else {
|
||||
const char* mid = strchr(arg, ';');
|
||||
if (mid != nullptr) {
|
||||
substitutions.push_back(Substitution{
|
||||
std::basic_regex<char>(arg, mid - arg),
|
||||
std::string(mid + 1),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read template.
|
||||
std::ifstream ifs(template_path);
|
||||
std::string str(std::istreambuf_iterator<char>(ifs),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
|
||||
// Apply regexes.
|
||||
for (const auto& subst : substitutions) {
|
||||
str = std::regex_replace(str, subst.regex, subst.replacement);
|
||||
}
|
||||
|
||||
// Output file.
|
||||
std::ofstream file(output_path);
|
||||
file << str;
|
||||
|
||||
return 0;
|
||||
}
|
35
bazel/expanded_template/expanded_template.bzl
Normal file
35
bazel/expanded_template/expanded_template.bzl
Normal file
|
@ -0,0 +1,35 @@
|
|||
def _impl(ctx):
|
||||
args = ctx.actions.args()
|
||||
args.add("--template", ctx.file.template)
|
||||
args.add("--output", ctx.outputs.out)
|
||||
args.add_all([k + ';' + v for k, v in ctx.attr.substitutions.items()])
|
||||
ctx.actions.run(
|
||||
executable = ctx.executable._bin,
|
||||
arguments = [args],
|
||||
inputs = [ctx.file.template],
|
||||
outputs = [ctx.outputs.out],
|
||||
)
|
||||
return [
|
||||
DefaultInfo(
|
||||
files = depset(direct = [ctx.outputs.out]),
|
||||
runfiles = ctx.runfiles(files = [ctx.outputs.out]),
|
||||
),
|
||||
]
|
||||
|
||||
expanded_template = rule(
|
||||
implementation = _impl,
|
||||
attrs = {
|
||||
"out": attr.output(mandatory = True),
|
||||
"template": attr.label(
|
||||
allow_single_file = True,
|
||||
mandatory = True,
|
||||
),
|
||||
"substitutions": attr.string_dict(),
|
||||
"_bin": attr.label(
|
||||
default = "//bazel/expanded_template:expand_template",
|
||||
executable = True,
|
||||
allow_single_file = True,
|
||||
cfg = "host",
|
||||
),
|
||||
},
|
||||
)
|
108
bazel/gflags.bzl
Normal file
108
bazel/gflags.bzl
Normal file
|
@ -0,0 +1,108 @@
|
|||
load("//bazel/expanded_template:expanded_template.bzl", "expanded_template")
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Add native rules to configure source files
|
||||
def gflags_sources(namespace = ["google", "gflags"]):
|
||||
expanded_template(
|
||||
name = "gflags_declare_h",
|
||||
template = "src/gflags_declare.h.in",
|
||||
out = "gflags_declare.h",
|
||||
substitutions = {
|
||||
"@GFLAGS_NAMESPACE@": namespace[0],
|
||||
"@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@": "1",
|
||||
"@([A-Z0-9_]+)@": "0",
|
||||
},
|
||||
)
|
||||
gflags_ns_h_files = []
|
||||
for ns in namespace[1:]:
|
||||
gflags_ns_h_file = "gflags_{}.h".format(ns)
|
||||
expanded_template(
|
||||
name = gflags_ns_h_file.replace(".", "_"),
|
||||
template = "src/gflags_ns.h.in",
|
||||
out = gflags_ns_h_file,
|
||||
substitutions = {
|
||||
"@ns@": ns,
|
||||
"@NS@": ns.upper(),
|
||||
},
|
||||
)
|
||||
gflags_ns_h_files.append(gflags_ns_h_file)
|
||||
expanded_template(
|
||||
name = "gflags_h",
|
||||
template = "src/gflags.h.in",
|
||||
out = "gflags.h",
|
||||
substitutions = {
|
||||
"@GFLAGS_ATTRIBUTE_UNUSED@": "",
|
||||
"@INCLUDE_GFLAGS_NS_H@": "\n".join(["#include \"gflags/{}\"".format(hdr) for hdr in gflags_ns_h_files]),
|
||||
},
|
||||
)
|
||||
expanded_template(
|
||||
name = "gflags_completions_h",
|
||||
template = "src/gflags_completions.h.in",
|
||||
out = "gflags_completions.h",
|
||||
substitutions = {
|
||||
"@GFLAGS_NAMESPACE@": namespace[0],
|
||||
},
|
||||
)
|
||||
hdrs = [":gflags_h", ":gflags_declare_h", ":gflags_completions_h"]
|
||||
hdrs.extend([":" + hdr.replace(".", "_") for hdr in gflags_ns_h_files])
|
||||
srcs = [
|
||||
"src/config.h",
|
||||
"src/gflags.cc",
|
||||
"src/gflags_completions.cc",
|
||||
"src/gflags_reporting.cc",
|
||||
"src/mutex.h",
|
||||
"src/util.h",
|
||||
] + select({
|
||||
"//:x64_windows": [
|
||||
"src/windows_port.cc",
|
||||
"src/windows_port.h",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
return [hdrs, srcs]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Add native rule to build gflags library
|
||||
def gflags_library(hdrs = [], srcs = [], threads = 1):
|
||||
name = "gflags"
|
||||
copts = [
|
||||
"-DGFLAGS_BAZEL_BUILD",
|
||||
"-DGFLAGS_INTTYPES_FORMAT_C99",
|
||||
"-DGFLAGS_IS_A_DLL=0",
|
||||
# macros otherwise defined by CMake configured defines.h file
|
||||
"-DHAVE_STDINT_H",
|
||||
"-DHAVE_SYS_TYPES_H",
|
||||
"-DHAVE_INTTYPES_H",
|
||||
"-DHAVE_SYS_STAT_H",
|
||||
"-DHAVE_STRTOLL",
|
||||
"-DHAVE_STRTOQ",
|
||||
"-DHAVE_RWLOCK",
|
||||
] + select({
|
||||
"//:x64_windows": [
|
||||
"-DOS_WINDOWS",
|
||||
],
|
||||
"//conditions:default": [
|
||||
"-DHAVE_UNISTD_H",
|
||||
"-DHAVE_FNMATCH_H",
|
||||
"-DHAVE_PTHREAD",
|
||||
],
|
||||
})
|
||||
linkopts = []
|
||||
if threads:
|
||||
linkopts += select({
|
||||
"//:android": [],
|
||||
"//:x64_windows": [],
|
||||
"//conditions:default": ["-lpthread"],
|
||||
})
|
||||
else:
|
||||
name += "_nothreads"
|
||||
copts += ["-DNO_THREADS"]
|
||||
native.cc_library(
|
||||
name = name,
|
||||
hdrs = hdrs,
|
||||
srcs = srcs,
|
||||
copts = copts,
|
||||
linkopts = linkopts,
|
||||
visibility = ["//visibility:public"],
|
||||
include_prefix = "gflags",
|
||||
)
|
26
cmake/cmake_uninstall.cmake.in
Normal file
26
cmake/cmake_uninstall.cmake.in
Normal file
|
@ -0,0 +1,26 @@
|
|||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
if (NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
|
||||
endif ()
|
||||
message(${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
|
@ -1,23 +1,183 @@
|
|||
## gflags CMake configuration file
|
||||
|
||||
# library version information
|
||||
set (@PACKAGE_NAME@_VERSION_STRING "@PACKAGE_VERSION@")
|
||||
set (@PACKAGE_NAME@_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@)
|
||||
set (@PACKAGE_NAME@_VERSION_MINOR @PACKAGE_VERSION_MINOR@)
|
||||
set (@PACKAGE_NAME@_VERSION_PATCH @PACKAGE_VERSION_PATCH@)
|
||||
set (@PACKAGE_PREFIX@_VERSION_STRING "@PACKAGE_VERSION@")
|
||||
set (@PACKAGE_PREFIX@_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@)
|
||||
set (@PACKAGE_PREFIX@_VERSION_MINOR @PACKAGE_VERSION_MINOR@)
|
||||
set (@PACKAGE_PREFIX@_VERSION_PATCH @PACKAGE_VERSION_PATCH@)
|
||||
|
||||
# import targets
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-export.cmake")
|
||||
if (NOT DEFINED @PACKAGE_PREFIX@_USE_TARGET_NAMESPACE)
|
||||
set (@PACKAGE_PREFIX@_USE_TARGET_NAMESPACE FALSE)
|
||||
endif ()
|
||||
if (@PACKAGE_PREFIX@_USE_TARGET_NAMESPACE)
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/@EXPORT_NAME@.cmake")
|
||||
set (@PACKAGE_PREFIX@_TARGET_NAMESPACE @PACKAGE_NAME@)
|
||||
else ()
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-nonamespace-targets.cmake")
|
||||
set (@PACKAGE_PREFIX@_TARGET_NAMESPACE)
|
||||
endif ()
|
||||
if (@PACKAGE_PREFIX@_TARGET_NAMESPACE)
|
||||
set (@PACKAGE_PREFIX@_TARGET_PREFIX ${@PACKAGE_PREFIX@_TARGET_NAMESPACE}::)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_TARGET_PREFIX)
|
||||
endif ()
|
||||
|
||||
# installation prefix
|
||||
get_filename_component (CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
get_filename_component (_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PREFIX_REL2CONFIG_DIR@" ABSOLUTE)
|
||||
|
||||
# include directory
|
||||
set (@PACKAGE_NAME@_INCLUDE_DIR "${_INSTALL_PREFIX}/@INCLUDE_INSTALL_DIR@")
|
||||
#
|
||||
# Newer versions of CMake set the INTERFACE_INCLUDE_DIRECTORIES property
|
||||
# of the imported targets. It is hence not necessary to add this path
|
||||
# manually to the include search path for targets which link to gflags.
|
||||
set (@PACKAGE_PREFIX@_INCLUDE_DIR "${_INSTALL_PREFIX}/@INCLUDE_INSTALL_DIR@")
|
||||
|
||||
# gflags library
|
||||
set (@PACKAGE_NAME@_LIBRARIES gflags)
|
||||
if (@PACKAGE_NAME@_FIND_COMPONENTS)
|
||||
foreach (@PACKAGE_NAME@_FIND_COMPONENT IN LISTS @PACKAGE_NAME@_FIND_COMPONENTS)
|
||||
if (@PACKAGE_NAME@_FIND_REQUIRED_${@PACKAGE_NAME@_FIND_COMPONENT} AND NOT TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_${@PACKAGE_NAME@_FIND_COMPONENT})
|
||||
message (FATAL_ERROR "Package @PACKAGE_NAME@ was installed without required component ${@PACKAGE_PREFIX@_TARGET_PREFIX}${@PACKAGE_NAME@_FIND_COMPONENT}!")
|
||||
endif ()
|
||||
endforeach ()
|
||||
list (GET @PACKAGE_NAME@_FIND_COMPONENTS 0 @PACKAGE_NAME@_FIND_COMPONENT)
|
||||
else ()
|
||||
set (@PACKAGE_NAME@_FIND_COMPONENT)
|
||||
endif ()
|
||||
|
||||
# default settings of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS
|
||||
#
|
||||
# It is recommended to use either one of the following find_package commands
|
||||
# instead of setting the @PACKAGE_PREFIX@_(SHARED|NOTHREADS) variables:
|
||||
# - find_package(@PACKAGE_NAME@ REQUIRED)
|
||||
# - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_static)
|
||||
# - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_shared)
|
||||
# - find_package(@PACKAGE_NAME@ COMPONENTS static)
|
||||
# - find_package(@PACKAGE_NAME@ COMPONENTS shared)
|
||||
if (NOT DEFINED @PACKAGE_PREFIX@_SHARED)
|
||||
if (DEFINED @PACKAGE_NAME@_SHARED)
|
||||
set (@PACKAGE_PREFIX@_SHARED ${@PACKAGE_NAME@_SHARED})
|
||||
elseif (@PACKAGE_NAME@_FIND_COMPONENT)
|
||||
if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "shared")
|
||||
set (@PACKAGE_PREFIX@_SHARED TRUE)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_SHARED FALSE)
|
||||
endif ()
|
||||
elseif (TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared OR TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_shared)
|
||||
set (@PACKAGE_PREFIX@_SHARED TRUE)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_SHARED FALSE)
|
||||
endif ()
|
||||
endif ()
|
||||
if (NOT DEFINED @PACKAGE_PREFIX@_NOTHREADS)
|
||||
if (DEFINED @PACKAGE_NAME@_NOTHREADS)
|
||||
set (@PACKAGE_PREFIX@_NOTHREADS ${@PACKAGE_NAME@_NOTHREADS})
|
||||
elseif (@PACKAGE_NAME@_FIND_COMPONENT)
|
||||
if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "nothreads")
|
||||
set (@PACKAGE_PREFIX@_NOTHREADS TRUE)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_NOTHREADS FALSE)
|
||||
endif ()
|
||||
elseif (TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_static OR TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared)
|
||||
set (@PACKAGE_PREFIX@_NOTHREADS FALSE)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_NOTHREADS TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# choose imported library target
|
||||
if (NOT @PACKAGE_PREFIX@_TARGET)
|
||||
if (@PACKAGE_NAME@_TARGET)
|
||||
set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_NAME@_TARGET})
|
||||
elseif (@PACKAGE_PREFIX@_SHARED)
|
||||
if (@PACKAGE_PREFIX@_NOTHREADS)
|
||||
set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_shared)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared)
|
||||
endif ()
|
||||
else ()
|
||||
if (@PACKAGE_PREFIX@_NOTHREADS)
|
||||
set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_static)
|
||||
else ()
|
||||
set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_static)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
if (NOT TARGET ${@PACKAGE_PREFIX@_TARGET})
|
||||
message (FATAL_ERROR "Your @PACKAGE_NAME@ installation does not contain a ${@PACKAGE_PREFIX@_TARGET} library target!"
|
||||
" Try a different combination of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS.")
|
||||
endif ()
|
||||
|
||||
# add more convenient "${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@" import target
|
||||
if (NOT TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@)
|
||||
if (@PACKAGE_PREFIX@_SHARED)
|
||||
add_library (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ SHARED IMPORTED)
|
||||
else ()
|
||||
add_library (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ STATIC IMPORTED)
|
||||
endif ()
|
||||
# copy INTERFACE_* properties
|
||||
foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS
|
||||
COMPILE_DEFINITIONS
|
||||
COMPILE_FEATURES
|
||||
COMPILE_OPTIONS
|
||||
INCLUDE_DIRECTORIES
|
||||
LINK_LIBRARIES
|
||||
POSITION_INDEPENDENT_CODE
|
||||
)
|
||||
get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME})
|
||||
if (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
|
||||
set_target_properties(${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES
|
||||
INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}"
|
||||
)
|
||||
endif ()
|
||||
endforeach ()
|
||||
# copy IMPORTED_*_<CONFIG> properties
|
||||
get_target_property (_@PACKAGE_PREFIX@_CONFIGURATIONS ${@PACKAGE_PREFIX@_TARGET} IMPORTED_CONFIGURATIONS)
|
||||
set_target_properties (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES IMPORTED_CONFIGURATIONS "${_@PACKAGE_PREFIX@_CONFIGURATIONS}")
|
||||
foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS
|
||||
IMPLIB
|
||||
LOCATION
|
||||
LINK_DEPENDENT_LIBRARIES
|
||||
LINK_INTERFACE_LIBRARIES
|
||||
LINK_INTERFACE_LANGUAGES
|
||||
LINK_INTERFACE_MULTIPLICITY
|
||||
NO_SONAME
|
||||
SONAME
|
||||
)
|
||||
foreach (_@PACKAGE_PREFIX@_CONFIG IN LISTS _@PACKAGE_PREFIX@_CONFIGURATIONS)
|
||||
get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG})
|
||||
if (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
|
||||
set_target_properties(${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES
|
||||
IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}"
|
||||
)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endforeach ()
|
||||
unset (_@PACKAGE_PREFIX@_CONFIGURATIONS)
|
||||
unset (_@PACKAGE_PREFIX@_CONFIG)
|
||||
unset (_@PACKAGE_PREFIX@_PROPERTY_NAME)
|
||||
unset (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
|
||||
endif ()
|
||||
|
||||
# alias for default import target to be compatible with older CMake package configurations
|
||||
set (@PACKAGE_PREFIX@_LIBRARIES "${@PACKAGE_PREFIX@_TARGET}")
|
||||
|
||||
# set @PACKAGE_NAME@_* variables for backwards compatibility
|
||||
if (NOT "^@PACKAGE_NAME@$" STREQUAL "^@PACKAGE_PREFIX@$")
|
||||
foreach (_@PACKAGE_PREFIX@_VARIABLE IN ITEMS
|
||||
VERSION_STRING
|
||||
VERSION_MAJOR
|
||||
VERSION_MINOR
|
||||
VERSION_PATCH
|
||||
INCLUDE_DIR
|
||||
LIBRARIES
|
||||
TARGET
|
||||
)
|
||||
set (@PACKAGE_NAME@_${_@PACKAGE_PREFIX@_VARIABLE} "${@PACKAGE_PREFIX@_${_@PACKAGE_PREFIX@_VARIABLE}}")
|
||||
endforeach ()
|
||||
unset (_@PACKAGE_PREFIX@_VARIABLE)
|
||||
endif ()
|
||||
|
||||
# unset private variables
|
||||
unset (@PACKAGE_NAME@_FIND_COMPONENT)
|
||||
unset (_INSTALL_PREFIX)
|
||||
|
|
14
cmake/package.pc.in
Normal file
14
cmake/package.pc.in
Normal file
|
@ -0,0 +1,14 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
bindir=${exec_prefix}/@RUNTIME_INSTALL_DIR@
|
||||
libdir=${exec_prefix}/@LIBRARY_INSTALL_DIR@
|
||||
includedir=${prefix}/@INCLUDE_INSTALL_DIR@
|
||||
|
||||
Name: @PACKAGE_NAME@
|
||||
Version: @PACKAGE_VERSION@
|
||||
Description: @PACKAGE_DESCRIPTION@
|
||||
URL: @PACKAGE_URL@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lgflags
|
||||
Libs.private: -lpthread
|
||||
Cflags: -I${includedir}
|
|
@ -11,7 +11,7 @@ macro (bool_to_int VAR)
|
|||
endmacro ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Extract version numbers from version string.
|
||||
## Extract version numbers from version string
|
||||
function (version_numbers version major minor patch)
|
||||
if (version MATCHES "([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(rc[1-9][0-9]*|[a-z]+)?")
|
||||
if (CMAKE_MATCH_1)
|
||||
|
@ -41,6 +41,79 @@ function (version_numbers version major minor patch)
|
|||
set ("${patch}" "${_patch}" PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Determine if cache entry exists
|
||||
macro (gflags_is_cached retvar varname)
|
||||
if (DEFINED ${varname})
|
||||
get_property (${retvar} CACHE ${varname} PROPERTY TYPE SET)
|
||||
else ()
|
||||
set (${retvar} FALSE)
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Add gflags configuration variable
|
||||
#
|
||||
# The default value of the (cached) configuration value can be overridden either
|
||||
# on the CMake command-line or the super-project by setting the GFLAGS_<varname>
|
||||
# variable. When gflags is a subproject of another project (GFLAGS_IS_SUBPROJECT),
|
||||
# the variable is not added to the CMake cache. Otherwise it is cached.
|
||||
macro (gflags_define type varname docstring default)
|
||||
# note that ARGC must be expanded here, as it is not a "real" variable
|
||||
# (see the CMake documentation for the macro command)
|
||||
if ("${ARGC}" GREATER 5)
|
||||
message (FATAL_ERROR "gflags_variable: Too many macro arguments")
|
||||
endif ()
|
||||
if (NOT DEFINED GFLAGS_${varname})
|
||||
if (DEFINED ${varname})
|
||||
set (GFLAGS_${varname} "${${varname}}")
|
||||
else ()
|
||||
if (GFLAGS_IS_SUBPROJECT AND "${ARGC}" EQUAL 5)
|
||||
set (GFLAGS_${varname} "${ARGV4}")
|
||||
else ()
|
||||
set (GFLAGS_${varname} "${default}")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
if (GFLAGS_IS_SUBPROJECT)
|
||||
set (${varname} "${GFLAGS_${varname}}")
|
||||
else ()
|
||||
set (${varname} "${GFLAGS_${varname}}" CACHE ${type} "${docstring}")
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Set property of cached gflags configuration variable
|
||||
macro (gflags_property varname property value)
|
||||
gflags_is_cached (_cached ${varname})
|
||||
if (_cached)
|
||||
# note that property must be expanded here, as it is not a "real" variable
|
||||
# (see the CMake documentation for the macro command)
|
||||
if ("${property}" STREQUAL "ADVANCED")
|
||||
if (${value})
|
||||
mark_as_advanced (FORCE ${varname})
|
||||
else ()
|
||||
mark_as_advanced (CLEAR ${varname})
|
||||
endif ()
|
||||
else ()
|
||||
set_property (CACHE ${varname} PROPERTY "${property}" "${value}")
|
||||
endif ()
|
||||
endif ()
|
||||
unset (_cached)
|
||||
endmacro ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Modify value of gflags configuration variable
|
||||
macro (gflags_set varname value)
|
||||
gflags_is_cached (_cached ${varname})
|
||||
if (_cached)
|
||||
set_property (CACHE ${varname} PROPERTY VALUE "${value}")
|
||||
else ()
|
||||
set (${varname} "${value}")
|
||||
endif ()
|
||||
unset (_cached)
|
||||
endmacro ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
## Configure public header files
|
||||
function (configure_headers out)
|
||||
|
@ -94,3 +167,41 @@ macro (add_gflags_test name expected_rc expected_output unexpected_output cmd)
|
|||
WORKING_DIRECTORY "${GFLAGS_FLAGFILES_DIR}"
|
||||
)
|
||||
endmacro ()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
## Register installed package with CMake
|
||||
#
|
||||
# This function adds an entry to the CMake registry for packages with the
|
||||
# path of the directory where the package configuration file of the installed
|
||||
# package is located in order to help CMake find the package in a custom
|
||||
# installation prefix. This differs from CMake's export(PACKAGE) command
|
||||
# which registers the build directory instead.
|
||||
function (register_gflags_package CONFIG_DIR)
|
||||
if (NOT IS_ABSOLUTE "${CONFIG_DIR}")
|
||||
set (CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}")
|
||||
endif ()
|
||||
string (MD5 REGISTRY_ENTRY "${CONFIG_DIR}")
|
||||
if (WIN32)
|
||||
install (CODE
|
||||
"execute_process (
|
||||
COMMAND reg add \"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\" /v \"${REGISTRY_ENTRY}\" /d \"${CONFIG_DIR}\" /t REG_SZ /f
|
||||
RESULT_VARIABLE RT
|
||||
ERROR_VARIABLE ERR
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
if (RT EQUAL 0)
|
||||
message (STATUS \"Register: Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\\\\${REGISTRY_ENTRY}\")
|
||||
else ()
|
||||
string (STRIP \"\${ERR}\" ERR)
|
||||
message (STATUS \"Register: Failed to add registry entry: \${ERR}\")
|
||||
endif ()"
|
||||
)
|
||||
elseif (IS_DIRECTORY "$ENV{HOME}")
|
||||
file (WRITE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" "${CONFIG_DIR}")
|
||||
install (
|
||||
FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry"
|
||||
DESTINATION "$ENV{HOME}/.cmake/packages/${PACKAGE_NAME}"
|
||||
RENAME "${REGISTRY_ENTRY}"
|
||||
)
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
|
0
doc/.nojekyll
Normal file
0
doc/.nojekyll
Normal file
4
doc/README.md
Normal file
4
doc/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
To update the GitHub Pages at http://gflags.github.io/gflags/, use command:
|
||||
```
|
||||
git subtree push --prefix=doc/ origin gh-pages
|
||||
```
|
112
doc/index.html
112
doc/index.html
|
@ -38,17 +38,20 @@
|
|||
<blockquote><dl>
|
||||
<dt> Table of contents </dt>
|
||||
<dd> <a href="#intro">Introduction</a> </dd>
|
||||
<dd> <a href="#cmake">Finding and Linking to gflags using CMake</a></dd>
|
||||
<dd> <a href="#download">Download and Installation</a> </dd>
|
||||
<dd> <a href="#cmake">Declare dependency on gflags with CMake</a></dd>
|
||||
<dd> <a href="#bazel">Declare dependency on gflags with Bazel</a></dd>
|
||||
<dd> <a href="#define">DEFINE: Defining Flags In Program</A> </dd>
|
||||
<dd> <a href="#using">Accessing the Flag</A> </dd>
|
||||
<dd> <a href="#declare">DECLARE: Using the Flag in a Different File</a> </dd>
|
||||
<dd> <a href="#validate">RegisterFlagValidator: Sanity-checking Flag Values</a> </dd>
|
||||
<dd> <a href="#together">Putting It Together: How to Set Up Flags</a> </dd>
|
||||
<dd> <a href="#commandline">Setting Flags on the Command Line</a> </dd>
|
||||
<dd> <a href="#varz">Setting Flags at Runtime</a> </dd>
|
||||
<dd> <a href="#default">Changing the Default Flag Value</a> </dd>
|
||||
<dd> <a href="#special">Special Flags</a> </dd>
|
||||
<dd> <a href="#api">The API</a> </dd>
|
||||
<dd> <a href="#misc">Miscellaneous Notes</a> </dd>
|
||||
<dd> <a href="#issues">Issues and Feature Requests</a> </dd>
|
||||
<dd> <br/> </dd>
|
||||
</dl></blockquote>
|
||||
|
||||
|
@ -91,16 +94,86 @@ library. It's a C++ library, so examples are in C++. However, there
|
|||
is a Python port with the same functionality, and this discussion
|
||||
translates directly to Python.</p>
|
||||
|
||||
<h2> <A name=cmake>Finding and Linking to gflags </A> using CMake</h2>
|
||||
<h2> <A NAME=download>Download and Installation</A> </h2>
|
||||
|
||||
<p> Using gflags within a project which uses <A href="http://www.cmake.org">CMake</A> for its build system is easy. Therefore, simply add the following CMake code to your <code>CMakeLists.txt</code> file.
|
||||
<p>The gflags library can be downloaded from <A href="https://github.com/gflags/gflags">GitHub</A>.
|
||||
You can clone the project using the command:</p>
|
||||
<pre>
|
||||
git clone https://github.com/gflags/gflags.git
|
||||
</pre>
|
||||
<p>Build and installation instructions are provided in the
|
||||
<A href="https://github.com/gflags/gflags/blob/master/INSTALL.md">INSTALL</A> file.
|
||||
The installation of the gflags package includes configuration files for popular build systems
|
||||
such as <A href="https://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</A>,
|
||||
<A href="#cmake">CMake</A>, and <A href="#bazel">Bazel</A>.</p>
|
||||
|
||||
|
||||
<h2> <A name=cmake>Declare dependency on gflags with CMake</A></h2>
|
||||
|
||||
<p>Using gflags within a project which uses <A href="http://www.cmake.org">CMake</A> for its build system is easy.
|
||||
You can either require an external installation of the gflags package and find it using CMake's find_package
|
||||
command, or include the gflags project as subtree or submodule within your project's source tree and add the directory
|
||||
using CMake's add_subdirectory command.
|
||||
|
||||
<p>To use an external gflags installation, add the following CMake code to your <code>CMakeLists.txt</code> file.</p>
|
||||
|
||||
<p>Find gflags installation. The <code>gflags_DIR</code> variable must be set to the <prefix>/lib/cmake/gflags directory
|
||||
containing the gflags-config.cmake file if <prefix> is a non-standard location. Otherwise, CMake should find
|
||||
the gflags installation automatically.</p>
|
||||
<pre>
|
||||
find_package(gflags REQUIRED)
|
||||
</pre>
|
||||
<p>To request a particular imported gflags library target to link against, use the <code>COMPONENTS</code> option of
|
||||
the find_package command. For example, to force the use of the single-threaded static library, use the command</p>
|
||||
<pre>
|
||||
find_package(gflags COMPONENTS nothreads_static)
|
||||
</pre>
|
||||
<p>Note that this will raise a fatal error when the installed gflags package does not contain the requested library.
|
||||
It is therefore recommended to only specify the particular component to look for if a specific library must be used.
|
||||
Otherwise, the gflags-config.cmake module will choose a suitable and available library for you. By default, the
|
||||
multi-threaded gflags library with shared linkage is chosen if available.</p>
|
||||
|
||||
<p>When the source tree of the gflags project is included as subtree or submodule in the "gflags" directory of your project,
|
||||
replace the above find_package command by <code>add_subdirectory(gflags)</code>. See the top of the <code>gflags/CMakeLists.txt</code>
|
||||
file for a listing of available CMake variables that can be set before this command to configure the build of the
|
||||
gflags library. The default build settings are the build of a single-threaded static library which does not require
|
||||
any installation of the gflags subproject products.</p>
|
||||
|
||||
<p>Finally, add your executable build target which uses gflags to parse the command arguments with dependency on the
|
||||
imported gflags library target:</p>
|
||||
<pre>
|
||||
add_executable(foo main.cc)
|
||||
target_link_libraries(foo gflags::gflags)
|
||||
</pre>
|
||||
|
||||
<h2> <A name=bazel>Declare dependency on gflags with Bazel</A></h2>
|
||||
|
||||
<p>To use gflags within a project which uses <A href="https://bazel.build/">Bazel</A> as build tool,
|
||||
add the following lines to your <code>WORKSPACE</code> file
|
||||
(see also Bazel documentation of <A href="https://www.bazel.io/versions/master/docs/be/workspace.html#git_repository">git_repository</A>):
|
||||
|
||||
<pre>
|
||||
find_package (gflags REQUIRED)
|
||||
include_directories (${gflags_INCLUDE_DIR})
|
||||
|
||||
add_executable (foo main.cc)
|
||||
target_link_libraries (foo gflags)
|
||||
git_repository(
|
||||
name = "com_github_gflags_gflags",
|
||||
remote = "https://github.com/gflags/gflags.git",
|
||||
tag = "v2.2.2"
|
||||
)
|
||||
</pre>
|
||||
|
||||
<p>You can then add <code>@com_github_gflags_gflags//:gflags</code> to the <code>deps</code> section of a
|
||||
<code>cc_binary</code> or <code>cc_library</code> rule, and <code>#include "gflags/gflags.h"</code> to
|
||||
include it in your source code. This uses the shared gflags library with multi-threading enabled.
|
||||
In order to use the single-threaded shared gflags library, use the dependency
|
||||
<code>@com_github_gflags_gflags//:gflags_nothreads</code> instead.</p>
|
||||
|
||||
<p>For example, see the following <code>BUILD</code> rule of the gflags/example project:</p>
|
||||
|
||||
<pre>
|
||||
cc_binary(
|
||||
name = "foo",
|
||||
srcs = ["main.cc"],
|
||||
deps = ["@com_github_gflags_gflags//:gflags"],
|
||||
)
|
||||
</pre>
|
||||
|
||||
<h2> <A name=define>DEFINE: Defining Flags In Program</A> </h2>
|
||||
|
@ -246,17 +319,20 @@ static bool ValidatePort(const char* flagname, int32 value) {
|
|||
return false;
|
||||
}
|
||||
DEFINE_int32(port, 0, "What port to listen on");
|
||||
static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
|
||||
DEFINE_validator(port, &ValidatePort);
|
||||
</pre>
|
||||
|
||||
<p>By doing the registration at global initialization time (right
|
||||
after the DEFINE), we ensure that the registration happens before
|
||||
after the DEFINE_int32), we ensure that the registration happens before
|
||||
the commandline is parsed at the beginning of <code>main()</code>.</p>
|
||||
|
||||
<p><code>RegisterFlagValidator()</code> returns true if the
|
||||
registration is successful. It return false if the registration fails
|
||||
<p>The above used <code>DEFINE_validator</code> macro calls the
|
||||
<code>RegisterFlagValidator()</code> function which returns true if the
|
||||
registration is successful. It returns false if the registration fails
|
||||
because a) the first argument does not refer to a commandline flag, or
|
||||
b) a different validator has already been registered for this flag.</p>
|
||||
b) a different validator has already been registered for this flag.
|
||||
The return value is available as global static boolean variable named
|
||||
<code><flag>_validator_registered</code>.</p>
|
||||
|
||||
|
||||
<h2> <A name=together>Putting It Together: How to Set Up Flags</A> </h2>
|
||||
|
@ -393,7 +469,7 @@ the application to print some information about itself and exit.</p>
|
|||
<td>shows all flags from all files, sorted by file and then by name;
|
||||
shows the flagname, its default value, and its help string</td>
|
||||
</tr><tr valign=top>
|
||||
<td><code>--helpfull</code></td>
|
||||
<td><code>--helpful</code></td>
|
||||
<td>same as -help, but unambiguously asks for all flags
|
||||
(in case -help changes in the future)</td>
|
||||
</tr><tr valign=top>
|
||||
|
@ -466,7 +542,7 @@ the application.</p>
|
|||
<p>Note it is still an error to say <code>--tryfromenv=foo</code> if
|
||||
<code>foo</code> is not DEFINED somewhere in the application.</p>
|
||||
|
||||
<h3> <code>--flagfile</code> </h3>
|
||||
<h3 id="flagfiles"> <code>--flagfile</code> </h3>
|
||||
|
||||
<p><code>--flagfile=f</code> tells the commandlineflags module to read
|
||||
the file <code>f</code>, and to run all the flag-assignments found in
|
||||
|
@ -544,6 +620,10 @@ methods such as <code>gflags::SetUsageMessage()</code> and
|
|||
reduce the size of the resulting binary somewhat, and may also be
|
||||
useful for security reasons.</p>
|
||||
|
||||
<h2> <A name="issues">Issues and Feature Requests</code> </h2>
|
||||
|
||||
<p>Please report any issues or ideas for additional features on <A href="https://github.com/gflags/gflags/issues">GitHub</A>.
|
||||
We would also like to encourage <A href="https://github.com/gflags/gflags/pulls">pull requests</A> for bug fixes and implementations of new features.</p>
|
||||
|
||||
<hr>
|
||||
<address>
|
||||
|
|
59
src/config.h
Normal file
59
src/config.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Note: This header file is only used internally. It is not part of public interface!
|
||||
|
||||
#ifndef GFLAGS_CONFIG_H_
|
||||
#define GFLAGS_CONFIG_H_
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// System checks
|
||||
|
||||
// CMake build configuration is written to defines.h file, unused by Bazel build
|
||||
#if !defined(GFLAGS_BAZEL_BUILD)
|
||||
# include "defines.h"
|
||||
#endif
|
||||
|
||||
// gcc requires this to get PRId64, etc.
|
||||
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
|
||||
# define __STDC_FORMAT_MACROS 1
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Path separator
|
||||
#ifndef PATH_SEPARATOR
|
||||
# ifdef OS_WINDOWS
|
||||
# define PATH_SEPARATOR '\\'
|
||||
# else
|
||||
# define PATH_SEPARATOR '/'
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Windows
|
||||
|
||||
// Always export symbols when compiling a shared library as this file is only
|
||||
// included by internal modules when building the gflags library itself.
|
||||
// The gflags_declare.h header file will set it to import these symbols otherwise.
|
||||
#ifndef GFLAGS_DLL_DECL
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECL __declspec(dllexport)
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define GFLAGS_DLL_DECL __attribute__((visibility("default")))
|
||||
# else
|
||||
# define GFLAGS_DLL_DECL
|
||||
# endif
|
||||
#endif
|
||||
// Flags defined by the gflags library itself must be exported
|
||||
#ifndef GFLAGS_DLL_DEFINE_FLAG
|
||||
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
|
||||
#endif
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
// The unittests import the symbols of the shared gflags library
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
|
||||
# endif
|
||||
# include "windows_port.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // GFLAGS_CONFIG_H_
|
112
src/config.h.in
112
src/config.h.in
|
@ -1,112 +0,0 @@
|
|||
/* Generated from config.h.in during build configuration using CMake. */
|
||||
|
||||
// Note: This header file is only used internally. It is not part of public interface!
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// System checks
|
||||
|
||||
// Define if you build this library for a MS Windows OS.
|
||||
#cmakedefine OS_WINDOWS
|
||||
|
||||
// Define if you have the <stdint.h> header file.
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
// Define if you have the <sys/types.h> header file.
|
||||
#cmakedefine HAVE_SYS_TYPES_H
|
||||
|
||||
// Define if you have the <inttypes.h> header file.
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
|
||||
// Define if you have the <sys/stat.h> header file.
|
||||
#cmakedefine HAVE_SYS_STAT_H
|
||||
|
||||
// Define if you have the <unistd.h> header file.
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
|
||||
// Define if you have the <fnmatch.h> header file.
|
||||
#cmakedefine HAVE_FNMATCH_H
|
||||
|
||||
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
|
||||
#cmakedefine HAVE_SHLWAPI_H
|
||||
|
||||
// Define if you have the strtoll function.
|
||||
#cmakedefine HAVE_STRTOLL
|
||||
|
||||
// Define if you have the strtoq function.
|
||||
#cmakedefine HAVE_STRTOQ
|
||||
|
||||
// Define if you have the <pthread.h> header file.
|
||||
#cmakedefine HAVE_PTHREAD
|
||||
|
||||
// Define if your pthread library defines the type pthread_rwlock_t
|
||||
#cmakedefine HAVE_RWLOCK
|
||||
|
||||
// gcc requires this to get PRId64, etc.
|
||||
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
|
||||
# define __STDC_FORMAT_MACROS 1
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Package information
|
||||
|
||||
// Name of package.
|
||||
#define PACKAGE @PROJECT_NAME@
|
||||
|
||||
// Define to the full name of this package.
|
||||
#define PACKAGE_NAME @PACKAGE_NAME@
|
||||
|
||||
// Define to the full name and version of this package.
|
||||
#define PACKAGE_STRING @PACKAGE_STRING@
|
||||
|
||||
// Define to the one symbol short name of this package.
|
||||
#define PACKAGE_TARNAME @PACKAGE_TARNAME@
|
||||
|
||||
// Define to the version of this package.
|
||||
#define PACKAGE_VERSION @PACKAGE_VERSION@
|
||||
|
||||
// Version number of package.
|
||||
#define VERSION PACKAGE_VERSION
|
||||
|
||||
// Define to the address where bug reports for this package should be sent.
|
||||
#define PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Path separator
|
||||
#ifndef PATH_SEPARATOR
|
||||
# ifdef OS_WINDOWS
|
||||
# define PATH_SEPARATOR '\\'
|
||||
# else
|
||||
# define PATH_SEPARATOR '/'
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Windows
|
||||
|
||||
// Whether gflags library is a DLL.
|
||||
#ifndef GFLAGS_IS_A_DLL
|
||||
# define GFLAGS_IS_A_DLL 0
|
||||
#endif
|
||||
|
||||
// Always export symbols when compiling a shared library as this file is only
|
||||
// included by internal modules when building the gflags library itself.
|
||||
// The gflags_declare.h header file will set it to import these symbols otherwise.
|
||||
#ifndef GFLAGS_DLL_DECL
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define GFLAGS_DLL_DECL
|
||||
# endif
|
||||
#endif
|
||||
// Flags defined by the gflags library itself must be exported
|
||||
#ifndef GFLAGS_DLL_DEFINE_FLAG
|
||||
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
|
||||
#endif
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
// The unittests import the symbols of the shared gflags library
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
|
||||
# endif
|
||||
# include "windows_port.h"
|
||||
#endif
|
48
src/defines.h.in
Normal file
48
src/defines.h.in
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Generated from defines.h.in during build configuration using CMake. */
|
||||
|
||||
// Note: This header file is only used internally. It is not part of public interface!
|
||||
// Any cmakedefine is defined using the -D flag instead when Bazel is used.
|
||||
// For Bazel, this file is thus not used to avoid a private file in $(GENDIR).
|
||||
|
||||
#ifndef GFLAGS_DEFINES_H_
|
||||
#define GFLAGS_DEFINES_H_
|
||||
|
||||
|
||||
// Define if you build this library for a MS Windows OS.
|
||||
#cmakedefine OS_WINDOWS
|
||||
|
||||
// Define if you have the <stdint.h> header file.
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
// Define if you have the <sys/types.h> header file.
|
||||
#cmakedefine HAVE_SYS_TYPES_H
|
||||
|
||||
// Define if you have the <inttypes.h> header file.
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
|
||||
// Define if you have the <sys/stat.h> header file.
|
||||
#cmakedefine HAVE_SYS_STAT_H
|
||||
|
||||
// Define if you have the <unistd.h> header file.
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
|
||||
// Define if you have the <fnmatch.h> header file.
|
||||
#cmakedefine HAVE_FNMATCH_H
|
||||
|
||||
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
|
||||
#cmakedefine HAVE_SHLWAPI_H
|
||||
|
||||
// Define if you have the strtoll function.
|
||||
#cmakedefine HAVE_STRTOLL
|
||||
|
||||
// Define if you have the strtoq function.
|
||||
#cmakedefine HAVE_STRTOQ
|
||||
|
||||
// Define if you have the <pthread.h> header file.
|
||||
#cmakedefine HAVE_PTHREAD
|
||||
|
||||
// Define if your pthread library defines the type pthread_rwlock_t
|
||||
#cmakedefine HAVE_RWLOCK
|
||||
|
||||
|
||||
#endif // GFLAGS_DEFINES_H_
|
372
src/gflags.cc
372
src/gflags.cc
|
@ -88,19 +88,20 @@
|
|||
// are, similarly, mostly hooks into the functionality described above.
|
||||
|
||||
#include "config.h"
|
||||
#include "gflags.h"
|
||||
#include "gflags/gflags.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#if defined(HAVE_FNMATCH_H)
|
||||
# include <fnmatch.h>
|
||||
#elif defined(HAVE_SHLWAPI_H)
|
||||
# define NO_SHLWAPI_ISOS
|
||||
# include <shlwapi.h>
|
||||
#endif
|
||||
#include <stdarg.h> // For va_list and related operations
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cstdarg> // For va_list and related operations
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
@ -111,6 +112,9 @@
|
|||
#include "mutex.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace MUTEX_NAMESPACE;
|
||||
|
||||
|
||||
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
|
||||
DEFINE_string(flagfile, "", "load flags from file");
|
||||
DEFINE_string(fromenv, "", "set flags from the environment"
|
||||
|
@ -167,12 +171,10 @@ enum DieWhenReporting { DIE, DO_NOT_DIE };
|
|||
|
||||
// Report Error and exit if requested.
|
||||
static void ReportError(DieWhenReporting should_die, const char* format, ...) {
|
||||
char error_message[255];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(error_message, sizeof(error_message), format, ap);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "%s", error_message);
|
||||
fflush(stderr); // should be unnecessary, but cygwin's rxvt buffers stderr
|
||||
if (should_die == DIE) gflags_exitfunc(1);
|
||||
}
|
||||
|
@ -188,34 +190,41 @@ static void ReportError(DieWhenReporting should_die, const char* format, ...) {
|
|||
class CommandLineFlag;
|
||||
class FlagValue {
|
||||
public:
|
||||
FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value);
|
||||
enum ValueType {
|
||||
FV_BOOL = 0,
|
||||
FV_INT32 = 1,
|
||||
FV_UINT32 = 2,
|
||||
FV_INT64 = 3,
|
||||
FV_UINT64 = 4,
|
||||
FV_DOUBLE = 5,
|
||||
FV_STRING = 6,
|
||||
FV_MAX_INDEX = 6,
|
||||
};
|
||||
|
||||
template <typename FlagType>
|
||||
FlagValue(FlagType* valbuf, bool transfer_ownership_of_value);
|
||||
~FlagValue();
|
||||
|
||||
bool ParseFrom(const char* spec);
|
||||
string ToString() const;
|
||||
|
||||
ValueType Type() const { return static_cast<ValueType>(type_); }
|
||||
|
||||
private:
|
||||
friend class CommandLineFlag; // for many things, including Validate()
|
||||
friend class GFLAGS_NAMESPACE::FlagSaverImpl; // calls New()
|
||||
friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map
|
||||
template <typename T> friend T GetFromEnv(const char*, const char*, T);
|
||||
template <typename T> friend T GetFromEnv(const char*, T);
|
||||
friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
|
||||
const char*, string*); // for New(), CopyFrom()
|
||||
|
||||
enum ValueType {
|
||||
FV_BOOL = 0,
|
||||
FV_INT32 = 1,
|
||||
FV_INT64 = 2,
|
||||
FV_UINT64 = 3,
|
||||
FV_DOUBLE = 4,
|
||||
FV_STRING = 5,
|
||||
FV_MAX_INDEX = 5,
|
||||
};
|
||||
template <typename FlagType>
|
||||
struct FlagValueTraits;
|
||||
|
||||
const char* TypeName() const;
|
||||
bool Equal(const FlagValue& x) const;
|
||||
FlagValue* New() const; // creates a new one with default value
|
||||
void CopyFrom(const FlagValue& x);
|
||||
int ValueSize() const;
|
||||
|
||||
// Calls the given validate-fn on value_buffer_, and returns
|
||||
// whatever it returns. But first casts validate_fn_proto to a
|
||||
|
@ -223,14 +232,33 @@ class FlagValue {
|
|||
// (*validate_fn)(bool) for a bool flag).
|
||||
bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
|
||||
|
||||
void* value_buffer_; // points to the buffer holding our data
|
||||
int8 type_; // how to interpret value_
|
||||
bool owns_value_; // whether to free value on destruct
|
||||
void* const value_buffer_; // points to the buffer holding our data
|
||||
const int8 type_; // how to interpret value_
|
||||
const bool owns_value_; // whether to free value on destruct
|
||||
|
||||
FlagValue(const FlagValue&); // no copying!
|
||||
void operator=(const FlagValue&);
|
||||
};
|
||||
|
||||
// Map the given C++ type to a value of the ValueType enum at compile time.
|
||||
#define DEFINE_FLAG_TRAITS(type, value) \
|
||||
template <> \
|
||||
struct FlagValue::FlagValueTraits<type> { \
|
||||
static const ValueType kValueType = value; \
|
||||
}
|
||||
|
||||
// Define full template specializations of the FlagValueTraits template
|
||||
// for all supported flag types.
|
||||
DEFINE_FLAG_TRAITS(bool, FV_BOOL);
|
||||
DEFINE_FLAG_TRAITS(int32, FV_INT32);
|
||||
DEFINE_FLAG_TRAITS(uint32, FV_UINT32);
|
||||
DEFINE_FLAG_TRAITS(int64, FV_INT64);
|
||||
DEFINE_FLAG_TRAITS(uint64, FV_UINT64);
|
||||
DEFINE_FLAG_TRAITS(double, FV_DOUBLE);
|
||||
DEFINE_FLAG_TRAITS(std::string, FV_STRING);
|
||||
|
||||
#undef DEFINE_FLAG_TRAITS
|
||||
|
||||
|
||||
// This could be a templated method of FlagValue, but doing so adds to the
|
||||
// size of the .o. Since there's no type-safety here anyway, macro is ok.
|
||||
|
@ -238,16 +266,12 @@ class FlagValue {
|
|||
#define OTHER_VALUE_AS(fv, type) *reinterpret_cast<type*>(fv.value_buffer_)
|
||||
#define SET_VALUE_AS(type, value) VALUE_AS(type) = (value)
|
||||
|
||||
FlagValue::FlagValue(void* valbuf, const char* type,
|
||||
template <typename FlagType>
|
||||
FlagValue::FlagValue(FlagType* valbuf,
|
||||
bool transfer_ownership_of_value)
|
||||
: value_buffer_(valbuf),
|
||||
type_(FlagValueTraits<FlagType>::kValueType),
|
||||
owns_value_(transfer_ownership_of_value) {
|
||||
for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
|
||||
if (!strcmp(type, TypeName())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(type_ <= FV_MAX_INDEX); // Unknown typename
|
||||
}
|
||||
|
||||
FlagValue::~FlagValue() {
|
||||
|
@ -257,6 +281,7 @@ FlagValue::~FlagValue() {
|
|||
switch (type_) {
|
||||
case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
|
||||
case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
|
||||
case FV_UINT32: delete reinterpret_cast<uint32*>(value_buffer_); break;
|
||||
case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
|
||||
case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
|
||||
case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
|
||||
|
@ -305,6 +330,16 @@ bool FlagValue::ParseFrom(const char* value) {
|
|||
SET_VALUE_AS(int32, static_cast<int32>(r));
|
||||
return true;
|
||||
}
|
||||
case FV_UINT32: {
|
||||
while (*value == ' ') value++;
|
||||
if (*value == '-') return false; // negative number
|
||||
const uint64 r = strtou64(value, &end, base);
|
||||
if (errno || end != value + strlen(value)) return false; // bad parse
|
||||
if (static_cast<uint32>(r) != r) // worked, but number out of range
|
||||
return false;
|
||||
SET_VALUE_AS(uint32, static_cast<uint32>(r));
|
||||
return true;
|
||||
}
|
||||
case FV_INT64: {
|
||||
const int64 r = strto64(value, &end, base);
|
||||
if (errno || end != value + strlen(value)) return false; // bad parse
|
||||
|
@ -340,6 +375,9 @@ string FlagValue::ToString() const {
|
|||
case FV_INT32:
|
||||
snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
|
||||
return intbuf;
|
||||
case FV_UINT32:
|
||||
snprintf(intbuf, sizeof(intbuf), "%" PRIu32, VALUE_AS(uint32));
|
||||
return intbuf;
|
||||
case FV_INT64:
|
||||
snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
|
||||
return intbuf;
|
||||
|
@ -366,6 +404,9 @@ bool FlagValue::Validate(const char* flagname,
|
|||
case FV_INT32:
|
||||
return reinterpret_cast<bool (*)(const char*, int32)>(
|
||||
validate_fn_proto)(flagname, VALUE_AS(int32));
|
||||
case FV_UINT32:
|
||||
return reinterpret_cast<bool (*)(const char*, uint32)>(
|
||||
validate_fn_proto)(flagname, VALUE_AS(uint32));
|
||||
case FV_INT64:
|
||||
return reinterpret_cast<bool (*)(const char*, int64)>(
|
||||
validate_fn_proto)(flagname, VALUE_AS(int64));
|
||||
|
@ -388,6 +429,7 @@ const char* FlagValue::TypeName() const {
|
|||
static const char types[] =
|
||||
"bool\0xx"
|
||||
"int32\0x"
|
||||
"uint32\0"
|
||||
"int64\0x"
|
||||
"uint64\0"
|
||||
"double\0"
|
||||
|
@ -406,6 +448,7 @@ bool FlagValue::Equal(const FlagValue& x) const {
|
|||
switch (type_) {
|
||||
case FV_BOOL: return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
|
||||
case FV_INT32: return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
|
||||
case FV_UINT32: return VALUE_AS(uint32) == OTHER_VALUE_AS(x, uint32);
|
||||
case FV_INT64: return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
|
||||
case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
|
||||
case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
|
||||
|
@ -415,14 +458,14 @@ bool FlagValue::Equal(const FlagValue& x) const {
|
|||
}
|
||||
|
||||
FlagValue* FlagValue::New() const {
|
||||
const char *type = TypeName();
|
||||
switch (type_) {
|
||||
case FV_BOOL: return new FlagValue(new bool(false), type, true);
|
||||
case FV_INT32: return new FlagValue(new int32(0), type, true);
|
||||
case FV_INT64: return new FlagValue(new int64(0), type, true);
|
||||
case FV_UINT64: return new FlagValue(new uint64(0), type, true);
|
||||
case FV_DOUBLE: return new FlagValue(new double(0.0), type, true);
|
||||
case FV_STRING: return new FlagValue(new string, type, true);
|
||||
case FV_BOOL: return new FlagValue(new bool(false), true);
|
||||
case FV_INT32: return new FlagValue(new int32(0), true);
|
||||
case FV_UINT32: return new FlagValue(new uint32(0), true);
|
||||
case FV_INT64: return new FlagValue(new int64(0), true);
|
||||
case FV_UINT64: return new FlagValue(new uint64(0), true);
|
||||
case FV_DOUBLE: return new FlagValue(new double(0.0), true);
|
||||
case FV_STRING: return new FlagValue(new string, true);
|
||||
default: assert(false); return NULL; // unknown type
|
||||
}
|
||||
}
|
||||
|
@ -432,6 +475,7 @@ void FlagValue::CopyFrom(const FlagValue& x) {
|
|||
switch (type_) {
|
||||
case FV_BOOL: SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool)); break;
|
||||
case FV_INT32: SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32)); break;
|
||||
case FV_UINT32: SET_VALUE_AS(uint32, OTHER_VALUE_AS(x, uint32)); break;
|
||||
case FV_INT64: SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64)); break;
|
||||
case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64)); break;
|
||||
case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double)); break;
|
||||
|
@ -440,22 +484,6 @@ void FlagValue::CopyFrom(const FlagValue& x) {
|
|||
}
|
||||
}
|
||||
|
||||
int FlagValue::ValueSize() const {
|
||||
if (type_ > FV_MAX_INDEX) {
|
||||
assert(false); // unknown type
|
||||
return 0;
|
||||
}
|
||||
static const uint8 valuesize[] = {
|
||||
sizeof(bool),
|
||||
sizeof(int32),
|
||||
sizeof(int64),
|
||||
sizeof(uint64),
|
||||
sizeof(double),
|
||||
sizeof(string),
|
||||
};
|
||||
return valuesize[type_];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// CommandLineFlag
|
||||
// This represents a single flag, including its name, description,
|
||||
|
@ -484,11 +512,14 @@ class CommandLineFlag {
|
|||
ValidateFnProto validate_function() const { return validate_fn_proto_; }
|
||||
const void* flag_ptr() const { return current_->value_buffer_; }
|
||||
|
||||
FlagValue::ValueType Type() const { return defvalue_->Type(); }
|
||||
|
||||
void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
|
||||
|
||||
// If validate_fn_proto_ is non-NULL, calls it on value, returns result.
|
||||
bool Validate(const FlagValue& value) const;
|
||||
bool ValidateCurrent() const { return Validate(*current_); }
|
||||
bool Modified() const { return modified_; }
|
||||
|
||||
private:
|
||||
// for SetFlagLocked() and setting flags_by_ptr_
|
||||
|
@ -531,26 +562,14 @@ CommandLineFlag::~CommandLineFlag() {
|
|||
}
|
||||
|
||||
const char* CommandLineFlag::CleanFileName() const {
|
||||
// Compute top-level directory & file that this appears in
|
||||
// search full path backwards.
|
||||
// Stop going backwards at kRootDir; and skip by the first slash.
|
||||
static const char kRootDir[] = ""; // can set this to root directory,
|
||||
|
||||
if (sizeof(kRootDir)-1 == 0) // no prefix to strip
|
||||
return filename();
|
||||
|
||||
const char* clean_name = filename() + strlen(filename()) - 1;
|
||||
while ( clean_name > filename() ) {
|
||||
if (*clean_name == PATH_SEPARATOR) {
|
||||
if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) {
|
||||
clean_name += sizeof(kRootDir)-1; // past root-dir
|
||||
break;
|
||||
}
|
||||
}
|
||||
--clean_name;
|
||||
}
|
||||
while ( *clean_name == PATH_SEPARATOR ) ++clean_name; // Skip any slashes
|
||||
return clean_name;
|
||||
// This function has been used to strip off a common prefix from
|
||||
// flag source file names. Because flags can be defined in different
|
||||
// shared libraries, there may not be a single common prefix.
|
||||
// Further, this functionality hasn't been active for many years.
|
||||
// Need a better way to produce more user friendly help output or
|
||||
// "anonymize" file paths in help output, respectively.
|
||||
// Follow issue at: https://github.com/gflags/gflags/issues/86
|
||||
return filename();
|
||||
}
|
||||
|
||||
void CommandLineFlag::FillCommandLineFlagInfo(
|
||||
|
@ -661,7 +680,7 @@ class FlagRegistry {
|
|||
|
||||
private:
|
||||
friend class GFLAGS_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them
|
||||
friend class CommandLineFlagParser; // for ValidateAllFlags
|
||||
friend class CommandLineFlagParser; // for ValidateUnmodifiedFlags
|
||||
friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
|
||||
|
||||
// The map from name to flag, for FindFlagLocked().
|
||||
|
@ -677,7 +696,6 @@ class FlagRegistry {
|
|||
static FlagRegistry* global_registry_; // a singleton registry
|
||||
|
||||
Mutex lock_;
|
||||
static Mutex global_registry_lock_;
|
||||
|
||||
static void InitGlobalRegistry();
|
||||
|
||||
|
@ -722,7 +740,12 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
|
|||
CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
|
||||
FlagConstIterator i = flags_.find(name);
|
||||
if (i == flags_.end()) {
|
||||
return NULL;
|
||||
// If the name has dashes in it, try again after replacing with
|
||||
// underscores.
|
||||
if (strchr(name, '-') == NULL) return NULL;
|
||||
string name_rep = name;
|
||||
std::replace(name_rep.begin(), name_rep.end(), '-', '_');
|
||||
return FindFlagLocked(name_rep.c_str());
|
||||
} else {
|
||||
return i->second;
|
||||
}
|
||||
|
@ -774,7 +797,7 @@ CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
|
|||
kError, key->c_str());
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(flag->type_name(), "bool") != 0) {
|
||||
if (flag->Type() != FlagValue::FV_BOOL) {
|
||||
// 'x' exists but is not boolean, so we're not in the exception case.
|
||||
*error_message = StringPrintf(
|
||||
"%sboolean value (%s) specified for %s command line flag\n",
|
||||
|
@ -788,7 +811,7 @@ CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
|
|||
}
|
||||
|
||||
// Assign a value if this is a boolean flag
|
||||
if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) {
|
||||
if (*v == NULL && flag->Type() == FlagValue::FV_BOOL) {
|
||||
*v = "1"; // the --nox case was already handled, so this is the --x case
|
||||
}
|
||||
|
||||
|
@ -875,10 +898,10 @@ bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
|
|||
|
||||
// Get the singleton FlagRegistry object
|
||||
FlagRegistry* FlagRegistry::global_registry_ = NULL;
|
||||
Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED);
|
||||
|
||||
FlagRegistry* FlagRegistry::GlobalRegistry() {
|
||||
MutexLock acquire_lock(&global_registry_lock_);
|
||||
static Mutex lock(Mutex::LINKER_INITIALIZED);
|
||||
MutexLock acquire_lock(&lock);
|
||||
if (!global_registry_) {
|
||||
global_registry_ = new FlagRegistry;
|
||||
}
|
||||
|
@ -917,8 +940,9 @@ class CommandLineFlagParser {
|
|||
// In gflags_reporting.cc:HandleCommandLineHelpFlags().
|
||||
|
||||
// Stage 3: validate all the commandline flags that have validators
|
||||
// registered.
|
||||
void ValidateAllFlags();
|
||||
// registered and were not set/modified by ParseNewCommandLineFlags.
|
||||
void ValidateFlags(bool all);
|
||||
void ValidateUnmodifiedFlags();
|
||||
|
||||
// Stage 4: report any errors and return true if any were found.
|
||||
bool ReportErrors();
|
||||
|
@ -1005,9 +1029,6 @@ static string ReadFileIntoString(const char* filename) {
|
|||
|
||||
uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
|
||||
bool remove_flags) {
|
||||
const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR); // nix path
|
||||
program_name = (program_name == NULL ? (*argv)[0] : program_name+1);
|
||||
|
||||
int first_nonopt = *argc; // for non-options moved to the end
|
||||
|
||||
registry_->Lock();
|
||||
|
@ -1015,17 +1036,15 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
|
|||
char* arg = (*argv)[i];
|
||||
|
||||
// Like getopt(), we permute non-option flags to be at the end.
|
||||
if (arg[0] != '-' || // must be a program argument
|
||||
(arg[0] == '-' && arg[1] == '\0')) { // "-" is an argument, not a flag
|
||||
if (arg[0] != '-' || arg[1] == '\0') { // must be a program argument: "-" is an argument, not a flag
|
||||
memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
|
||||
(*argv)[*argc-1] = arg; // we go last
|
||||
first_nonopt--; // we've been pushed onto the stack
|
||||
i--; // to undo the i++ in the loop
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg[0] == '-') arg++; // allow leading '-'
|
||||
if (arg[0] == '-') arg++; // or leading '--'
|
||||
arg++; // skip leading '-'
|
||||
if (arg[0] == '-') arg++; // or leading '--'
|
||||
|
||||
// -- alone means what it does for GNU: stop options parsing
|
||||
if (*arg == '\0') {
|
||||
|
@ -1047,7 +1066,7 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
|
|||
|
||||
if (value == NULL) {
|
||||
// Boolean options are always assigned a value by SplitArgumentLocked()
|
||||
assert(strcmp(flag->type_name(), "bool") != 0);
|
||||
assert(flag->Type() != FlagValue::FV_BOOL);
|
||||
if (i+1 >= first_nonopt) {
|
||||
// This flag needs a value, but there is nothing available
|
||||
error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
|
||||
|
@ -1072,7 +1091,7 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
|
|||
// "-lat -30.5" would trigger the warning. The common cases we
|
||||
// want to solve talk about true and false as values.
|
||||
if (value[0] == '-'
|
||||
&& strcmp(flag->type_name(), "string") == 0
|
||||
&& flag->Type() == FlagValue::FV_STRING
|
||||
&& (strstr(flag->help(), "true")
|
||||
|| strstr(flag->help(), "false"))) {
|
||||
LOG(WARNING) << "Did you really mean to set flag '"
|
||||
|
@ -1137,8 +1156,8 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
|
|||
}
|
||||
|
||||
const string envname = string("FLAGS_") + string(flagname);
|
||||
string envval;
|
||||
if (!SafeGetEnv(envname.c_str(), envval)) {
|
||||
string envval;
|
||||
if (!SafeGetEnv(envname.c_str(), envval)) {
|
||||
if (errors_are_fatal) {
|
||||
error_flags_[flagname] = (string(kError) + envname +
|
||||
" not found in environment\n");
|
||||
|
@ -1184,23 +1203,31 @@ string CommandLineFlagParser::ProcessSingleOptionLocked(
|
|||
return msg;
|
||||
}
|
||||
|
||||
void CommandLineFlagParser::ValidateAllFlags() {
|
||||
void CommandLineFlagParser::ValidateFlags(bool all) {
|
||||
FlagRegistryLock frl(registry_);
|
||||
for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
|
||||
i != registry_->flags_.end(); ++i) {
|
||||
if (!i->second->ValidateCurrent()) {
|
||||
if ((all || !i->second->Modified()) && !i->second->ValidateCurrent()) {
|
||||
// only set a message if one isn't already there. (If there's
|
||||
// an error message, our job is done, even if it's not exactly
|
||||
// the same error.)
|
||||
if (error_flags_[i->second->name()].empty())
|
||||
if (error_flags_[i->second->name()].empty()) {
|
||||
error_flags_[i->second->name()] =
|
||||
string(kError) + "--" + i->second->name() +
|
||||
" must be set on the commandline"
|
||||
" (default value fails validation)\n";
|
||||
" must be set on the commandline";
|
||||
if (!i->second->Modified()) {
|
||||
error_flags_[i->second->name()] += " (default value fails validation)";
|
||||
}
|
||||
error_flags_[i->second->name()] += "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLineFlagParser::ValidateUnmodifiedFlags() {
|
||||
ValidateFlags(false);
|
||||
}
|
||||
|
||||
bool CommandLineFlagParser::ReportErrors() {
|
||||
// error_flags_ indicates errors we saw while parsing.
|
||||
// But we ignore undefined-names if ok'ed by --undef_ok
|
||||
|
@ -1252,7 +1279,11 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
|
|||
for (; line_end; flagfile_contents = line_end + 1) {
|
||||
while (*flagfile_contents && isspace(*flagfile_contents))
|
||||
++flagfile_contents;
|
||||
line_end = strchr(flagfile_contents, '\n');
|
||||
// Windows uses "\r\n"
|
||||
line_end = strchr(flagfile_contents, '\r');
|
||||
if (line_end == NULL)
|
||||
line_end = strchr(flagfile_contents, '\n');
|
||||
|
||||
size_t len = line_end ? line_end - flagfile_contents
|
||||
: strlen(flagfile_contents);
|
||||
string line(flagfile_contents, len);
|
||||
|
@ -1310,8 +1341,8 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
|
|||
|| fnmatch(glob.c_str(), ProgramInvocationName(), FNM_PATHNAME) == 0
|
||||
|| fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
|
||||
#elif defined(HAVE_SHLWAPI_H)
|
||||
|| PathMatchSpec(glob.c_str(), ProgramInvocationName())
|
||||
|| PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
|
||||
|| PathMatchSpecA(glob.c_str(), ProgramInvocationName())
|
||||
|| PathMatchSpecA(glob.c_str(), ProgramInvocationShortName())
|
||||
#endif
|
||||
) {
|
||||
flags_are_relevant = true;
|
||||
|
@ -1332,14 +1363,14 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
|
|||
// --------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
T GetFromEnv(const char *varname, const char* type, T dflt) {
|
||||
T GetFromEnv(const char *varname, T dflt) {
|
||||
std::string valstr;
|
||||
if (SafeGetEnv(varname, valstr)) {
|
||||
FlagValue ifv(new T, type, true);
|
||||
FlagValue ifv(new T, true);
|
||||
if (!ifv.ParseFrom(valstr.c_str())) {
|
||||
ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
|
||||
varname, valstr.c_str());
|
||||
}
|
||||
}
|
||||
return OTHER_VALUE_AS(ifv, T);
|
||||
} else return dflt;
|
||||
}
|
||||
|
@ -1386,22 +1417,48 @@ bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
|
|||
// values in a global destructor.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
FlagRegisterer::FlagRegisterer(const char* name, const char* type,
|
||||
const char* help, const char* filename,
|
||||
void* current_storage, void* defvalue_storage) {
|
||||
namespace {
|
||||
void RegisterCommandLineFlag(const char* name,
|
||||
const char* help,
|
||||
const char* filename,
|
||||
FlagValue* current,
|
||||
FlagValue* defvalue) {
|
||||
if (help == NULL)
|
||||
help = "";
|
||||
// FlagValue expects the type-name to not include any namespace
|
||||
// components, so we get rid of those, if any.
|
||||
if (strchr(type, ':'))
|
||||
type = strrchr(type, ':') + 1;
|
||||
FlagValue* current = new FlagValue(current_storage, type, false);
|
||||
FlagValue* defvalue = new FlagValue(defvalue_storage, type, false);
|
||||
// Importantly, flag_ will never be deleted, so storage is always good.
|
||||
CommandLineFlag* flag = new CommandLineFlag(name, help, filename,
|
||||
current, defvalue);
|
||||
FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry
|
||||
CommandLineFlag* flag =
|
||||
new CommandLineFlag(name, help, filename, current, defvalue);
|
||||
FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FlagType>
|
||||
FlagRegisterer::FlagRegisterer(const char* name,
|
||||
const char* help,
|
||||
const char* filename,
|
||||
FlagType* current_storage,
|
||||
FlagType* defvalue_storage) {
|
||||
FlagValue* const current = new FlagValue(current_storage, false);
|
||||
FlagValue* const defvalue = new FlagValue(defvalue_storage, false);
|
||||
RegisterCommandLineFlag(name, help, filename, current, defvalue);
|
||||
}
|
||||
|
||||
// Force compiler to generate code for the given template specialization.
|
||||
#define INSTANTIATE_FLAG_REGISTERER_CTOR(type) \
|
||||
template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \
|
||||
const char* name, const char* help, const char* filename, \
|
||||
type* current_storage, type* defvalue_storage)
|
||||
|
||||
// Do this for all supported flag types.
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(bool);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(int32);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(uint32);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(int64);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(uint64);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(double);
|
||||
INSTANTIATE_FLAG_REGISTERER_CTOR(std::string);
|
||||
|
||||
#undef INSTANTIATE_FLAG_REGISTERER_CTOR
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// GetAllFlags()
|
||||
|
@ -1451,65 +1508,58 @@ void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
|
|||
|
||||
// These values are not protected by a Mutex because they are normally
|
||||
// set only once during program startup.
|
||||
static const char* argv0 = "UNKNOWN"; // just the program name
|
||||
static const char* cmdline = ""; // the entire command-line
|
||||
static string argv0("UNKNOWN"); // just the program name
|
||||
static string cmdline; // the entire command-line
|
||||
static string program_usage;
|
||||
static vector<string> argvs;
|
||||
static uint32 argv_sum = 0;
|
||||
static const char* program_usage = NULL;
|
||||
|
||||
void SetArgv(int argc, const char** argv) {
|
||||
static bool called_set_argv = false;
|
||||
if (called_set_argv) // we already have an argv for you
|
||||
return;
|
||||
|
||||
if (called_set_argv) return;
|
||||
called_set_argv = true;
|
||||
|
||||
assert(argc > 0); // every program has at least a progname
|
||||
argv0 = strdup(argv[0]); // small memory leak, but fn only called once
|
||||
assert(argv0);
|
||||
assert(argc > 0); // every program has at least a name
|
||||
argv0 = argv[0];
|
||||
|
||||
string cmdline_string; // easier than doing strcats
|
||||
cmdline.clear();
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (i != 0) {
|
||||
cmdline_string += " ";
|
||||
}
|
||||
cmdline_string += argv[i];
|
||||
if (i != 0) cmdline += " ";
|
||||
cmdline += argv[i];
|
||||
argvs.push_back(argv[i]);
|
||||
}
|
||||
cmdline = strdup(cmdline_string.c_str()); // another small memory leak
|
||||
assert(cmdline);
|
||||
|
||||
// Compute a simple sum of all the chars in argv
|
||||
for (const char* c = cmdline; *c; c++)
|
||||
argv_sum = 0;
|
||||
for (string::const_iterator c = cmdline.begin(); c != cmdline.end(); ++c) {
|
||||
argv_sum += *c;
|
||||
}
|
||||
}
|
||||
|
||||
const vector<string>& GetArgvs() { return argvs; }
|
||||
const char* GetArgv() { return cmdline; }
|
||||
const char* GetArgv0() { return argv0; }
|
||||
const char* GetArgv() { return cmdline.c_str(); }
|
||||
const char* GetArgv0() { return argv0.c_str(); }
|
||||
uint32 GetArgvSum() { return argv_sum; }
|
||||
const char* ProgramInvocationName() { // like the GNU libc fn
|
||||
return GetArgv0();
|
||||
}
|
||||
const char* ProgramInvocationShortName() { // like the GNU libc fn
|
||||
const char* slash = strrchr(argv0, '/');
|
||||
size_t pos = argv0.rfind('/');
|
||||
#ifdef OS_WINDOWS
|
||||
if (!slash) slash = strrchr(argv0, '\\');
|
||||
if (pos == string::npos) pos = argv0.rfind('\\');
|
||||
#endif
|
||||
return slash ? slash + 1 : argv0;
|
||||
return (pos == string::npos ? argv0.c_str() : (argv0.c_str() + pos + 1));
|
||||
}
|
||||
|
||||
void SetUsageMessage(const string& usage) {
|
||||
if (program_usage != NULL)
|
||||
ReportError(DIE, "ERROR: SetUsageMessage() called twice\n");
|
||||
program_usage = strdup(usage.c_str()); // small memory leak
|
||||
program_usage = usage;
|
||||
}
|
||||
|
||||
const char* ProgramUsage() {
|
||||
if (program_usage) {
|
||||
return program_usage;
|
||||
if (program_usage.empty()) {
|
||||
return "Warning: SetUsageMessage() never called";
|
||||
}
|
||||
return "Warning: SetUsageMessage() never called";
|
||||
return program_usage.c_str();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -1517,16 +1567,14 @@ const char* ProgramUsage() {
|
|||
// VersionString()
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static const char* version_string = NULL;
|
||||
static string version_string;
|
||||
|
||||
void SetVersionString(const string& version) {
|
||||
if (version_string != NULL)
|
||||
ReportError(DIE, "ERROR: SetVersionString() called twice\n");
|
||||
version_string = strdup(version.c_str()); // small memory leak
|
||||
version_string = version;
|
||||
}
|
||||
|
||||
const char* VersionString() {
|
||||
return version_string ? version_string : "";
|
||||
return version_string.c_str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1787,6 +1835,7 @@ bool ReadFromFlagsFile(const string& filename, const char* prog_name,
|
|||
// --------------------------------------------------------------------
|
||||
// BoolFromEnv()
|
||||
// Int32FromEnv()
|
||||
// Uint32FromEnv()
|
||||
// Int64FromEnv()
|
||||
// Uint64FromEnv()
|
||||
// DoubleFromEnv()
|
||||
|
@ -1798,19 +1847,22 @@ bool ReadFromFlagsFile(const string& filename, const char* prog_name,
|
|||
// --------------------------------------------------------------------
|
||||
|
||||
bool BoolFromEnv(const char *v, bool dflt) {
|
||||
return GetFromEnv(v, "bool", dflt);
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
int32 Int32FromEnv(const char *v, int32 dflt) {
|
||||
return GetFromEnv(v, "int32", dflt);
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
uint32 Uint32FromEnv(const char *v, uint32 dflt) {
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
int64 Int64FromEnv(const char *v, int64 dflt) {
|
||||
return GetFromEnv(v, "int64", dflt);
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
uint64 Uint64FromEnv(const char *v, uint64 dflt) {
|
||||
return GetFromEnv(v, "uint64", dflt);
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
double DoubleFromEnv(const char *v, double dflt) {
|
||||
return GetFromEnv(v, "double", dflt);
|
||||
return GetFromEnv(v, dflt);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -1846,6 +1898,10 @@ bool RegisterFlagValidator(const int32* flag,
|
|||
bool (*validate_fn)(const char*, int32)) {
|
||||
return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
|
||||
}
|
||||
bool RegisterFlagValidator(const uint32* flag,
|
||||
bool (*validate_fn)(const char*, uint32)) {
|
||||
return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
|
||||
}
|
||||
bool RegisterFlagValidator(const int64* flag,
|
||||
bool (*validate_fn)(const char*, int64)) {
|
||||
return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
|
||||
|
@ -1901,7 +1957,7 @@ static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
|
|||
HandleCommandLineHelpFlags(); // may cause us to exit on --help, etc.
|
||||
|
||||
// See if any of the unset flags fail their validation checks
|
||||
parser.ValidateAllFlags();
|
||||
parser.ValidateUnmodifiedFlags();
|
||||
|
||||
if (parser.ReportErrors()) // may cause us to exit on illegal flags
|
||||
gflags_exitfunc(1);
|
||||
|
|
|
@ -81,12 +81,12 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gflags_declare.h" // IWYU pragma: export
|
||||
#include "gflags/gflags_declare.h" // IWYU pragma: export
|
||||
|
||||
|
||||
// We always want to export variables defined in user code
|
||||
#ifndef GFLAGS_DLL_DEFINE_FLAG
|
||||
# ifdef _MSC_VER
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
|
||||
# else
|
||||
# define GFLAGS_DLL_DEFINE_FLAG
|
||||
|
@ -128,6 +128,7 @@ namespace GFLAGS_NAMESPACE {
|
|||
// validator is already registered for this flag).
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32));
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
|
||||
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
|
||||
|
@ -222,7 +223,7 @@ extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLine
|
|||
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
|
||||
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
|
||||
|
||||
enum GFLAGS_DLL_DECL FlagSettingMode {
|
||||
enum FlagSettingMode {
|
||||
// update the flag's value (can call this multiple times).
|
||||
SET_FLAGS_VALUE,
|
||||
// update the flag's value, but *only if* it has not yet been updated
|
||||
|
@ -313,6 +314,7 @@ extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const
|
|||
|
||||
extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
|
||||
extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
|
||||
extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval);
|
||||
extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
|
||||
extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
|
||||
extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
|
||||
|
@ -429,11 +431,37 @@ extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
|
|||
|
||||
class GFLAGS_DLL_DECL FlagRegisterer {
|
||||
public:
|
||||
FlagRegisterer(const char* name, const char* type,
|
||||
// We instantiate this template ctor for all supported types,
|
||||
// so it is possible to place implementation of the FlagRegisterer ctor in
|
||||
// .cc file.
|
||||
// Calling this constructor with unsupported type will produce linker error.
|
||||
template <typename FlagType>
|
||||
FlagRegisterer(const char* name,
|
||||
const char* help, const char* filename,
|
||||
void* current_storage, void* defvalue_storage);
|
||||
FlagType* current_storage, FlagType* defvalue_storage);
|
||||
};
|
||||
|
||||
// Force compiler to not generate code for the given template specialization.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0
|
||||
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)
|
||||
#else
|
||||
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) \
|
||||
extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \
|
||||
const char* name, const char* help, const char* filename, \
|
||||
type* current_storage, type* defvalue_storage)
|
||||
#endif
|
||||
|
||||
// Do this for all supported flag types.
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double);
|
||||
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string);
|
||||
|
||||
#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR
|
||||
|
||||
// If your application #defines STRIP_FLAG_HELP to a non-zero value
|
||||
// before #including this file, we remove the help message from the
|
||||
// binary file. This can reduce the size of the resulting binary
|
||||
|
@ -471,9 +499,9 @@ extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
|
|||
static const type FLAGS_nono##name = value; \
|
||||
/* We always want to export defined variables, dll or no */ \
|
||||
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
|
||||
type FLAGS_no##name = FLAGS_nono##name; \
|
||||
static type FLAGS_no##name = FLAGS_nono##name; \
|
||||
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
|
||||
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
|
||||
#name, MAYBE_STRIPPED_HELP(help), __FILE__, \
|
||||
&FLAGS_##name, &FLAGS_no##name); \
|
||||
} \
|
||||
using fL##shorttype::FLAGS_##name
|
||||
|
@ -508,6 +536,10 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
|
|||
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
|
||||
name, val, txt)
|
||||
|
||||
#define DEFINE_uint32(name,val, txt) \
|
||||
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \
|
||||
name, val, txt)
|
||||
|
||||
#define DEFINE_int64(name, val, txt) \
|
||||
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
|
||||
name, val, txt)
|
||||
|
@ -538,6 +570,26 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
|
|||
}
|
||||
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
|
||||
int value);
|
||||
|
||||
// Auxiliary class used to explicitly call destructor of string objects
|
||||
// allocated using placement new during static program deinitialization.
|
||||
// The destructor MUST be an inline function such that the explicit
|
||||
// destruction occurs in the same compilation unit as the placement new.
|
||||
class StringFlagDestructor {
|
||||
void *current_storage_;
|
||||
void *defvalue_storage_;
|
||||
|
||||
public:
|
||||
|
||||
StringFlagDestructor(void *current, void *defvalue)
|
||||
: current_storage_(current), defvalue_storage_(defvalue) {}
|
||||
|
||||
~StringFlagDestructor() {
|
||||
reinterpret_cast<clstring*>(current_storage_ )->~clstring();
|
||||
reinterpret_cast<clstring*>(defvalue_storage_)->~clstring();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fLS
|
||||
|
||||
// We need to define a var named FLAGS_no##name so people don't define
|
||||
|
@ -550,13 +602,15 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
|
|||
#define DEFINE_string(name, val, txt) \
|
||||
namespace fLS { \
|
||||
using ::fLS::clstring; \
|
||||
using ::fLS::StringFlagDestructor; \
|
||||
static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
|
||||
clstring* const FLAGS_no##name = ::fLS:: \
|
||||
dont_pass0toDEFINE_string(s_##name[0].s, \
|
||||
val); \
|
||||
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
|
||||
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
|
||||
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
|
||||
#name, MAYBE_STRIPPED_HELP(txt), __FILE__, \
|
||||
FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
|
||||
static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \
|
||||
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
|
||||
using fLS::FLAGS_##name; \
|
||||
clstring& FLAGS_##name = *FLAGS_no##name; \
|
||||
|
|
|
@ -39,26 +39,25 @@
|
|||
// 2a) If there are no matching flags, do nothing.
|
||||
// 2b) If all matching flags share a common prefix longer than the
|
||||
// completion word, output just that matching prefix
|
||||
// 3) Categorize those flags to produce a rough ordering of relevence.
|
||||
// 3) Categorize those flags to produce a rough ordering of relevance.
|
||||
// 4) Potentially trim the set of flags returned to a smaller number
|
||||
// that bash is happier with
|
||||
// 5) Output the matching flags in groups ordered by relevence.
|
||||
// 5) Output the matching flags in groups ordered by relevance.
|
||||
// 5a) Force bash to place most-relevent groups at the top of the list
|
||||
// 5b) Trim most flag's descriptions to fit on a single terminal line
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // for strlen
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring> // for strlen
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gflags.h"
|
||||
#include "config.h"
|
||||
#include "gflags/gflags.h"
|
||||
#include "gflags/gflags_completions.h"
|
||||
#include "util.h"
|
||||
|
||||
using std::set;
|
||||
|
@ -120,7 +119,7 @@ static void CategorizeAllMatchingFlags(
|
|||
NotableFlags *notable_flags);
|
||||
|
||||
static void TryFindModuleAndPackageDir(
|
||||
const vector<CommandLineFlagInfo> all_flags,
|
||||
const vector<CommandLineFlagInfo> &all_flags,
|
||||
string *module,
|
||||
string *package_dir);
|
||||
|
||||
|
@ -171,7 +170,7 @@ static string GetLongFlagLine(
|
|||
// most likely to be useful first. If this is set, however, the user
|
||||
// really does want us to return every single flag as an option.
|
||||
// - force_no_update: Any time we output lines, all of which share a
|
||||
// common prefix, bash will 'helpfully' not even bother to show the
|
||||
// common prefix, bash will 'helpfuly' not even bother to show the
|
||||
// output, instead changing the current word to be that common prefix.
|
||||
// If it's clear this shouldn't happen, we'll set this boolean
|
||||
struct CompletionOptions {
|
||||
|
@ -180,11 +179,16 @@ struct CompletionOptions {
|
|||
bool flag_description_substring_search;
|
||||
bool return_all_matching_flags;
|
||||
bool force_no_update;
|
||||
CompletionOptions(): flag_name_substring_search(false),
|
||||
flag_location_substring_search(false),
|
||||
flag_description_substring_search(false),
|
||||
return_all_matching_flags(false),
|
||||
force_no_update(false) { }
|
||||
};
|
||||
|
||||
// Notable flags are flags that are special or preferred for some
|
||||
// reason. For example, flags that are defined in the binary's module
|
||||
// are expected to be much more relevent than flags defined in some
|
||||
// are expected to be much more relevant than flags defined in some
|
||||
// other random location. These sets are specified roughly in precedence
|
||||
// order. Once a flag is placed in one of these 'higher' sets, it won't
|
||||
// be placed in any of the 'lower' sets.
|
||||
|
@ -203,7 +207,7 @@ struct NotableFlags {
|
|||
static void PrintFlagCompletionInfo(void) {
|
||||
string cursor_word = FLAGS_tab_completion_word;
|
||||
string canonical_token;
|
||||
CompletionOptions options = { };
|
||||
CompletionOptions options = CompletionOptions();
|
||||
CanonicalizeCursorWordAndSearchOptions(
|
||||
cursor_word,
|
||||
&canonical_token,
|
||||
|
@ -321,12 +325,10 @@ static void CanonicalizeCursorWordAndSearchOptions(
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (found_question_marks) { // all fallthroughs
|
||||
case 3: options->flag_description_substring_search = true;
|
||||
case 2: options->flag_location_substring_search = true;
|
||||
case 1: options->flag_name_substring_search = true;
|
||||
};
|
||||
|
||||
if (found_question_marks > 2) options->flag_description_substring_search = true;
|
||||
if (found_question_marks > 1) options->flag_location_substring_search = true;
|
||||
if (found_question_marks > 0) options->flag_name_substring_search = true;
|
||||
|
||||
options->return_all_matching_flags = (found_plusses > 0);
|
||||
}
|
||||
|
@ -408,7 +410,7 @@ static bool DoesSingleFlagMatch(
|
|||
// 3) Categorize matches (and helper method)
|
||||
|
||||
// Given a set of matching flags, categorize them by
|
||||
// likely relevence to this specific binary
|
||||
// likely relevance to this specific binary
|
||||
static void CategorizeAllMatchingFlags(
|
||||
const set<const CommandLineFlagInfo *> &all_matches,
|
||||
const string &search_token,
|
||||
|
@ -449,10 +451,6 @@ static void CategorizeAllMatchingFlags(
|
|||
// In the package, since there was no slash after the package portion
|
||||
notable_flags->package_flags.insert(*it);
|
||||
DVLOG(3) << "Result: package match";
|
||||
} else if (false) {
|
||||
// In the list of the XXX most commonly supplied flags overall
|
||||
// TODO(user): Compile this list.
|
||||
DVLOG(3) << "Result: most-common match";
|
||||
} else if (!package_dir.empty() &&
|
||||
pos != string::npos && slash != string::npos) {
|
||||
// In a subdirectory of the package
|
||||
|
@ -470,7 +468,7 @@ static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) {
|
|||
}
|
||||
|
||||
static void TryFindModuleAndPackageDir(
|
||||
const vector<CommandLineFlagInfo> all_flags,
|
||||
const vector<CommandLineFlagInfo> &all_flags,
|
||||
string *module,
|
||||
string *package_dir) {
|
||||
module->clear();
|
||||
|
@ -546,8 +544,7 @@ static void FinalizeCompletionOutput(
|
|||
|
||||
vector<DisplayInfoGroup> output_groups;
|
||||
bool perfect_match_found = false;
|
||||
if (lines_so_far < max_desired_lines &&
|
||||
!notable_flags->perfect_match_flag.empty()) {
|
||||
if (!notable_flags->perfect_match_flag.empty()) {
|
||||
perfect_match_found = true;
|
||||
DisplayInfoGroup group =
|
||||
{ "",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
// handling.
|
||||
//
|
||||
// ** Overview of Bash completions:
|
||||
// Bash can be told to programatically determine completions for the
|
||||
// Bash can be told to programmatically determine completions for the
|
||||
// current 'cursor word'. It does this by (in this case) invoking a
|
||||
// command with some additional arguments identifying the command
|
||||
// being executed, the word being completed, and the previous word
|
||||
|
@ -63,7 +63,7 @@
|
|||
// we'll include the default flag value and as much of the flag's
|
||||
// description as can fit on a single terminal line width, as specified
|
||||
// by the flag --tab_completion_columns). Furthermore, we'll try to
|
||||
// make bash order the output such that the most useful or relevent
|
||||
// make bash order the output such that the most useful or relevant
|
||||
// flags are the most likely to be shown at the top.
|
||||
//
|
||||
// ** Additional features:
|
||||
|
|
|
@ -45,19 +45,32 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// Windows DLL import/export.
|
||||
|
||||
// We always want to import the symbols of the gflags library
|
||||
// Whether gflags library is a DLL.
|
||||
//
|
||||
// Set to 1 by default when the shared gflags library was built on Windows.
|
||||
// Must be overwritten when this header file is used with the optionally also
|
||||
// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS.
|
||||
#ifndef GFLAGS_IS_A_DLL
|
||||
# define GFLAGS_IS_A_DLL @GFLAGS_IS_A_DLL@
|
||||
#endif
|
||||
|
||||
// We always want to import the symbols of the gflags library.
|
||||
#ifndef GFLAGS_DLL_DECL
|
||||
# if @GFLAGS_IS_A_DLL@ && defined(_MSC_VER)
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECL __declspec(dllimport)
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define GFLAGS_DLL_DECL __attribute__((visibility("default")))
|
||||
# else
|
||||
# define GFLAGS_DLL_DECL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// We always want to import variables declared in user code
|
||||
// We always want to import variables declared in user code.
|
||||
#ifndef GFLAGS_DLL_DECLARE_FLAG
|
||||
# ifdef _MSC_VER
|
||||
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define GFLAGS_DLL_DECLARE_FLAG __attribute__((visibility("default")))
|
||||
# else
|
||||
# define GFLAGS_DLL_DECLARE_FLAG
|
||||
# endif
|
||||
|
@ -120,6 +133,9 @@ typedef std::string clstring;
|
|||
#define DECLARE_int32(name) \
|
||||
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
|
||||
|
||||
#define DECLARE_uint32(name) \
|
||||
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name)
|
||||
|
||||
#define DECLARE_int64(name) \
|
||||
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
|
||||
|
||||
|
@ -132,7 +148,6 @@ typedef std::string clstring;
|
|||
#define DECLARE_string(name) \
|
||||
/* We always want to import declared variables, dll or no */ \
|
||||
namespace fLS { \
|
||||
using ::fLS::clstring; \
|
||||
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
|
||||
} \
|
||||
using fLS::FLAGS_##name
|
||||
|
|
|
@ -77,6 +77,7 @@ using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
|
|||
using GFLAGS_NAMESPACE::ReadFromFlagsFile;
|
||||
using GFLAGS_NAMESPACE::BoolFromEnv;
|
||||
using GFLAGS_NAMESPACE::Int32FromEnv;
|
||||
using GFLAGS_NAMESPACE::Uint32FromEnv;
|
||||
using GFLAGS_NAMESPACE::Int64FromEnv;
|
||||
using GFLAGS_NAMESPACE::Uint64FromEnv;
|
||||
using GFLAGS_NAMESPACE::DoubleFromEnv;
|
||||
|
|
|
@ -48,22 +48,22 @@
|
|||
// called after all flag-values have been assigned, that is, after
|
||||
// parsing the command-line.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "config.h"
|
||||
#include "gflags.h"
|
||||
#include "gflags_completions.h"
|
||||
#include "gflags/gflags.h"
|
||||
#include "gflags/gflags_completions.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
// The 'reporting' flags. They all call gflags_exitfunc().
|
||||
DEFINE_bool (help, false, "show help on all flags [tip: all flags can have two dashes]");
|
||||
DEFINE_bool (helpfull, false, "show help on all flags -- same as -help");
|
||||
DEFINE_bool (helpful, false, "show help on all flags -- same as -help");
|
||||
DEFINE_bool (helpshort, false, "show help on only the main module for this program");
|
||||
DEFINE_string(helpon, "", "show help on the modules named by this flag value");
|
||||
DEFINE_string(helpmatch, "", "show help on modules whose name contains the specified substr");
|
||||
|
@ -123,10 +123,11 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
|
|||
flag.description.c_str());
|
||||
const char* c_string = main_part.c_str();
|
||||
int chars_left = static_cast<int>(main_part.length());
|
||||
string final_string = "";
|
||||
string final_string;
|
||||
int chars_in_line = 0; // how many chars in current line so far?
|
||||
while (1) {
|
||||
assert(chars_left == strlen(c_string)); // Unless there's a \0 in there?
|
||||
assert(static_cast<size_t>(chars_left)
|
||||
== strlen(c_string)); // Unless there's a \0 in there?
|
||||
const char* newline = strchr(c_string, '\n');
|
||||
if (newline == NULL && chars_in_line+chars_left < kLineLength) {
|
||||
// The whole remainder of the string fits on this line
|
||||
|
@ -274,9 +275,9 @@ static void ShowUsageWithFlagsMatching(const char *argv0,
|
|||
++flag) {
|
||||
if (substrings.empty() ||
|
||||
FileMatchesSubstring(flag->filename, substrings)) {
|
||||
found_match = true; // this flag passed the match!
|
||||
// If the flag has been stripped, pretend that it doesn't exist.
|
||||
if (flag->description == kStrippedFlagHelp) continue;
|
||||
found_match = true; // this flag passed the match!
|
||||
if (flag->filename != last_filename) { // new file
|
||||
if (Dirname(flag->filename) != Dirname(last_filename)) { // new dir!
|
||||
if (!first_directory)
|
||||
|
@ -295,10 +296,10 @@ static void ShowUsageWithFlagsMatching(const char *argv0,
|
|||
}
|
||||
}
|
||||
|
||||
void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict) {
|
||||
void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict_) {
|
||||
vector<string> substrings;
|
||||
if (restrict != NULL && *restrict != '\0') {
|
||||
substrings.push_back(restrict);
|
||||
if (restrict_ != NULL && *restrict_ != '\0') {
|
||||
substrings.push_back(restrict_);
|
||||
}
|
||||
ShowUsageWithFlagsMatching(argv0, substrings);
|
||||
}
|
||||
|
@ -352,7 +353,7 @@ static void ShowVersion() {
|
|||
|
||||
static void AppendPrognameStrings(vector<string>* substrings,
|
||||
const char* progname) {
|
||||
string r("");
|
||||
string r;
|
||||
r += PATH_SEPARATOR;
|
||||
r += progname;
|
||||
substrings->push_back(r + ".");
|
||||
|
@ -382,14 +383,14 @@ void HandleCommandLineHelpFlags() {
|
|||
ShowUsageWithFlagsMatching(progname, substrings);
|
||||
gflags_exitfunc(1);
|
||||
|
||||
} else if (FLAGS_help || FLAGS_helpfull) {
|
||||
} else if (FLAGS_help || FLAGS_helpful) {
|
||||
// show all options
|
||||
ShowUsageWithFlagsRestrict(progname, ""); // empty restrict
|
||||
gflags_exitfunc(1);
|
||||
|
||||
} else if (!FLAGS_helpon.empty()) {
|
||||
string restrict = PATH_SEPARATOR + FLAGS_helpon + ".";
|
||||
ShowUsageWithFlagsRestrict(progname, restrict.c_str());
|
||||
string restrict_ = PATH_SEPARATOR + FLAGS_helpon + ".";
|
||||
ShowUsageWithFlagsRestrict(progname, restrict_.c_str());
|
||||
gflags_exitfunc(1);
|
||||
|
||||
} else if (!FLAGS_helpmatch.empty()) {
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
#ifndef GFLAGS_MUTEX_H_
|
||||
#define GFLAGS_MUTEX_H_
|
||||
|
||||
#include "gflags_declare.h" // to figure out pthreads support
|
||||
#include "gflags/gflags_declare.h" // to figure out pthreads support
|
||||
|
||||
#if defined(NO_THREADS)
|
||||
typedef int MutexType; // to keep a lock-count
|
||||
|
@ -166,7 +166,7 @@ class Mutex {
|
|||
// It inhibits work being done by the destructor, which makes it
|
||||
// safer for code that tries to acqiure this mutex in their global
|
||||
// destructor.
|
||||
inline Mutex(LinkerInitialized);
|
||||
explicit inline Mutex(LinkerInitialized);
|
||||
|
||||
// Destructor
|
||||
inline ~Mutex();
|
||||
|
@ -197,7 +197,7 @@ class Mutex {
|
|||
inline void SetIsSafe() { is_safe_ = true; }
|
||||
|
||||
// Catch the error of writing Mutex when intending MutexLock.
|
||||
Mutex(Mutex* /*ignored*/) {}
|
||||
explicit Mutex(Mutex* /*ignored*/) {}
|
||||
// Disallow "evil" constructors
|
||||
Mutex(const Mutex&);
|
||||
void operator=(const Mutex&);
|
||||
|
@ -344,8 +344,5 @@ class WriterMutexLock {
|
|||
|
||||
} // namespace MUTEX_NAMESPACE
|
||||
|
||||
using namespace MUTEX_NAMESPACE;
|
||||
|
||||
#undef MUTEX_NAMESPACE
|
||||
|
||||
#endif /* #define GFLAGS_MUTEX_H__ */
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <config.h>
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
@ -88,9 +87,10 @@ typedef unsigned char uint8;
|
|||
|
||||
// -- utility macros ---------------------------------------------------------
|
||||
|
||||
template <bool> struct CompileAssert {};
|
||||
template <bool b> struct CompileAssert;
|
||||
template <> struct CompileAssert<true> {};
|
||||
#define COMPILE_ASSERT(expr, msg) \
|
||||
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
|
||||
enum { assert_##msg = sizeof(CompileAssert<bool(expr)>) }
|
||||
|
||||
// Returns the number of elements in an array.
|
||||
#define arraysize(arr) (sizeof(arr)/sizeof(*(arr)))
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
// These call the windows _vsnprintf, but always NUL-terminate.
|
||||
#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
|
||||
#if !(defined(_MSC_VER) && _MSC_VER >= 1900) /* msvc 2015 already defines */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
|
@ -68,4 +69,5 @@ int snprintf(char *str, size_t size, const char *format, ...) {
|
|||
return r;
|
||||
}
|
||||
|
||||
#endif /* if !(defined(_MSC_VER) && _MSC_VER >= 1900) */
|
||||
#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
|
||||
|
|
|
@ -63,18 +63,21 @@
|
|||
* name vsnprintf, since windows defines that (but not snprintf (!)).
|
||||
*/
|
||||
#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
|
||||
#if !(defined(_MSC_VER) && _MSC_VER >= 1900) /* msvc 2015 already defines */
|
||||
extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size,
|
||||
const char *format, ...);
|
||||
extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size,
|
||||
const char *format, va_list ap);
|
||||
#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
|
||||
#define va_copy(dst, src) (dst) = (src)
|
||||
#endif
|
||||
#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4996) // ignore getenv security warning
|
||||
#endif
|
||||
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
|
||||
inline void setenv(const char* name, const char* value, int) {
|
||||
// In windows, it's impossible to set a variable to the empty string.
|
||||
// We handle this by setting it to "0" and the NUL-ing out the \0.
|
||||
|
@ -96,6 +99,7 @@ inline void setenv(const char* name, const char* value, int) {
|
|||
*getenv(name) = '\0'; // works when putenv() copies nameval
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
@ -107,10 +111,14 @@ inline void setenv(const char* name, const char* value, int) {
|
|||
#define unlink _unlink
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#define PRId32 "d"
|
||||
#define PRIu32 "u"
|
||||
#define PRId64 "I64d"
|
||||
#define PRIu64 "I64u"
|
||||
#endif
|
||||
|
||||
#if !defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
#define strtoq _strtoi64
|
||||
|
|
|
@ -12,16 +12,22 @@ set (GFLAGS_FLAGFILES_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
|||
# ----------------------------------------------------------------------------
|
||||
# common include directories and link libraries
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
include_directories ("${gflags_SOURCE_DIR}/src")
|
||||
include_directories ("${gflags_BINARY_DIR}/include")
|
||||
include_directories ("${gflags_BINARY_DIR}/include/gflags")
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (type shared)
|
||||
if (GFLAGS_IS_A_DLL)
|
||||
add_definitions(-DGFLAGS_IS_A_DLL)
|
||||
endif ()
|
||||
else ()
|
||||
set (type static)
|
||||
endif ()
|
||||
if (BUILD_gflags_LIB)
|
||||
link_libraries (gflags-${type})
|
||||
link_libraries (gflags_${type})
|
||||
else ()
|
||||
link_libraries (gflags_nothreads-${type})
|
||||
link_libraries (gflags_nothreads_${type})
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
@ -34,6 +40,7 @@ add_test (
|
|||
NAME strip_flags_binary
|
||||
COMMAND "${CMAKE_COMMAND}" "-DBINARY=$<TARGET_FILE:gflags_strip_flags_test>"
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.cmake"
|
||||
CONFIGURATIONS Release MinSizeRel
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
@ -70,8 +77,8 @@ add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string
|
|||
add_gflags_test(nohelp 0 "PASS" "" gflags_unittest --nohelp)
|
||||
add_gflags_test(help=false 0 "PASS" "" gflags_unittest --help=false)
|
||||
|
||||
# --helpfull is the same as help
|
||||
add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helpfull)
|
||||
# --helpful is the same as help
|
||||
add_gflags_test(helpful 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helpful)
|
||||
|
||||
# --helpshort should show only flags from the gflags_unittest itself
|
||||
add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest --helpshort)
|
||||
|
@ -133,8 +140,8 @@ add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittes
|
|||
add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=version)
|
||||
add_gflags_test(fromenv=help 0 "PASS" "" gflags_unittest --fromenv=help)
|
||||
add_gflags_test(tryfromenv=help 0 "PASS" "" gflags_unittest --tryfromenv=help)
|
||||
add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" gflags_unittest --fromenv=helpfull)
|
||||
add_gflags_test(tryfromenv=helpfull 0 "PASS" "" gflags_unittest --tryfromenv=helpfull)
|
||||
add_gflags_test(fromenv=helpful 1 "helpful not found in environment" "" gflags_unittest --fromenv=helpful)
|
||||
add_gflags_test(tryfromenv=helpful 0 "PASS" "" gflags_unittest --tryfromenv=helpful)
|
||||
add_gflags_test(tryfromenv=undefok 0 "PASS" "" gflags_unittest --tryfromenv=undefok --foo)
|
||||
add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" gflags_unittest --tryfromenv=weirdo)
|
||||
add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=test_bool,version,unused_bool)
|
||||
|
@ -162,24 +169,59 @@ add_test(NAME gflags_declare COMMAND gflags_declare_test --message "Hello gflags
|
|||
set_tests_properties(gflags_declare PROPERTIES PASS_REGULAR_EXPRESSION "Hello gflags!")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# (negative) compilation tests
|
||||
if (BUILD_NC_TESTS)
|
||||
# qnx specific test installation (ctest not compatible)
|
||||
if (QNX)
|
||||
install (
|
||||
DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
DESTINATION ${RUNTIME_INSTALL_DIR}/gflags_tests
|
||||
)
|
||||
install (
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/test/
|
||||
DESTINATION ${RUNTIME_INSTALL_DIR}/gflags_tests
|
||||
FILES_MATCHING
|
||||
PATTERN "flagfile.*"
|
||||
PATTERN "gflags_unittest_flagfile"
|
||||
PATTERN "config" EXCLUDE
|
||||
PATTERN "nc" EXCLUDE
|
||||
)
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# configure Python script which configures and builds a test project
|
||||
if (BUILD_NC_TESTS OR BUILD_CONFIG_TESTS)
|
||||
find_package (PythonInterp)
|
||||
if (NOT PYTHON_EXECUTABLE)
|
||||
message (FATAL_ERROR "No Python installation found! It is required by the negative compilation tests."
|
||||
" Either install Python or set BUILD_NC_TESTS to FALSE and try again.")
|
||||
message (FATAL_ERROR "No Python installation found! It is required by the (negative) compilation tests."
|
||||
" Either install Python or set BUILD_NC_TESTS and BUILD_CONFIG_TESTS to FALSE.")
|
||||
endif ()
|
||||
set (SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/nc")
|
||||
configure_file (gflags_nc.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" @ONLY)
|
||||
macro (add_gflags_nc_test name)
|
||||
set (TMPDIR "${PROJECT_BINARY_DIR}/Testing/Temporary")
|
||||
configure_file (gflags_build.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py" @ONLY)
|
||||
function (add_gflags_build_test name srcdir expect_fail)
|
||||
set (srcdir "${CMAKE_CURRENT_SOURCE_DIR}/${srcdir}")
|
||||
add_test (
|
||||
NAME nc_${name}
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" ${name}
|
||||
NAME "${name}"
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py"
|
||||
${name} ${srcdir} ${expect_fail}
|
||||
)
|
||||
endmacro ()
|
||||
add_gflags_nc_test (sanity)
|
||||
add_gflags_nc_test (swapped_args)
|
||||
add_gflags_nc_test (int_instead_of_bool)
|
||||
add_gflags_nc_test (bool_in_quotes)
|
||||
add_gflags_nc_test (define_string_with_0)
|
||||
endfunction ()
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# negative compilation tests
|
||||
option (BUILD_NC_TESTS "Request addition of negative compilation tests." OFF)
|
||||
mark_as_advanced (BUILD_NC_TESTS)
|
||||
if (BUILD_NC_TESTS)
|
||||
add_gflags_build_test (nc_sanity nc 0)
|
||||
add_gflags_build_test (nc_swapped_args nc 1)
|
||||
add_gflags_build_test (nc_int_instead_of_bool nc 1)
|
||||
add_gflags_build_test (nc_bool_in_quotes nc 1)
|
||||
add_gflags_build_test (nc_define_string_with_0 nc 1)
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# build configuration test
|
||||
option (BUILD_CONFIG_TESTS "Request addition of package configuration tests." OFF)
|
||||
mark_as_advanced (BUILD_CONFIG_TESTS)
|
||||
if (BUILD_CONFIG_TESTS)
|
||||
add_gflags_build_test (cmake_config config 0)
|
||||
endif ()
|
||||
|
|
10
test/config/CMakeLists.txt
Normal file
10
test/config/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
## gflags package configuration tests
|
||||
|
||||
cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
project (gflags_${TEST_NAME})
|
||||
|
||||
find_package (gflags REQUIRED)
|
||||
|
||||
add_executable (foo main.cc)
|
||||
target_link_libraries (foo gflags::gflags)
|
20
test/config/main.cc
Normal file
20
test/config/main.cc
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <iostream>
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
DEFINE_string(message, "Hello World!", "The message to print");
|
||||
|
||||
static bool ValidateMessage(const char* flagname, const std::string &message)
|
||||
{
|
||||
return !message.empty();
|
||||
}
|
||||
DEFINE_validator(message, ValidateMessage);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
gflags::SetUsageMessage("Test CMake configuration of gflags library (gflags-config.cmake)");
|
||||
gflags::SetVersionString("0.1");
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::cout << FLAGS_message << std::endl;
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
return 0;
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
// All Rights Reserved.
|
||||
//
|
||||
//
|
||||
// This file is needed for windows -- unittests are not part of the
|
||||
// gflags dll, but still want to include config.h just like the
|
||||
// dll does, so they can use internal tools and APIs for testing.
|
||||
//
|
||||
// The problem is that config.h declares GFLAGS_DLL_DECL to be
|
||||
// for exporting symbols, but the unittest needs to *import* symbols
|
||||
// (since it's not the dll).
|
||||
//
|
||||
// The solution is to have this file, which is just like config.h but
|
||||
// sets GFLAGS_DLL_DECL to do a dllimport instead of a dllexport.
|
||||
//
|
||||
// The reason we need this extra GFLAGS_DLL_DECL_FOR_UNITTESTS
|
||||
// variable is in case people want to set GFLAGS_DLL_DECL explicitly
|
||||
// to something other than __declspec(dllexport). In that case, they
|
||||
// may want to use something other than __declspec(dllimport) for the
|
||||
// unittest case. For that, we allow folks to define both
|
||||
// GFLAGS_DLL_DECL and GFLAGS_DLL_DECL_FOR_UNITTESTS explicitly.
|
||||
//
|
||||
// NOTE: This file is equivalent to config.h on non-windows systems,
|
||||
// which never defined GFLAGS_DLL_DECL_FOR_UNITTESTS and always
|
||||
// define GFLAGS_DLL_DECL to the empty string.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef GFLAGS_DLL_DECL
|
||||
# undef GFLAGS_DLL_DECL
|
||||
#endif
|
||||
#ifdef GFLAGS_DLL_DEFINE_FLAG
|
||||
# undef GFLAGS_DLL_DEFINE_FLAG
|
||||
#endif
|
||||
#ifdef GFLAGS_DLL_DECLARE_FLAG
|
||||
# undef GFLAGS_DLL_DECLARE_FLAG
|
||||
#endif
|
||||
|
||||
#ifdef GFLAGS_DLL_DECL_FOR_UNITTESTS
|
||||
# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS
|
||||
#else
|
||||
# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
|
||||
#endif
|
||||
|
||||
// Import flags defined by gflags.cc
|
||||
#if GFLAGS_IS_A_DLL && defined(_MSC_VER)
|
||||
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
|
||||
#else
|
||||
# define GFLAGS_DLL_DECLARE_FLAG
|
||||
#endif
|
43
test/gflags_build.py.in
Normal file
43
test/gflags_build.py.in
Normal file
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
CMAKE = '@CMAKE_COMMAND@'
|
||||
CMAKE_BUILD_TYPE = '@CMAKE_BUILD_TYPE@'
|
||||
TMPDIR = '@TMPDIR@'
|
||||
SRCDIR = '@SRCDIR@'
|
||||
GFLAGS_DIR = '@gflags_BINARY_DIR@'
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 4:
|
||||
sys.stderr.write(' '.join(['usage:', sys.argv[0], '<test_name> <srcdir> <expect_fail:0|1>\n']))
|
||||
sys.exit(1)
|
||||
test_name = sys.argv[1]
|
||||
srcdir = sys.argv[2]
|
||||
expect_fail = (sys.argv[3].lower() in ['true', 'yes', 'on', '1'])
|
||||
bindir = os.path.join(TMPDIR, test_name)
|
||||
if TMPDIR == '':
|
||||
sys.stderr.write('Temporary directory not set!\n')
|
||||
sys.exit(1)
|
||||
# create build directory
|
||||
if os.path.isdir(bindir): shutil.rmtree(bindir)
|
||||
os.makedirs(bindir)
|
||||
# configure the build tree
|
||||
if subprocess.call([CMAKE, '-DCMAKE_BUILD_TYPE:STRING='+CMAKE_BUILD_TYPE,
|
||||
'-Dgflags_DIR:PATH='+GFLAGS_DIR,
|
||||
'-DTEST_NAME:STRING='+test_name, srcdir], cwd=bindir) != 0:
|
||||
sys.stderr.write('Failed to configure the build tree!\n')
|
||||
sys.exit(1)
|
||||
# build the test project
|
||||
exit_code = subprocess.call([CMAKE, '--build', bindir, '--config', CMAKE_BUILD_TYPE], cwd=bindir)
|
||||
if expect_fail == True:
|
||||
if exit_code == 0:
|
||||
sys.stderr.write('Build expected to fail, but it succeeded!\n')
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.stderr.write('Build failed as expected\n')
|
||||
exit_code = 0
|
||||
sys.exit(exit_code)
|
5
test/gflags_declare_flags.cc
Normal file → Executable file
5
test/gflags_declare_flags.cc
Normal file → Executable file
|
@ -1,8 +1,13 @@
|
|||
// The macro can already be defined when using Unity builds.
|
||||
#undef GFLAGS_DLL_DECLARE_FLAG
|
||||
#define GFLAGS_DLL_DECLARE_FLAG
|
||||
|
||||
#include <iostream>
|
||||
#include <gflags/gflags_declare.h>
|
||||
|
||||
DECLARE_string(message); // in gflags_delcare_test.cc
|
||||
|
||||
void print_message();
|
||||
void print_message()
|
||||
{
|
||||
std::cout << FLAGS_message << std::endl;
|
||||
|
|
|
@ -5,8 +5,8 @@ void print_message(); // in gflags_declare_flags.cc
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
gflags::SetUsageMessage("Test compilation and use of gflags_declare.h");
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
GFLAGS_NAMESPACE::SetUsageMessage("Test compilation and use of gflags_declare.h");
|
||||
GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
|
||||
print_message();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
CMAKE = '@CMAKE_COMMAND@'
|
||||
TMPDIR = '@TEMPDIR@'
|
||||
SRCDIR = '@SRCDIR@'
|
||||
GFLAGS_DIR = '@gflags_BINARY_DIR@'
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
sys.stderr.write(' '.join(['usage:', sys.argv[0], '<test_name>\n']))
|
||||
sys.exit(1)
|
||||
test_name = sys.argv[1]
|
||||
bindir = os.path.join(TMPDIR, '_'.join(['nc', test_name]))
|
||||
if TMPDIR == '':
|
||||
sys.stderr.write('Temporary directory not set!\n')
|
||||
sys.exit(1)
|
||||
# create build directory
|
||||
if os.path.isdir(bindir): shutil.rmtree(bindir)
|
||||
os.makedirs(bindir)
|
||||
# configure the build tree
|
||||
if subprocess.call([CMAKE, '-Dgflags_DIR:PATH='+GFLAGS_DIR, '-DTEST_NAME:STRING='+test_name, SRCDIR], cwd=bindir) != 0:
|
||||
sys.stderr.write('Failed to configure the build tree!\n')
|
||||
sys.exit(1)
|
||||
# try build, which is supposed to fail (except in case of the sanity check)
|
||||
if subprocess.call([CMAKE, '--build', bindir], cwd=bindir) == 0 and test_name != 'sanity':
|
||||
sys.stderr.write('Build expected to fail, but it succeeded!\n')
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
1
test/gflags_strip_flags_test.cc
Normal file → Executable file
1
test/gflags_strip_flags_test.cc
Normal file → Executable file
|
@ -34,7 +34,6 @@
|
|||
// script that runs 'strings' over this program and makes sure
|
||||
// that the help string is not in there.
|
||||
|
||||
#include "config_for_unittests.h"
|
||||
#define STRIP_FLAG_HELP 1
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
if (NOT BINARY)
|
||||
message (FATAl_ERROR "BINARY file to check not specified!")
|
||||
message (FATAL_ERROR "BINARY file to check not specified!")
|
||||
endif ()
|
||||
file (STRINGS "${BINARY}" strings REGEX "This text should be stripped out")
|
||||
if (strings)
|
||||
message (FATAL_ERROR "Text not stripped from binary like it should be: ${BINARY}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
|
76
test/gflags_unittest.cc
Normal file → Executable file
76
test/gflags_unittest.cc
Normal file → Executable file
|
@ -32,9 +32,11 @@
|
|||
// For now, this unit test does not cover all features of
|
||||
// gflags.cc
|
||||
|
||||
#include "config_for_unittests.h"
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <math.h> // for isinf() and isnan()
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -44,7 +46,6 @@
|
|||
#endif
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "util.h"
|
||||
TEST_INIT
|
||||
EXPECT_DEATH_INIT
|
||||
|
||||
|
@ -74,6 +75,7 @@ DECLARE_string(tryfromenv); // in gflags.cc
|
|||
DEFINE_bool(test_bool, false, "tests bool-ness");
|
||||
DEFINE_int32(test_int32, -1, "");
|
||||
DEFINE_int64(test_int64, -2, "");
|
||||
DEFINE_uint32(test_uint32, 1, "");
|
||||
DEFINE_uint64(test_uint64, 2, "");
|
||||
DEFINE_double(test_double, -1.0, "");
|
||||
DEFINE_string(test_string, "initial", "");
|
||||
|
@ -114,6 +116,7 @@ DEFINE_string(changeable_string_var, ChangeableString(), "");
|
|||
DEFINE_bool(unused_bool, true, "unused bool-ness");
|
||||
DEFINE_int32(unused_int32, -1001, "");
|
||||
DEFINE_int64(unused_int64, -2001, "");
|
||||
DEFINE_uint32(unused_uint32, 1000, "");
|
||||
DEFINE_uint64(unused_uint64, 2000, "");
|
||||
DEFINE_double(unused_double, -1000.0, "");
|
||||
DEFINE_string(unused_string, "unused", "");
|
||||
|
@ -213,7 +216,7 @@ namespace fLI {
|
|||
int32 FLAGS_tldflag1 = FLAGS_nonotldflag1;
|
||||
int32 FLAGS_notldflag1 = FLAGS_nonotldflag1;
|
||||
static FlagRegisterer o_tldflag1(
|
||||
"tldflag1", "int32",
|
||||
"tldflag1",
|
||||
"should show up in --helpshort", "gflags_unittest.cc",
|
||||
&FLAGS_tldflag1, &FLAGS_notldflag1);
|
||||
}
|
||||
|
@ -224,7 +227,7 @@ namespace fLI {
|
|||
int32 FLAGS_tldflag2 = FLAGS_nonotldflag2;
|
||||
int32 FLAGS_notldflag2 = FLAGS_nonotldflag2;
|
||||
static FlagRegisterer o_tldflag2(
|
||||
"tldflag2", "int32",
|
||||
"tldflag2",
|
||||
"should show up in --helpshort", "gflags_unittest.",
|
||||
&FLAGS_tldflag2, &FLAGS_notldflag2);
|
||||
}
|
||||
|
@ -276,6 +279,7 @@ TEST(FlagTypes, FlagTypes) {
|
|||
AssertIsType<bool>(FLAGS_test_bool);
|
||||
AssertIsType<int32>(FLAGS_test_int32);
|
||||
AssertIsType<int64>(FLAGS_test_int64);
|
||||
AssertIsType<uint32>(FLAGS_test_uint32);
|
||||
AssertIsType<uint64>(FLAGS_test_uint64);
|
||||
AssertIsType<double>(FLAGS_test_double);
|
||||
AssertIsType<string>(FLAGS_test_string);
|
||||
|
@ -353,6 +357,19 @@ TEST(FlagFileTest, ReadFlagsFromString) {
|
|||
false,
|
||||
123,
|
||||
123.0);
|
||||
|
||||
// Test that flags can use dashes instead of underscores.
|
||||
TestFlagString(
|
||||
// Flag string
|
||||
"-test-string=initial\n"
|
||||
"--test-bool=false\n"
|
||||
"--test-int32=123\n"
|
||||
"--test-double=123.0\n",
|
||||
// Expected values
|
||||
"initial",
|
||||
false,
|
||||
123,
|
||||
123.0);
|
||||
}
|
||||
|
||||
// Tests the filename part of the flagfile
|
||||
|
@ -590,11 +607,15 @@ TEST(SetFlagValueTest, IllegalValues) {
|
|||
FLAGS_test_bool = true;
|
||||
FLAGS_test_int32 = 119;
|
||||
FLAGS_test_int64 = 1191;
|
||||
FLAGS_test_uint64 = 11911;
|
||||
FLAGS_test_uint32 = 11911;
|
||||
FLAGS_test_uint64 = 119111;
|
||||
|
||||
EXPECT_EQ("",
|
||||
SetCommandLineOption("test_bool", "12"));
|
||||
|
||||
EXPECT_EQ("",
|
||||
SetCommandLineOption("test_uint32", "-1970"));
|
||||
|
||||
EXPECT_EQ("",
|
||||
SetCommandLineOption("test_int32", "7000000000000"));
|
||||
|
||||
|
@ -608,6 +629,7 @@ TEST(SetFlagValueTest, IllegalValues) {
|
|||
EXPECT_EQ("", SetCommandLineOption("test_bool", ""));
|
||||
EXPECT_EQ("", SetCommandLineOption("test_int32", ""));
|
||||
EXPECT_EQ("", SetCommandLineOption("test_int64", ""));
|
||||
EXPECT_EQ("", SetCommandLineOption("test_uint32", ""));
|
||||
EXPECT_EQ("", SetCommandLineOption("test_uint64", ""));
|
||||
EXPECT_EQ("", SetCommandLineOption("test_double", ""));
|
||||
EXPECT_EQ("test_string set to \n", SetCommandLineOption("test_string", ""));
|
||||
|
@ -615,7 +637,8 @@ TEST(SetFlagValueTest, IllegalValues) {
|
|||
EXPECT_TRUE(FLAGS_test_bool);
|
||||
EXPECT_EQ(119, FLAGS_test_int32);
|
||||
EXPECT_EQ(1191, FLAGS_test_int64);
|
||||
EXPECT_EQ(11911, FLAGS_test_uint64);
|
||||
EXPECT_EQ(11911, FLAGS_test_uint32);
|
||||
EXPECT_EQ(119111, FLAGS_test_uint64);
|
||||
}
|
||||
|
||||
|
||||
|
@ -668,14 +691,19 @@ TEST(FromEnvTest, LegalValues) {
|
|||
EXPECT_EQ(-1, Int32FromEnv("INT_VAL2", 10));
|
||||
EXPECT_EQ(10, Int32FromEnv("INT_VAL_UNKNOWN", 10));
|
||||
|
||||
setenv("INT_VAL3", "1099511627776", 1);
|
||||
setenv("INT_VAL3", "4294967295", 1);
|
||||
EXPECT_EQ(1, Uint32FromEnv("INT_VAL1", 10));
|
||||
EXPECT_EQ(4294967295L, Uint32FromEnv("INT_VAL3", 30));
|
||||
EXPECT_EQ(10, Uint32FromEnv("INT_VAL_UNKNOWN", 10));
|
||||
|
||||
setenv("INT_VAL4", "1099511627776", 1);
|
||||
EXPECT_EQ(1, Int64FromEnv("INT_VAL1", 20));
|
||||
EXPECT_EQ(-1, Int64FromEnv("INT_VAL2", 20));
|
||||
EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL3", 20));
|
||||
EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL4", 20));
|
||||
EXPECT_EQ(20, Int64FromEnv("INT_VAL_UNKNOWN", 20));
|
||||
|
||||
EXPECT_EQ(1, Uint64FromEnv("INT_VAL1", 30));
|
||||
EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL3", 30));
|
||||
EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL4", 30));
|
||||
EXPECT_EQ(30, Uint64FromEnv("INT_VAL_UNKNOWN", 30));
|
||||
|
||||
// I pick values here that can be easily represented exactly in floating-point
|
||||
|
@ -711,6 +739,11 @@ TEST(FromEnvDeathTest, IllegalValues) {
|
|||
EXPECT_DEATH(Int32FromEnv("INT_BAD3", 10), "error parsing env variable");
|
||||
EXPECT_DEATH(Int32FromEnv("INT_BAD4", 10), "error parsing env variable");
|
||||
|
||||
EXPECT_DEATH(Uint32FromEnv("INT_BAD1", 10), "error parsing env variable");
|
||||
EXPECT_DEATH(Uint32FromEnv("INT_BAD2", 10), "error parsing env variable");
|
||||
EXPECT_DEATH(Uint32FromEnv("INT_BAD3", 10), "error parsing env variable");
|
||||
EXPECT_DEATH(Uint32FromEnv("INT_BAD4", 10), "error parsing env variable");
|
||||
|
||||
setenv("BIGINT_BAD1", "18446744073709551616000", 1);
|
||||
EXPECT_DEATH(Int64FromEnv("INT_BAD1", 20), "error parsing env variable");
|
||||
EXPECT_DEATH(Int64FromEnv("INT_BAD3", 20), "error parsing env variable");
|
||||
|
@ -814,9 +847,10 @@ TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
|
|||
// Initializes the flags.
|
||||
FLAGS_test_bool = false;
|
||||
FLAGS_test_int32 = -1;
|
||||
FLAGS_test_int64 = -2;
|
||||
FLAGS_test_uint64 = 3;
|
||||
FLAGS_test_double = 4.0;
|
||||
FLAGS_test_uint32 = 2;
|
||||
FLAGS_test_int64 = -3;
|
||||
FLAGS_test_uint64 = 4;
|
||||
FLAGS_test_double = 5.0;
|
||||
FLAGS_test_string = "good";
|
||||
|
||||
// Saves the flag states.
|
||||
|
@ -826,8 +860,9 @@ TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
|
|||
// Modifies the flags.
|
||||
FLAGS_test_bool = true;
|
||||
FLAGS_test_int32 = -5;
|
||||
FLAGS_test_int64 = -6;
|
||||
FLAGS_test_uint64 = 7;
|
||||
FLAGS_test_uint32 = 6;
|
||||
FLAGS_test_int64 = -7;
|
||||
FLAGS_test_uint64 = 8;
|
||||
FLAGS_test_double = 8.0;
|
||||
FLAGS_test_string = "bad";
|
||||
|
||||
|
@ -837,9 +872,10 @@ TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
|
|||
// Verifies the flag values were restored.
|
||||
EXPECT_FALSE(FLAGS_test_bool);
|
||||
EXPECT_EQ(-1, FLAGS_test_int32);
|
||||
EXPECT_EQ(-2, FLAGS_test_int64);
|
||||
EXPECT_EQ(3, FLAGS_test_uint64);
|
||||
EXPECT_DOUBLE_EQ(4.0, FLAGS_test_double);
|
||||
EXPECT_EQ(2, FLAGS_test_uint32);
|
||||
EXPECT_EQ(-3, FLAGS_test_int64);
|
||||
EXPECT_EQ(4, FLAGS_test_uint64);
|
||||
EXPECT_DOUBLE_EQ(5.0, FLAGS_test_double);
|
||||
EXPECT_EQ("good", FLAGS_test_string);
|
||||
}
|
||||
|
||||
|
@ -1332,7 +1368,7 @@ TEST(ParseCommandLineFlagsWrongFields,
|
|||
// addresses of these variables will be overwritten... Stack smash!
|
||||
static bool current_storage;
|
||||
static bool defvalue_storage;
|
||||
FlagRegisterer fr("flag_name", "bool", 0, "filename",
|
||||
FlagRegisterer fr("flag_name", NULL, "filename",
|
||||
¤t_storage, &defvalue_storage);
|
||||
CommandLineFlagInfo fi;
|
||||
EXPECT_TRUE(GetCommandLineFlagInfo("flag_name", &fi));
|
||||
|
@ -1485,7 +1521,7 @@ TEST(FlagsValidator, FlagSaver) {
|
|||
|
||||
} // unnamed namespace
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
static int main(int argc, char **argv) {
|
||||
|
||||
// Run unit tests only if called without arguments, otherwise this program
|
||||
// is used by an "external" usage test
|
||||
|
@ -1514,7 +1550,7 @@ int main(int argc, char **argv) {
|
|||
// The non-recommended way:
|
||||
FLAGS_changed_bool2 = true;
|
||||
|
||||
SetUsageMessage(usage_message.c_str());
|
||||
SetUsageMessage(usage_message);
|
||||
SetVersionString("test_version");
|
||||
ParseCommandLineFlags(&argc, &argv, true);
|
||||
MakeTmpdir(&FLAGS_test_tmpdir);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
## gflags negative compilation tests
|
||||
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
if (NOT TEST_NAME)
|
||||
message (FATAL_ERROR "Missing TEST_NAME CMake flag")
|
||||
endif ()
|
||||
string (TOUPPER ${TEST_NAME} TEST_NAME_UPPER)
|
||||
|
||||
project (gflags_nc_${TEST_NAME})
|
||||
project (gflags_${TEST_NAME})
|
||||
|
||||
find_package (gflags REQUIRED)
|
||||
include_directories (${gflags_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
link_libraries (gflags_nothreads)
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
add_definitions (-DTEST_${TEST_NAME_UPPER})
|
||||
add_executable (gflags_nc_${TEST_NAME} gflags_nc.cc)
|
||||
add_executable (gflags_${TEST_NAME} gflags_nc.cc)
|
||||
target_link_libraries(gflags_${TEST_NAME} gflags)
|
||||
|
|
|
@ -33,33 +33,33 @@
|
|||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#if defined(TEST_SWAPPED_ARGS)
|
||||
#if defined(TEST_NC_SWAPPED_ARGS)
|
||||
|
||||
DEFINE_bool(some_bool_flag,
|
||||
"the default value should go here, not the description",
|
||||
false);
|
||||
|
||||
|
||||
#elif defined(TEST_INT_INSTEAD_OF_BOOL)
|
||||
#elif defined(TEST_NC_INT_INSTEAD_OF_BOOL)
|
||||
|
||||
DEFINE_bool(some_bool_flag_2,
|
||||
0,
|
||||
"should have been an int32 flag but mistakenly used bool instead");
|
||||
|
||||
#elif defined(TEST_BOOL_IN_QUOTES)
|
||||
#elif defined(TEST_NC_BOOL_IN_QUOTES)
|
||||
|
||||
|
||||
DEFINE_bool(some_bool_flag_3,
|
||||
"false",
|
||||
"false in in quotes, which is wrong");
|
||||
|
||||
#elif defined(TEST_SANITY)
|
||||
#elif defined(TEST_NC_SANITY)
|
||||
|
||||
DEFINE_bool(some_bool_flag_4,
|
||||
true,
|
||||
"this is the correct usage of DEFINE_bool");
|
||||
|
||||
#elif defined(TEST_DEFINE_STRING_WITH_0)
|
||||
#elif defined(TEST_NC_DEFINE_STRING_WITH_0)
|
||||
|
||||
DEFINE_string(some_string_flag,
|
||||
0,
|
||||
|
|
Loading…
Add table
Reference in a new issue