Skip to content

Commit 7a73271

Browse files
committed
build: Better detect (and permit disabling) std::filesystem in CMake.
This should transparently identify when it's available in standard or experimental forms, as well as when it requires stdc++fs to be linked.
1 parent fb885a3 commit 7a73271

File tree

5 files changed

+110
-8
lines changed

5 files changed

+110
-8
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
- pr.188.gh.OpenXR-SDK-Source
3+
---
4+
Allow disabling of std::filesystem usage, and detect if it's available and what its requirements are.

src/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@
1717
# Author:
1818
#
1919

20+
if(POLICY CMP0075)
21+
cmake_policy(SET CMP0075 NEW)
22+
endif()
23+
2024
# Entire project uses C++14
2125
set(CMAKE_CXX_STANDARD 14)
2226
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
2327
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
2428

2529
include(GNUInstallDirs)
30+
include(StdFilesystemFlags)
2631

2732
### Dependencies
2833
set(OpenGL_GL_PREFERENCE GLVND)
@@ -61,6 +66,7 @@ option(
6166
"Enable exception handling in the loader. Leave this on unless your standard library is built to not throw."
6267
ON
6368
)
69+
6470
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
6571
option(DYNAMIC_LOADER "Build the loader as a .dll library" OFF)
6672
else()
@@ -80,6 +86,8 @@ include(CMakeDependentOption)
8086
cmake_dependent_option(
8187
BUILD_WITH_SYSTEM_JSONCPP "Use system jsoncpp instead of vendored source" ON "JSONCPP_FOUND" OFF
8288
)
89+
cmake_dependent_option(BUILD_WITH_STD_FILESYSTEM "Use std::[experimental::]filesystem." ON
90+
"HAVE_FILESYSTEM_WITHOUT_LIB OR HAVE_FILESYSTEM_NEEDING_LIB" OFF)
8391

8492
# Several files use these compile-time OS switches
8593
if(WIN32)
@@ -90,7 +98,7 @@ endif()
9098

9199
# /EHsc (support for C++ exceptions) is default in most configurations but seems missing when building arm/arm64.
92100
if(MSVC)
93-
set(CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}")
101+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
94102
endif()
95103

96104
# This is a little helper library for setting up OpenGL

src/cmake/StdFilesystemFlags.cmake

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright 2020, Collabora, Ltd.
2+
#
3+
# SPDX-License-Identifier: BSL-1.0
4+
5+
include(CheckCXXSourceCompiles)
6+
set(_stdfs_test_source
7+
"bool is_reg_file(const std::string &path) { return fs::is_regular_file(path); }
8+
int main() {
9+
(void)is_reg_file(\"/etc/os-release\");
10+
return 0;
11+
}
12+
"
13+
)
14+
set(_stdfs_source
15+
"#if __cplusplus >= 201703L
16+
#include <filesystem>
17+
namespace fs = std::filesystem;
18+
#endif
19+
${_stdfs_test_source}
20+
"
21+
)
22+
set(_stdfs_experimental_source
23+
"#if __cplusplus < 201703L
24+
#include <experimental/filesystem>
25+
namespace fs = std::experimental::filesystem;
26+
#endif
27+
${_stdfs_test_source}
28+
"
29+
)
30+
set(_stdfs_needlib_source
31+
"#if __cplusplus >= 201703L
32+
#include <filesystem>
33+
namespace fs = std::filesystem;
34+
#else
35+
#include <experimental/filesystem>
36+
namespace fs = std::experimental::filesystem;
37+
#endif
38+
${_stdfs_test_source}
39+
"
40+
)
41+
42+
# First, just look for the include.
43+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
44+
set(CMAKE_REQUIRED_LIBRARIES)
45+
check_cxx_source_compiles("${_stdfs_source}" HAVE_FILESYSTEM_IN_STD)
46+
check_cxx_source_compiles("${_stdfs_experimental_source}" HAVE_FILESYSTEM_IN_STDEXPERIMENTAL)
47+
48+
set(CMAKE_REQUIRED_FLAGS "-DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=TRUE")
49+
check_cxx_source_compiles("${_stdfs_source}" HAVE_FILESYSTEM_IN_STD_17)
50+
unset(CMAKE_REQUIRED_FLAGS)
51+
52+
if(HAVE_FILESYSTEM_IN_STD_17 AND NOT HAVE_FILESYSTEM_IN_STD)
53+
set(HAVE_FILESYSTEM_NEEDS_17
54+
ON
55+
CACHE INTERNAL ""
56+
)
57+
set(CMAKE_REQUIRED_FLAGS "-DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=TRUE")
58+
else()
59+
set(HAVE_FILESYSTEM_NEEDS_17
60+
OFF
61+
CACHE INTERNAL ""
62+
)
63+
endif()
64+
65+
# Now, see if we need
66+
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
67+
check_cxx_source_compiles("${_stdfs_needlib_source}" HAVE_FILESYSTEM_WITHOUT_LIB)
68+
set(CMAKE_REQUIRED_LIBRARIES stdc++fs)
69+
check_cxx_source_compiles("${_stdfs_needlib_source}" HAVE_FILESYSTEM_NEEDING_LIB)
70+
71+
function(openxr_add_filesystem_utils TARGET_NAME)
72+
target_sources(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/src/common/filesystem_utils.cpp)
73+
target_include_directories(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/src/common)
74+
if(NOT BUILD_WITH_STD_FILESYSTEM)
75+
target_compile_definitions(${TARGET_NAME} PRIVATE DISABLE_STD_FILESYSTEM)
76+
else()
77+
if(HAVE_FILESYSTEM_NEEDS_17)
78+
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 17)
79+
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD_REQUIRED TRUE)
80+
endif()
81+
if(HAVE_FILESYSTEM_NEEDING_LIB AND NOT HAVE_FILESYSTEM_WITHOUT_LIB)
82+
target_link_libraries(${TARGET_NAME} PRIVATE stdc++fs)
83+
endif()
84+
endif()
85+
endfunction()

src/loader/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ add_library(openxr_loader ${LIBRARY_TYPE}
5959
runtime_interface.cpp
6060
runtime_interface.hpp
6161
${GENERATED_OUTPUT}
62-
${PROJECT_SOURCE_DIR}/src/common/filesystem_utils.cpp
63-
${PROJECT_SOURCE_DIR}/src/common/filesystem_utils.hpp
6462
${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h
6563
${PROJECT_SOURCE_DIR}/src/common/object_info.cpp
6664
${PROJECT_SOURCE_DIR}/src/common/object_info.h
@@ -117,6 +115,7 @@ target_link_libraries(
117115
)
118116

119117
target_compile_definitions(openxr_loader PRIVATE API_NAME="OpenXR")
118+
openxr_add_filesystem_utils(openxr_loader)
120119

121120
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
122121
set(FALLBACK_CONFIG_DIRS
@@ -145,7 +144,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
145144
set_target_properties(openxr_loader PROPERTIES SOVERSION "${MAJOR}" VERSION "${MAJOR}.${MINOR}.${PATCH}")
146145
target_link_libraries(
147146
openxr_loader
148-
PRIVATE stdc++fs
149147
PUBLIC m
150148
)
151149

src/tests/loader_test/CMakeLists.txt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
add_executable(loader_test
2121
loader_test_utils.cpp
2222
loader_test.cpp
23-
${PROJECT_SOURCE_DIR}/src/common/filesystem_utils.cpp
2423
)
24+
openxr_add_filesystem_utils(loader_test)
2525
set_target_properties(loader_test PROPERTIES FOLDER ${TESTS_FOLDER})
26+
target_link_libraries(loader_test PRIVATE openxr_loader ${CMAKE_THREAD_LIBS_INIT})
2627

2728
add_dependencies(loader_test generate_openxr_header)
2829
if(TARGET openxr-gfxwrapper)
29-
target_link_libraries(loader_test openxr-gfxwrapper)
30+
target_link_libraries(loader_test PRIVATE openxr-gfxwrapper)
3031
endif()
3132
target_include_directories(
3233
loader_test
@@ -47,13 +48,19 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
4748
target_compile_definitions(loader_test PRIVATE _CRT_SECURE_NO_WARNINGS)
4849
target_compile_options(loader_test PRIVATE /Zc:wchar_t /Zc:forScope /W4 /WX)
4950
endif()
50-
target_link_libraries(loader_test openxr_loader opengl32 d3d11)
51+
if(OPENGL_FOUND)
52+
target_link_libraries(loader_test opengl32)
53+
endif()
54+
if(D3D_D3D11_FOUND)
55+
target_link_libraries(loader_test d3d11)
56+
endif()
57+
5158
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
5259
target_compile_options(
5360
loader_test PRIVATE -Wall -Wno-unused-function -Wno-format-truncation
5461
)
5562

56-
target_link_libraries(loader_test -lstdc++fs openxr_loader m -lpthread)
63+
target_link_libraries(loader_test PRIVATE m)
5764
else()
5865
message(FATAL_ERROR "Unsupported Platform")
5966
endif()

0 commit comments

Comments
 (0)