Back to home page

EIC code displayed by LXR

 
 

    


Warning, /acts/cmake/FindFilesystem.cmake is written in an unsupported language. File is not indexed.

0001 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
0002 # file Copyright.txt or https://cmake.org/licensing for details.
0003 
0004 # originally from https://github.com/vector-of-bool/CMakeCM/blob/master/modules/FindFilesystem.cmake
0005 
0006 #[=======================================================================[.rst:
0007 
0008 FindFilesystem
0009 ##############
0010 
0011 This module supports the C++17 standard library's filesystem utilities. Use the
0012 :imp-target:`std::filesystem` imported target to
0013 
0014 Options
0015 *******
0016 
0017 The ``COMPONENTS`` argument to this module supports the following values:
0018 
0019 .. find-component:: Experimental
0020     :name: fs.Experimental
0021 
0022     Allows the module to find the "experimental" Filesystem TS version of the
0023     Filesystem library. This is the library that should be used with the
0024     ``std::experimental::filesystem`` namespace.
0025 
0026 .. find-component:: Final
0027     :name: fs.Final
0028 
0029     Finds the final C++17 standard version of the filesystem library.
0030 
0031 If no components are provided, behaves as if the
0032 :find-component:`fs.Final` component was specified.
0033 
0034 If both :find-component:`fs.Experimental` and :find-component:`fs.Final` are
0035 provided, first looks for ``Final``, and falls back to ``Experimental`` in case
0036 of failure. If ``Final`` is found, :imp-target:`std::filesystem` and all
0037 :ref:`variables <fs.variables>` will refer to the ``Final`` version.
0038 
0039 
0040 Imported Targets
0041 ****************
0042 
0043 .. imp-target:: std::filesystem
0044 
0045     The ``std::filesystem`` imported target is defined when any requested
0046     version of the C++ filesystem library has been found, whether it is
0047     *Experimental* or *Final*.
0048 
0049     If no version of the filesystem library is available, this target will not
0050     be defined.
0051 
0052     .. note::
0053         This target has ``cxx_std_17`` as an ``INTERFACE``
0054         :ref:`compile language standard feature <req-lang-standards>`. Linking
0055         to this target will automatically enable C++17 if no later standard
0056         version is already required on the linking target.
0057 
0058 
0059 .. _fs.variables:
0060 
0061 Variables
0062 *********
0063 
0064 .. variable:: CXX_FILESYSTEM_IS_EXPERIMENTAL
0065 
0066     Set to ``TRUE`` when the :find-component:`fs.Experimental` version of C++
0067     filesystem library was found, otherwise ``FALSE``.
0068 
0069 .. variable:: CXX_FILESYSTEM_HAVE_FS
0070 
0071     Set to ``TRUE`` when a filesystem header was found.
0072 
0073 .. variable:: CXX_FILESYSTEM_HEADER
0074 
0075     Set to either ``filesystem`` or ``experimental/filesystem`` depending on
0076     whether :find-component:`fs.Final` or :find-component:`fs.Experimental` was
0077     found.
0078 
0079 .. variable:: CXX_FILESYSTEM_NAMESPACE
0080 
0081     Set to either ``std::filesystem`` or ``std::experimental::filesystem``
0082     depending on whether :find-component:`fs.Final` or
0083     :find-component:`fs.Experimental` was found.
0084 
0085 
0086 Examples
0087 ********
0088 
0089 Using `find_package(Filesystem)` with no component arguments:
0090 
0091 .. code-block:: cmake
0092 
0093     find_package(Filesystem REQUIRED)
0094 
0095     add_executable(my-program main.cpp)
0096     target_link_libraries(my-program PRIVATE std::filesystem)
0097 
0098 
0099 #]=======================================================================]
0100 
0101 if(TARGET std::filesystem)
0102     # This module has already been processed. Don't do it again.
0103     return()
0104 endif()
0105 
0106 cmake_minimum_required(VERSION 3.10)
0107 
0108 include(CMakePushCheckState)
0109 include(CheckIncludeFileCXX)
0110 
0111 # If we're not cross-compiling, try to run test executables.
0112 # Otherwise, assume that compile + link is a sufficient check.
0113 if(CMAKE_CROSSCOMPILING)
0114     include(CheckCXXSourceCompiles)
0115     macro(_cmcm_check_cxx_source code var)
0116         check_cxx_source_compiles("${code}" ${var})
0117     endmacro()
0118 else()
0119     include(CheckCXXSourceRuns)
0120     macro(_cmcm_check_cxx_source code var)
0121         check_cxx_source_runs("${code}" ${var})
0122     endmacro()
0123 endif()
0124 
0125 cmake_push_check_state()
0126 
0127 set(CMAKE_REQUIRED_QUIET ${Filesystem_FIND_QUIETLY})
0128 
0129 # All of our tests required C++17 or later
0130 if(DEFINED CMAKE_CXX_STANDARD)
0131     set(_prior_cmake_cxx_standard ${CMAKE_CXX_STANDARD})
0132 endif()
0133 
0134 set(CMAKE_CXX_STANDARD 17)
0135 
0136 # Normalize and check the component list we were given
0137 set(want_components ${Filesystem_FIND_COMPONENTS})
0138 if(Filesystem_FIND_COMPONENTS STREQUAL "")
0139     set(want_components Final)
0140 endif()
0141 
0142 # Warn on any unrecognized components
0143 set(extra_components ${want_components})
0144 list(REMOVE_ITEM extra_components Final Experimental)
0145 foreach(component IN LISTS extra_components)
0146     message(
0147         WARNING
0148         "Extraneous find_package component for Filesystem: ${component}"
0149     )
0150 endforeach()
0151 
0152 # Detect which of Experimental and Final we should look for
0153 set(find_experimental TRUE)
0154 set(find_final TRUE)
0155 if(NOT "Final" IN_LIST want_components)
0156     set(find_final FALSE)
0157 endif()
0158 if(NOT "Experimental" IN_LIST want_components)
0159     set(find_experimental FALSE)
0160 endif()
0161 
0162 if(find_final)
0163     check_include_file_cxx("filesystem" _CXX_FILESYSTEM_HAVE_HEADER)
0164     mark_as_advanced(_CXX_FILESYSTEM_HAVE_HEADER)
0165     if(_CXX_FILESYSTEM_HAVE_HEADER)
0166         # We found the non-experimental header. Don't bother looking for the
0167         # experimental one.
0168         set(find_experimental FALSE)
0169     endif()
0170 else()
0171     set(_CXX_FILESYSTEM_HAVE_HEADER FALSE)
0172 endif()
0173 
0174 if(find_experimental)
0175     check_include_file_cxx(
0176         "experimental/filesystem"
0177         _CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER
0178     )
0179     mark_as_advanced(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER)
0180 else()
0181     set(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER FALSE)
0182 endif()
0183 
0184 if(_CXX_FILESYSTEM_HAVE_HEADER)
0185     set(_have_fs TRUE)
0186     set(_fs_header filesystem)
0187     set(_fs_namespace std::filesystem)
0188     set(_is_experimental FALSE)
0189 elseif(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER)
0190     set(_have_fs TRUE)
0191     set(_fs_header experimental/filesystem)
0192     set(_fs_namespace std::experimental::filesystem)
0193     set(_is_experimental TRUE)
0194 else()
0195     set(_have_fs FALSE)
0196 endif()
0197 
0198 set(CXX_FILESYSTEM_HAVE_FS
0199     ${_have_fs}
0200     CACHE BOOL
0201     "TRUE if we have the C++ filesystem headers"
0202 )
0203 set(CXX_FILESYSTEM_HEADER
0204     ${_fs_header}
0205     CACHE STRING
0206     "The header that should be included to obtain the filesystem APIs"
0207 )
0208 set(CXX_FILESYSTEM_NAMESPACE
0209     ${_fs_namespace}
0210     CACHE STRING
0211     "The C++ namespace that contains the filesystem APIs"
0212 )
0213 set(CXX_FILESYSTEM_IS_EXPERIMENTAL
0214     ${_is_experimental}
0215     CACHE BOOL
0216     "TRUE if the C++ filesystem library is the experimental version"
0217 )
0218 
0219 set(_found FALSE)
0220 
0221 if(CXX_FILESYSTEM_HAVE_FS)
0222     # We have some filesystem library available. Do link checks
0223     string(
0224         CONFIGURE
0225         [[
0226         #include <cstdlib>
0227         #include <@CXX_FILESYSTEM_HEADER@>
0228 
0229         int main() {
0230             auto cwd = @CXX_FILESYSTEM_NAMESPACE@::current_path();
0231             printf("%s", cwd.c_str());
0232             return EXIT_SUCCESS;
0233         }
0234     ]]
0235         code
0236         @ONLY
0237     )
0238 
0239     # Check a simple filesystem program without any linker flags
0240     _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
0241 
0242     set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED})
0243 
0244     if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED)
0245         set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES})
0246         # Add the libstdc++ flag
0247         set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lstdc++fs)
0248         _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_STDCPPFS_NEEDED)
0249         set(can_link ${CXX_FILESYSTEM_STDCPPFS_NEEDED})
0250         if(NOT CXX_FILESYSTEM_STDCPPFS_NEEDED)
0251             # Try the libc++ flag
0252             set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lc++fs)
0253             _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_CPPFS_NEEDED)
0254             set(can_link ${CXX_FILESYSTEM_CPPFS_NEEDED})
0255         endif()
0256     endif()
0257 
0258     if(can_link)
0259         add_library(std::filesystem INTERFACE IMPORTED)
0260         set_property(
0261             TARGET std::filesystem
0262             APPEND
0263             PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_17
0264         )
0265         set(_found TRUE)
0266 
0267         if(CXX_FILESYSTEM_NO_LINK_NEEDED)
0268             # Nothing to add...
0269         elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED)
0270             set_property(
0271                 TARGET std::filesystem
0272                 APPEND
0273                 PROPERTY INTERFACE_LINK_LIBRARIES -lstdc++fs
0274             )
0275         elseif(CXX_FILESYSTEM_CPPFS_NEEDED)
0276             set_property(
0277                 TARGET std::filesystem
0278                 APPEND
0279                 PROPERTY INTERFACE_LINK_LIBRARIES -lc++fs
0280             )
0281         endif()
0282     endif()
0283 endif()
0284 
0285 cmake_pop_check_state()
0286 
0287 set(Filesystem_FOUND
0288     ${_found}
0289     CACHE BOOL
0290     "TRUE if we can run a program using std::filesystem"
0291     FORCE
0292 )
0293 
0294 if(DEFINED _prior_cmake_cxx_standard)
0295     set(CMAKE_CXX_STANDARD ${_prior_cmake_cxx_standard})
0296 else()
0297     unset(CMAKE_CXX_STANDARD)
0298 endif()
0299 
0300 if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND)
0301     message(FATAL_ERROR "Cannot run simple program using std::filesystem")
0302 endif()