From a6e4a95d6c6fb7ae4a91dff94763a9577f57d81e Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Jan 2014 15:58:45 -0500 Subject: Compute resource directory on startup Add a findResourceDir function to locate resources relative to the executable location at the start of main and a getResourceDir function to lookup the result later. --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 14 ++++++++- src/SourceDir.txt.in | 1 + src/Utils.cxx | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Utils.h | 30 ++++++++++++++++++++ src/castxml.cxx | 6 ++++ 6 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/SourceDir.txt.in create mode 100644 src/Utils.cxx create mode 100644 src/Utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 37a0d1b..81a2151 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,8 @@ endif() set(KWSYS_NAMESPACE cxsys) set(KWSYS_USE_Encoding 1) +set(KWSYS_USE_RegularExpression 1) +set(KWSYS_USE_SystemTools 1) set(KWSYS_HEADER_ROOT ${CastXML_BINARY_DIR}/src) add_subdirectory(src/kwsys) include_directories(${KWSYS_HEADER_ROOT}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f497e4f..97e1a02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,11 +14,23 @@ # limitations under the License. #============================================================================= +# Tell executables in the build tree where to find the source tree. +configure_file( + "SourceDir.txt.in" + "${CastXML_BINARY_DIR}/CMakeFiles/castxmlSourceDir.txt" @ONLY + ) + llvm_map_components_to_libraries(llvm_libs native option bitreader) -add_executable(castxml castxml.cxx) +add_executable(castxml + castxml.cxx + + Utils.cxx Utils.h + ) target_link_libraries(castxml cxsys ${llvm_libs} ) +set_property(SOURCE Utils.cxx APPEND PROPERTY COMPILE_DEFINITIONS + "CASTXML_INSTALL_DATA_DIR=\"${CastXML_INSTALL_DATA_DIR}\"") install(TARGETS castxml DESTINATION ${CastXML_INSTALL_RUNTIME_DIR}) diff --git a/src/SourceDir.txt.in b/src/SourceDir.txt.in new file mode 100644 index 0000000..a607cf7 --- /dev/null +++ b/src/SourceDir.txt.in @@ -0,0 +1 @@ +@CastXML_SOURCE_DIR@ diff --git a/src/Utils.cxx b/src/Utils.cxx new file mode 100644 index 0000000..bc556e3 --- /dev/null +++ b/src/Utils.cxx @@ -0,0 +1,80 @@ +/* + Copyright Kitware, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "Utils.h" + +#include +#include +#include + +static std::string castxmlResourceDir; + +//---------------------------------------------------------------------------- +static std::string GetMainExecutable(const char* argv0) +{ + return llvm::sys::fs::getMainExecutable + (argv0, (void*)(intptr_t)GetMainExecutable); +} + +//---------------------------------------------------------------------------- +static bool tryBuildDir(std::string const& dir) +{ + // Build tree has + // /CMakeFiles/castxmlSourceDir.txt + std::string src_dir_txt = dir + "/CMakeFiles/castxmlSourceDir.txt"; + std::ifstream src_fin(src_dir_txt.c_str()); + std::string src_dir; + if(src_fin && cxsys::SystemTools::GetLineFromStream(src_fin, src_dir) && + cxsys::SystemTools::FileIsDirectory(src_dir.c_str())) { + castxmlResourceDir = src_dir + "/share/castxml"; + return true; + } + return false; +} + +//---------------------------------------------------------------------------- +bool findResourceDir(const char* argv0, std::ostream& error) +{ + std::string exe = GetMainExecutable(argv0); + if(!cxsys::SystemTools::FileIsFullPath(exe.c_str())) { + error << "error: unable to locate " << argv0 << "\n"; + return false; + } + std::string exe_dir = cxsys::SystemTools::GetFilenamePath(exe); + + // Install tree has + // /bin/castxml + // / + std::string dir = cxsys::SystemTools::GetFilenamePath(exe_dir); + castxmlResourceDir = dir + "/" + CASTXML_INSTALL_DATA_DIR; + if(!cxsys::SystemTools::FileIsDirectory(castxmlResourceDir.c_str())) { + // Build tree has + // /bin[/]/castxml + if(!tryBuildDir(dir) && + !tryBuildDir(cxsys::SystemTools::GetFilenamePath(dir))) { + error << "Unable to locate resources for " << exe << "\n"; + return false; + } + } + + return true; +} + +//---------------------------------------------------------------------------- +std::string getResourceDir() +{ + return castxmlResourceDir; +} diff --git a/src/Utils.h b/src/Utils.h new file mode 100644 index 0000000..7ea3a41 --- /dev/null +++ b/src/Utils.h @@ -0,0 +1,30 @@ +/* + Copyright Kitware, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#ifndef CASTXML_UTILS_H +#define CASTXML_UTILS_H + +#include +#include + +/// findResources - Call from main() to find resources +/// relative to the executable. On success returns true. +/// On failure returns false and stores a message in the stream. +bool findResourceDir(const char* argv0, std::ostream& error); + +/// getResourceDir - Get resource directory found at startup +std::string getResourceDir(); + +#endif // CASTXML_UTILS_H diff --git a/src/castxml.cxx b/src/castxml.cxx index dacbe83..ee303ab 100644 --- a/src/castxml.cxx +++ b/src/castxml.cxx @@ -14,7 +14,10 @@ limitations under the License. */ +#include "Utils.h" + #include +#include //---------------------------------------------------------------------------- int main(int argc, const char* const * argv) @@ -23,6 +26,9 @@ int main(int argc, const char* const * argv) cxsys::Encoding::CommandLineArguments::Main(argc, argv); argc = args.argc(); argv = args.argv(); + if(!findResourceDir(argv[0], std::cerr)) { + return 1; + } (void)argc; (void)argv; return 0; -- cgit v0.12