| 59 | | const char* env_dir = std::getenv("GADGET_BASE_DIR"); |
|---|
| 60 | | #endif |
|---|
| 61 | | |
|---|
| 62 | | if ( NULL == env_dir ) |
|---|
| 63 | | { |
|---|
| 64 | | char tmppath[1024]; |
|---|
| 65 | | std::memset(tmppath, 0, sizeof(tmppath)); |
|---|
| 66 | | GetModuleFileName(module, tmppath, sizeof(tmppath)); |
|---|
| 67 | | |
|---|
| 68 | | try |
|---|
| 69 | | { |
|---|
| 70 | | fs::path dll_path(tmppath, fs::native); |
|---|
| 71 | | fs::path base_dir = dll_path.branch_path().branch_path(); |
|---|
| | 68 | env_dir = std::getenv("GADGET_BASE_DIR"); |
|---|
| | 69 | #endif |
|---|
| | 70 | |
|---|
| | 71 | try |
|---|
| | 72 | { |
|---|
| | 73 | fs::path base_dir; |
|---|
| | 74 | |
|---|
| | 75 | // If GADGET_BASE_DIR is not set, look up the path to this |
|---|
| | 76 | // DLL and use it to provide a default setting for that |
|---|
| | 77 | // environment variable. |
|---|
| | 78 | if ( NULL == env_dir ) |
|---|
| | 79 | { |
|---|
| | 80 | char tmppath[1024]; |
|---|
| | 81 | std::memset(tmppath, 0, sizeof(tmppath)); |
|---|
| | 82 | GetModuleFileName(module, tmppath, sizeof(tmppath)); |
|---|
| | 83 | |
|---|
| | 84 | const fs::path dll_path(tmppath, fs::native); |
|---|
| | 85 | base_dir = dll_path.branch_path().branch_path(); |
|---|
| 87 | | catch (fs::filesystem_error& ex) |
|---|
| 88 | | { |
|---|
| 89 | | std::cerr << "Automatic assignment of GADGET_BASE_DIR failed:\n" |
|---|
| 90 | | << ex.what() << std::endl; |
|---|
| 91 | | } |
|---|
| 92 | | } |
|---|
| 93 | | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| 94 | | else |
|---|
| 95 | | { |
|---|
| 96 | | std::free(env_dir); |
|---|
| 97 | | } |
|---|
| 98 | | #endif |
|---|
| | 103 | else |
|---|
| | 104 | { |
|---|
| | 105 | base_dir = fs::path(env_dir, fs::native); |
|---|
| | 106 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| | 107 | std::free(env_dir); |
|---|
| | 108 | env_dir = NULL; |
|---|
| | 109 | #endif |
|---|
| | 110 | } |
|---|
| | 111 | |
|---|
| | 112 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| | 113 | _dupenv_s(&env_dir, &len, "GADGET_DATA_DIR"); |
|---|
| | 114 | #else |
|---|
| | 115 | env_dir = std::getenv("GADGET_DATA_DIR"); |
|---|
| | 116 | #endif |
|---|
| | 117 | |
|---|
| | 118 | // If GADGET_BASE_DIR is not set, set a default relative to |
|---|
| | 119 | // base_dir. |
|---|
| | 120 | if ( NULL == env_dir ) |
|---|
| | 121 | { |
|---|
| | 122 | fs::path data_dir(base_dir / "share" / "gadgeteer"); |
|---|
| | 123 | const std::string data_dir_str = |
|---|
| | 124 | data_dir.native_directory_string(); |
|---|
| | 125 | |
|---|
| | 126 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| | 127 | _putenv_s("GADGET_DATA_DIR", data_dir_str.c_str()); |
|---|
| | 128 | #else |
|---|
| | 129 | std::ostringstream env_stream; |
|---|
| | 130 | env_stream << "GADGET_DATA_DIR=" << data_dir_str; |
|---|
| | 131 | putenv(env_stream.str().c_str()); |
|---|
| | 132 | #endif |
|---|
| | 133 | } |
|---|
| | 134 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| | 135 | else |
|---|
| | 136 | { |
|---|
| | 137 | std::free(env_dir); |
|---|
| | 138 | env_dir = NULL; |
|---|
| | 139 | } |
|---|
| | 140 | #endif |
|---|
| | 141 | } |
|---|
| | 142 | catch (fs::filesystem_error& ex) |
|---|
| | 143 | { |
|---|
| | 144 | std::cerr << "Automatic assignment of Gadgeteer environment " |
|---|
| | 145 | << "variables failed:\n" << ex.what() << std::endl; |
|---|
| | 146 | |
|---|
| | 147 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
|---|
| | 148 | if ( NULL != env_dir ) |
|---|
| | 149 | { |
|---|
| | 150 | std::free(env_dir); |
|---|
| | 151 | } |
|---|
| | 152 | #endif |
|---|
| | 153 | } |
|---|
| 107 | | |
|---|
| 108 | | |
|---|
| | 162 | #else |
|---|
| | 163 | /** |
|---|
| | 164 | * Non-Windows shared library constructor. This ensures that the environment |
|---|
| | 165 | * variable \c GADGET_BASE_DIR is set as soon as this shared library is loaded. |
|---|
| | 166 | * If it is not set, then it sets it based on an assumption about the |
|---|
| | 167 | * structure of a Gadgeteer installation. More specifically, an assumption is |
|---|
| | 168 | * made that this shared library lives in the \c lib subdirectory of the |
|---|
| | 169 | * Gadgeteer installation. Therefore, the root of the Gadgeteer installation |
|---|
| | 170 | * is the parent of the directory containing this shared library. |
|---|
| | 171 | */ |
|---|
| | 172 | extern "C" void __attribute ((constructor)) gadgetLibraryInit() |
|---|
| | 173 | { |
|---|
| | 174 | fs::path base_dir; |
|---|
| | 175 | const char* env_dir = std::getenv("GADGET_BASE_DIR"); |
|---|
| | 176 | |
|---|
| | 177 | // If GADGET_BASE_DIR is not set, look up the path to this shared library |
|---|
| | 178 | // and use it to provide a default setting for that environment variable. |
|---|
| | 179 | if ( NULL == env_dir ) |
|---|
| | 180 | { |
|---|
| | 181 | Dl_info info; |
|---|
| | 182 | info.dli_fname = 0; |
|---|
| | 183 | const int result = |
|---|
| | 184 | #if defined(__GNUC__) && __GNUC_MAJOR__ < 4 |
|---|
| | 185 | dladdr((void*) &gadgetLibraryInit, &info); |
|---|
| | 186 | #else |
|---|
| | 187 | dladdr(reinterpret_cast<void*>(&gadgetLibraryInit), &info); |
|---|
| | 188 | #endif |
|---|
| | 189 | |
|---|
| | 190 | // NOTE: dladdr(3) really does return a non-zero value on success. |
|---|
| | 191 | if ( 0 != result ) |
|---|
| | 192 | { |
|---|
| | 193 | try |
|---|
| | 194 | { |
|---|
| | 195 | fs::path lib_file(info.dli_fname, fs::native); |
|---|
| | 196 | lib_file = fs::system_complete(lib_file); |
|---|
| | 197 | |
|---|
| | 198 | #if defined(VPR_OS_IRIX) && defined(_ABIN32) |
|---|
| | 199 | const std::string bit_suffix("32"); |
|---|
| | 200 | #elif defined(VPR_OS_IRIX) && defined(_ABI64) || \ |
|---|
| | 201 | defined(VPR_OS_Linux) && defined(__x86_64__) |
|---|
| | 202 | const std::string bit_suffix("64"); |
|---|
| | 203 | #else |
|---|
| | 204 | const std::string bit_suffix(""); |
|---|
| | 205 | #endif |
|---|
| | 206 | |
|---|
| | 207 | // Get the directory containing this shared library. |
|---|
| | 208 | const fs::path lib_path = lib_file.branch_path(); |
|---|
| | 209 | |
|---|
| | 210 | // Start the search for the root of the Gadgeteer installation in |
|---|
| | 211 | // the parent of the directory containing this shared library. |
|---|
| | 212 | base_dir = lib_path.branch_path(); |
|---|
| | 213 | |
|---|
| | 214 | // Use the lib subdirectory to figure out when we have found the |
|---|
| | 215 | // root of the Gadgeteer installation tree. |
|---|
| | 216 | const fs::path lib_subdir(std::string("lib") + bit_suffix); |
|---|
| | 217 | |
|---|
| | 218 | bool found(false); |
|---|
| | 219 | while ( ! found && ! base_dir.empty() ) |
|---|
| | 220 | { |
|---|
| | 221 | try |
|---|
| | 222 | { |
|---|
| | 223 | if ( ! fs::exists(base_dir / lib_subdir) ) |
|---|
| | 224 | { |
|---|
| | 225 | base_dir = base_dir.branch_path(); |
|---|
| | 226 | } |
|---|
| | 227 | else |
|---|
| | 228 | { |
|---|
| | 229 | found = true; |
|---|
| | 230 | } |
|---|
| | 231 | } |
|---|
| | 232 | catch (fs::filesystem_error&) |
|---|
| | 233 | { |
|---|
| | 234 | base_dir = base_dir.branch_path(); |
|---|
| | 235 | } |
|---|
| | 236 | } |
|---|
| | 237 | |
|---|
| | 238 | if ( found ) |
|---|
| | 239 | { |
|---|
| | 240 | setenv("GADGET_BASE_DIR", |
|---|
| | 241 | base_dir.native_directory_string().c_str(), 1); |
|---|
| | 242 | } |
|---|
| | 243 | } |
|---|
| | 244 | catch (fs::filesystem_error& ex) |
|---|
| | 245 | { |
|---|
| | 246 | std::cerr << "Automatic assignment of GADGET_BASE_DIR failed:\n" |
|---|
| | 247 | << ex.what() << std::endl; |
|---|
| | 248 | } |
|---|
| | 249 | } |
|---|
| | 250 | } |
|---|
| | 251 | else |
|---|
| | 252 | { |
|---|
| | 253 | base_dir = fs::path(env_dir, fs::native); |
|---|
| | 254 | } |
|---|
| | 255 | |
|---|
| | 256 | if ( ! base_dir.empty() ) |
|---|
| | 257 | { |
|---|
| | 258 | // If base_dir were empty, this would result in data_dir being relative |
|---|
| | 259 | // to the current working directory. |
|---|
| | 260 | const fs::path data_dir = base_dir / GADGET_SHARE_DIR; |
|---|
| | 261 | |
|---|
| | 262 | // We use the overwrite value of 0 as a way around testing whether the |
|---|
| | 263 | // environment variable is already set. |
|---|
| | 264 | setenv("GADGET_DATA_DIR", data_dir.native_directory_string().c_str(), 0); |
|---|
| | 265 | } |
|---|
| | 266 | } |
|---|