Skip to content

Commit 749b03e

Browse files
authored
utils: refactor getopt into utils namespace (#9796)
On certain linux, macOS environment, there is already a system getopt. This often creates conflict when compiling filament. Here we alias utils::getopt to either the system getopt (if present) or third_party/getopt. Fixes #7551
1 parent 497a1cc commit 749b03e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+716
-654
lines changed

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,12 @@ endfunction()
869869
# Sub-projects
870870
# ==================================================================================================
871871

872+
include(CheckSymbolExists)
873+
check_symbol_exists(getopt_long "getopt.h" HAS_SYSTEM_GETOPT)
874+
if (NOT HAS_SYSTEM_GETOPT)
875+
add_subdirectory(${EXTERNAL}/getopt)
876+
endif()
877+
872878
# Common to all platforms
873879
add_subdirectory(${EXTERNAL}/libgtest/tnt)
874880
add_subdirectory(${LIBRARIES}/camutils)
@@ -904,7 +910,6 @@ add_subdirectory(${EXTERNAL}/cgltf/tnt)
904910
add_subdirectory(${EXTERNAL}/draco/tnt)
905911
add_subdirectory(${EXTERNAL}/jsmn/tnt)
906912
add_subdirectory(${EXTERNAL}/stb/tnt)
907-
add_subdirectory(${EXTERNAL}/getopt)
908913
add_subdirectory(${EXTERNAL}/perfetto/tnt)
909914
add_subdirectory(${EXTERNAL}/basisu/tnt)
910915

filament/backend/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,6 @@ if (FILAMENT_BUILD_TESTING)
616616
set(BACKEND_TEST_LIBS
617617
absl::str_format
618618
backend
619-
getopt
620619
gtest
621620
imageio
622621
filamat
@@ -725,7 +724,6 @@ if (FILAMENT_BUILD_TESTING)
725724

726725
target_link_libraries(metal_utils_test PRIVATE
727726
backend
728-
getopt
729727
gtest
730728
)
731729

filament/backend/test/Arguments.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#include "PlatformRunner.h"
1818

19-
#include <getopt/getopt.h>
19+
#include <utils/getopt.h>
2020

2121
#include <iostream>
2222
#include <string>
@@ -30,18 +30,18 @@ TestArguments parseArguments(int argc, char* argv[]) {
3030
// The first colon in OPTSTR turns on silent error reporting. This is important, as the
3131
// arguments may also contain gtest parameters we don't know about.
3232
static constexpr const char* OPTSTR = ":a:kc";
33-
static const struct option OPTIONS[] = {
34-
{ "api", required_argument, nullptr, 'a' },
35-
{ "headless_only", no_argument, nullptr, 'k' },
36-
{ "ci", no_argument, nullptr, 'c' },
37-
{ nullptr, 0, nullptr, 0 } // termination of the option list
33+
static const utils::getopt::option OPTIONS[] = {
34+
{ "api", utils::getopt::required_argument, nullptr, 'a' },
35+
{ "headless_only", utils::getopt::no_argument, nullptr, 'k' },
36+
{ "ci", utils::getopt::no_argument, nullptr, 'c' },
37+
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
3838
};
3939

4040
int opt;
4141
int optionIndex = 0;
4242

43-
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
44-
std::string arg(optarg ? optarg : "");
43+
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
44+
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
4545
switch (opt) {
4646
case 'a':
4747
if (arg == "opengl") {

libs/filament-matp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
4444
target_include_directories(${TARGET} PRIVATE ${filamat_SOURCE_DIR}/src)
4545

4646
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
47-
target_link_libraries(${TARGET} getopt filamat filabridge utils)
47+
target_link_libraries(${TARGET} filamat filabridge utils)
4848

4949
# ==================================================================================================
5050
# Installation

libs/filamentapp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ set(LIBS
5252
filament
5353
filament-iblprefilter
5454
geometry
55-
getopt
55+
5656
image
5757
imageio
5858
imgui

libs/utils/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(PUBLIC_HDR_DIR include)
1212
file(GLOB_RECURSE PUBLIC_HDRS ${PUBLIC_HDR_DIR}/${TARGET}/*.h)
1313

1414
set(DIST_HDRS
15+
${PUBLIC_HDR_DIR}/${TARGET}/getopt.h
1516
${PUBLIC_HDR_DIR}/${TARGET}/algorithm.h
1617
${PUBLIC_HDR_DIR}/${TARGET}/bitset.h
1718
${PUBLIC_HDR_DIR}/${TARGET}/CallStack.h
@@ -122,6 +123,11 @@ endif()
122123
include_directories(${PUBLIC_HDR_DIR})
123124

124125
add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS})
126+
if (HAS_SYSTEM_GETOPT)
127+
target_compile_definitions(${TARGET} PUBLIC HAS_SYSTEM_GETOPT)
128+
else()
129+
target_link_libraries(${TARGET} PUBLIC getopt)
130+
endif()
125131
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
126132
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
127133
target_link_libraries(${TARGET} PUBLIC tsl)

libs/utils/include/utils/getopt.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (C) 2026 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
18+
#ifndef UTILS_GETOPT_H
19+
#define UTILS_GETOPT_H
20+
21+
// If system has getopt, we just include it
22+
#if defined(HAS_SYSTEM_GETOPT)
23+
#include <getopt.h>
24+
#else
25+
#include <getopt/getopt.h>
26+
#endif
27+
28+
#ifdef __cplusplus
29+
30+
#undef no_argument
31+
#undef required_argument
32+
#undef optional_argument
33+
34+
// This is an aliasing of getopt to prevent compilation conflicts with the system getop (if
35+
// it exists). Please refer to third_party/getopt for API details.
36+
namespace utils {
37+
namespace getopt {
38+
using ::getopt;
39+
using ::optarg;
40+
using ::optind;
41+
using ::opterr;
42+
using ::optopt;
43+
using ::option;
44+
using ::getopt_long;
45+
using ::getopt_long_only;
46+
47+
constexpr int no_argument = 0;
48+
constexpr int required_argument = 1;
49+
constexpr int optional_argument = 2;
50+
}
51+
}
52+
#endif // __cplusplus
53+
54+
#endif // UTILS_GETOPT_H

samples/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ add_library(samples-common STATIC
228228
)
229229

230230
target_include_directories(samples-common PRIVATE
231-
${ROOT_DIR}/third_party/getopt/include
232231
)
233232
target_link_libraries(samples-common filament)
234233

samples/common/arguments.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
#include <utils/Path.h>
2222

23-
#include <getopt/getopt.h>
23+
#include <utils/getopt.h>
2424

2525
#include <iostream>
2626
#include <string>
@@ -73,16 +73,16 @@ filament::Engine::Backend parseArgumentsForBackend(int argc, char* argv[]) {
7373
// The first colon in OPTSTR turns on silent error reporting. This is important, as the
7474
// arguments may also contain gtest parameters we don't know about.
7575
static constexpr const char* OPTSTR = "ha:";
76-
static const struct option OPTIONS[] = {
77-
{ "help", no_argument, nullptr, 'h' },
78-
{ "api", required_argument, nullptr, 'a' },
76+
static const utils::getopt::option OPTIONS[] = {
77+
{ "help", utils::getopt::no_argument, nullptr, 'h' },
78+
{ "api", utils::getopt::required_argument, nullptr, 'a' },
7979
{ nullptr, 0, nullptr, 0 }
8080
};
8181
int opt;
8282
int optionIndex = 0;
8383

84-
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
85-
std::string arg(optarg ? optarg : "");
84+
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &optionIndex)) >= 0) {
85+
std::string arg(utils::getopt::optarg ? utils::getopt::optarg : "");
8686
switch (opt) {
8787
default:
8888
case 'h':

samples/frame_generator.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#include <math/vec3.h>
6969
#include <math/vec4.h>
7070

71-
#include <getopt/getopt.h>
71+
#include <utils/getopt.h>
7272

7373
#include <algorithm>
7474
#include <atomic>
@@ -151,7 +151,7 @@ static void printUsage(char* name) {
151151
" Prints this message\n\n"
152152
"API_USAGE"
153153
" --ibl=<path to cmgen IBL>, -i <path>\n"
154-
" Applies an IBL generated by cmgen's deploy option\n\n"
154+
" Applies an IBL generated by cmgen's deploy utils::getopt::option\n\n"
155155
" --scale=[number], -s [number]\n"
156156
" Applies uniform scale\n\n"
157157
" --material=<path>, -m <path>\n"
@@ -186,25 +186,25 @@ static void printUsage(char* name) {
186186
// Parses command line arguments and populates the Config object.
187187
static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
188188
static constexpr const char* OPTSTR = "ha:s:li:m:c:p:x:yb:S:";
189-
static const struct option OPTIONS[] = {
190-
{ "help", no_argument, nullptr, 'h' },
191-
{ "api", required_argument, nullptr, 'a' },
192-
{ "ibl", required_argument, nullptr, 'i' },
193-
{ "scale", required_argument, nullptr, 's' },
194-
{ "material", required_argument, nullptr, 'm' },
195-
{ "params", required_argument, nullptr, 'p' },
196-
{ "count", required_argument, nullptr, 'c' },
197-
{ "light-on", no_argument, nullptr, 'l' },
198-
{ "skybox-off", no_argument, nullptr, 'y' },
199-
{ "prefix", required_argument, nullptr, 'x' },
200-
{ "clear-color", required_argument, nullptr, 'b' },
201-
{ "size", required_argument, nullptr, 'S' },
202-
{ nullptr, 0, nullptr, 0 } // termination of the option list
189+
static const utils::getopt::option OPTIONS[] = {
190+
{ "help", utils::getopt::no_argument, nullptr, 'h' },
191+
{ "api", utils::getopt::required_argument, nullptr, 'a' },
192+
{ "ibl", utils::getopt::required_argument, nullptr, 'i' },
193+
{ "scale", utils::getopt::required_argument, nullptr, 's' },
194+
{ "material", utils::getopt::required_argument, nullptr, 'm' },
195+
{ "params", utils::getopt::required_argument, nullptr, 'p' },
196+
{ "count", utils::getopt::required_argument, nullptr, 'c' },
197+
{ "light-on", utils::getopt::no_argument, nullptr, 'l' },
198+
{ "skybox-off", utils::getopt::no_argument, nullptr, 'y' },
199+
{ "prefix", utils::getopt::required_argument, nullptr, 'x' },
200+
{ "clear-color", utils::getopt::required_argument, nullptr, 'b' },
201+
{ "size", utils::getopt::required_argument, nullptr, 'S' },
202+
{ nullptr, 0, nullptr, 0 } // termination of the utils::getopt::option list
203203
};
204204
int opt;
205205
int option_index = 0;
206-
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
207-
std::string const arg(optarg ? optarg : "");
206+
while ((opt = utils::getopt::getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
207+
std::string const arg(utils::getopt::optarg ? utils::getopt::optarg : "");
208208
switch (opt) {
209209
default:
210210
case 'h':
@@ -272,7 +272,7 @@ static int handleCommandLineArguments(int argc, char* argv[], Config* config) {
272272
}
273273
}
274274

275-
return optind;
275+
return utils::getopt::optind;
276276
}
277277

278278
// Cleans up Filament resources (entities, materials, etc.) before exit.

0 commit comments

Comments
 (0)