this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement xcode-select (#264)

+333 -37
+6 -3
src/xcselect/CMakeLists.txt
··· 1 1 project(xcselect) 2 2 3 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc") 3 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -fblocks") 4 4 5 5 set(DYLIB_INSTALL_NAME "/usr/lib/libxcselect.dylib") 6 6 set(DYLIB_COMPAT_VERSION "1.0.0") 7 7 set(DYLIB_CURRENT_VERSION "1.0.0") 8 8 9 - add_darling_library(xcselect libxcselect.c) 9 + add_darling_library(xcselect xcselect.c) 10 10 target_link_libraries(xcselect system) 11 11 12 12 add_darling_executable(xcrun xcrun.c) 13 13 target_link_libraries(xcrun system xcselect) 14 + 15 + add_darling_executable(xcode-select xcode-select.c) 16 + target_link_libraries(xcode-select system xcselect) 14 17 15 18 function(add_shim name) 16 19 add_darling_executable("${name}_shim" xcrun-shim.c) ··· 27 30 add_shim(nm) 28 31 29 32 install(TARGETS xcselect DESTINATION libexec/darling/usr/lib) 30 - install(TARGETS xcrun DESTINATION libexec/darling/usr/bin) 33 + install(TARGETS xcrun xcode-select DESTINATION libexec/darling/usr/bin) 31 34
+125 -32
src/xcselect/libxcselect.c src/xcselect/xcselect.c
··· 26 26 #include <string.h> 27 27 #include <dlfcn.h> 28 28 #include <stdio.h> 29 - #include "libxcselect.h" 29 + #include "xcselect.h" 30 30 31 31 static char path_buffer[1024]; 32 32 ··· 92 92 return false; 93 93 } 94 94 95 - const char* xcselect_find_developer_contents_from_path(const char* p, bool* is_cmd_line) 95 + bool xcselect_find_developer_contents_from_path(const char* p, char* dst, bool* is_cmd_line, size_t dst_size) 96 96 { 97 97 size_t length; 98 98 99 99 if (*p != '/') 100 100 { 101 - getcwd(path_buffer, sizeof(path_buffer)); 102 - strcat(path_buffer, "/"); 103 - strcat(path_buffer, p); 101 + getcwd(dst, dst_size); 102 + strcat(dst, "/"); 103 + strcat(dst, p); 104 104 } 105 105 else 106 - strcpy(path_buffer, p); 106 + strlcpy(dst, p, dst_size); 107 107 108 - length = strlen(path_buffer); 109 - if (valid_dev_path(path_buffer)) 110 - return path_buffer; 108 + length = strlen(dst); 109 + if (valid_dev_path(dst)) 110 + return true; 111 111 112 - path_buffer[length++] = '/'; 113 - path_buffer[length] = 0; 112 + dst[length++] = '/'; 113 + dst[length] = 0; 114 114 115 - strcat(path_buffer, "Library/Developer/CommandLineTools"); 116 - if (valid_dev_path(path_buffer)) 115 + strcat(dst, "Library/Developer/CommandLineTools"); 116 + if (valid_dev_path(dst)) 117 117 { 118 118 *is_cmd_line = true; 119 - return path_buffer; 119 + return true; 120 120 } 121 121 122 - path_buffer[length] = 0; 123 - strcat(path_buffer, "CommandLineTools"); 124 - if (valid_dev_path(path_buffer)) 122 + dst[length] = 0; 123 + strcat(dst, "CommandLineTools"); 124 + if (valid_dev_path(dst)) 125 125 { 126 126 *is_cmd_line = true; 127 - return path_buffer; 127 + return true; 128 128 } 129 129 130 - path_buffer[length] = 0; 131 - strcat(path_buffer, "Contents/Developer"); 132 - if (valid_dev_path(path_buffer)) 133 - return path_buffer; 130 + dst[length] = 0; 131 + strcat(dst, "Contents/Developer"); 132 + if (valid_dev_path(dst)) 133 + return true; 134 134 135 - return NULL; 135 + return false; 136 136 } 137 137 138 - const char* xcselect_get_developer_dir_path(bool* is_cmd_line) 138 + bool xcselect_get_developer_dir_path(char* path, size_t path_len, bool* is_cmd_line) 139 139 { 140 140 const char* p; 141 141 char* slash; ··· 145 145 p = getenv("DEVELOPER_DIR"); 146 146 if (p) 147 147 { 148 - p = xcselect_find_developer_contents_from_path(p, is_cmd_line); 149 - if (p) 148 + if (xcselect_find_developer_contents_from_path(p, path_buffer, is_cmd_line, sizeof(path_buffer))) 149 + { 150 + p = path_buffer; 150 151 goto have_path; 152 + } 151 153 } 152 154 153 155 p = get_developer_dir_from_symlink("/var/db/xcode_select_link"); ··· 173 175 goto have_path; 174 176 } 175 177 176 - return NULL; 178 + return false; 177 179 178 180 have_path: 179 181 slash = strrchr(p, '/'); ··· 183 185 *is_cmd_line = true; 184 186 } 185 187 186 - return p; 188 + strlcpy(path, p, path_len); 189 + strlcat(path, "/", path_len); 190 + return true; 187 191 } 188 192 189 193 190 194 int xcselect_invoke_xcrun(const char* tool, int argc, char* argv[], int flags) 191 195 { 192 - const char* dev_dir; 196 + char dev_dir[1024]; 193 197 bool is_cmdline; 194 198 195 - dev_dir = xcselect_get_developer_dir_path(&is_cmdline); 196 - 197 - if (dev_dir != NULL) 199 + if (xcselect_get_developer_dir_path(dev_dir, sizeof(dev_dir), &is_cmdline)) 198 200 { 199 201 char* buf = (char*) malloc(2048); 200 202 size_t length; ··· 266 268 exit(1); 267 269 } 268 270 271 + struct __xcselect_manpaths 272 + { 273 + unsigned int count; 274 + char** paths; 275 + }; 276 + 277 + void xcselect_manpaths_append(xcselect_manpaths* paths, const char* path) 278 + { 279 + paths->count++; 280 + paths->paths = realloc(paths->paths, sizeof(char*) * paths->count); 281 + paths->paths[paths->count - 1] = strdup(path); 282 + } 283 + 284 + xcselect_manpaths* xcselect_get_manpaths(const char* sdkname) 285 + { 286 + char path[1024]; 287 + bool unused; 288 + size_t len; 289 + xcselect_manpaths* rv; 290 + 291 + if (!xcselect_get_developer_dir_path(path, sizeof(path), &unused)) 292 + return NULL; 293 + 294 + len = strlen(path); 295 + strcat(path, "usr/lib/libxcrun.dylib"); 296 + 297 + rv = (xcselect_manpaths*) malloc(sizeof(*rv)); 298 + memset(rv, 0, sizeof(*rv)); 299 + 300 + if (access(path, F_OK) == 0) 301 + { 302 + void* module = dlopen(path, RTLD_LAZY); 303 + void (*fn)(const char* devpath, const char* sdkname, void (^)(const char*)); 304 + 305 + if (!module) 306 + { 307 + free(rv); 308 + fprintf(stderr, "%s: error: cannot load libxcrun (%s)\n", getprogname(), dlerror()); 309 + return NULL; 310 + } 311 + 312 + *((void**)&fn) = dlsym(module, "xcrun_iter_manpaths"); 313 + 314 + if (fn != NULL) 315 + { 316 + path[len] = 0; 317 + fn(path, sdkname, ^(const char* path) { 318 + xcselect_manpaths_append(rv, path); 319 + }); 320 + } 321 + 322 + dlclose(module); 323 + } 324 + 325 + // Add standard paths 326 + path[len] = 0; 327 + strcat(path, "usr/share/man"); 328 + xcselect_manpaths_append(rv, path); 329 + 330 + path[len] = 0; 331 + strcat(path, "usr/llvm-gcc-4,2/share/man"); 332 + xcselect_manpaths_append(rv, path); 333 + 334 + path[len] = 0; 335 + strcat(path, "Toolchains/XcodeDefault.xctoolchain/usr/share/man"); 336 + xcselect_manpaths_append(rv, path); 337 + 338 + return rv; 339 + } 340 + 341 + unsigned int xcselect_manpaths_get_num_paths(xcselect_manpaths* p) 342 + { 343 + return p->count; 344 + } 345 + 346 + const char* xcselect_manpaths_get_path(xcselect_manpaths* p, unsigned int idx) 347 + { 348 + if (idx < xcselect_manpaths_get_num_paths(p)) 349 + return p->paths[idx]; 350 + else 351 + return NULL; 352 + } 353 + 354 + void xcselect_manpaths_free(xcselect_manpaths* p) 355 + { 356 + for (unsigned int i = 0; i < p->count; i++) 357 + free(p->paths[i]); 358 + free(p->paths); 359 + free(p); 360 + } 361 +
+11
src/xcselect/libxcselect.h src/xcselect/xcselect.h
··· 18 18 */ 19 19 #ifndef _LIBXCSELECT_H_ 20 20 #define _LIBXCSELECT_H_ 21 + #include <stdbool.h> 22 + #include <stddef.h> 21 23 22 24 #define XCSELECT_FLAG_REQUIRE_XCODE 1 23 25 24 26 int xcselect_invoke_xcrun(const char* tool, int argc, char* argv[], int flags); 27 + 28 + bool xcselect_get_developer_dir_path(char* path, size_t len, bool* is_cmd_line); 29 + bool xcselect_find_developer_contents_from_path(const char* p, char* dst, bool* is_cmd_line, size_t dst_size); 30 + 31 + typedef struct __xcselect_manpaths xcselect_manpaths; 32 + xcselect_manpaths* xcselect_get_manpaths(const char* sdkname); 33 + unsigned int xcselect_manpaths_get_num_paths(xcselect_manpaths* p); 34 + const char* xcselect_manpaths_get_path(xcselect_manpaths* p, unsigned int idx); 35 + void xcselect_manpaths_free(xcselect_manpaths* p); 25 36 26 37 #endif 27 38
+189
src/xcselect/xcode-select.c
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2017 Lubos Dolezel 5 + 6 + Darling is free software: you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation, either version 3 of the License, or 9 + (at your option) any later version. 10 + 11 + Darling is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <stdio.h> 21 + #include <getopt.h> 22 + #include <stdlib.h> 23 + #include <string.h> 24 + #include <unistd.h> 25 + #include <errno.h> 26 + #include "xcselect.h" 27 + 28 + void printUsage(void); 29 + void doReset(void); 30 + void doSwitch(const char* path); 31 + void doPrintManPaths(void); 32 + 33 + int main(int argc, const char** argv) 34 + { 35 + if (argc == 1) 36 + { 37 + fprintf(stderr, "xcode-select: error: no command option given\n"); 38 + printUsage(); 39 + } 40 + else if (argc == 2 || argc == 3) 41 + { 42 + if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) 43 + { 44 + printUsage(); 45 + } 46 + else if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-version") == 0) 47 + { 48 + printf("xcode-select for Darling, version 1.0\n"); 49 + } 50 + else if (strcmp(argv[1], "-p") == 0 || strcmp(argv[1], "--print-path") == 0 || strcmp(argv[1], "-print-path") == 0) 51 + { 52 + char path[1024]; 53 + bool is_cmd_line; 54 + 55 + if (xcselect_get_developer_dir_path(path, sizeof(path), &is_cmd_line)) 56 + { 57 + printf("%s\n", path); 58 + } 59 + else 60 + { 61 + fprintf(stderr, "xcode-select: error: unable to get active developer directory\n"); 62 + return 1; 63 + } 64 + } 65 + else if (strcmp(argv[1], "--show-manpaths") == 0) 66 + { 67 + doPrintManPaths(); 68 + } 69 + else if (strcmp(argv[1], "--install") == 0) 70 + { 71 + if (access("/Library/Developer/CommandLineTools/usr/lib/libxcrun.dylib", F_OK) == 0) 72 + { 73 + fprintf(stderr, "xcode-select: error: command line tools are already installed\n"); 74 + return 1; 75 + } 76 + else 77 + { 78 + printf("Please visit https://developer.apple.com/download/more/ and download\n" 79 + "a package named \"Command Line Tools\".\n\n" 80 + "After that, install them by running `installer -pkg file.pkg -target /`.\n"); 81 + } 82 + } 83 + else if (strcmp(argv[1], "-r") == 0 || strcmp(argv[1], "--reset") == 0) 84 + { 85 + doReset(); 86 + } 87 + else if (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "--switch") == 0 || strcmp(argv[1], "-switch") == 0) 88 + { 89 + if (argc != 3) 90 + { 91 + fprintf(stderr, "xcode-select: error: missing argument to '%s'\n", argv[1]); 92 + return 1; 93 + } 94 + 95 + doSwitch(argv[2]); 96 + } 97 + else 98 + { 99 + fprintf(stderr, "xcode-select: error: unknown option: %s\n", argv[1]); 100 + printUsage(); 101 + return 1; 102 + } 103 + 104 + return 0; 105 + } 106 + else 107 + { 108 + fprintf(stderr, "xcode-select: error: bad argument count\n"); 109 + printUsage(); 110 + } 111 + return 1; 112 + } 113 + 114 + void printUsage(void) 115 + { 116 + fprintf(stderr, "Usage: xcode-select [options]\n\n"); 117 + fprintf(stderr, "xcode-select is used to set up path to the active developer directory.\n" 118 + "This affects both toolchain commands (such as clang or make) and Xcode-specific\n" 119 + "tools (such as xcodebuild).\n\n"); 120 + fprintf(stderr, "Options:\n" 121 + " -h, --help print this help message\n" 122 + " -p, --print-path print the path of the active developer directory\n" 123 + " -s <path>, --switch <path> change the path of the active developer directory\n" 124 + " --install trigger the installation of command line developer tools\n" 125 + " -v, --version print the version of this tool\n" 126 + " -r, --reset reset to the default developer directory\n"); 127 + } 128 + 129 + static void killLink(const char* path) 130 + { 131 + if (unlink(path) != 0) 132 + { 133 + if (errno != ENOENT) 134 + { 135 + fprintf(stderr, "xcode-select: error: cannot remove existing link at '%s': %s\n", 136 + path, strerror(errno)); 137 + exit(1); 138 + } 139 + } 140 + } 141 + 142 + void doReset(void) 143 + { 144 + killLink("/var/db/xcode_select_link"); 145 + killLink("/usr/share/xcode-select/xcode_dir_link"); 146 + killLink("/usr/share/xcode-select/xcode_dir_path"); 147 + } 148 + 149 + void doSwitch(const char* path) 150 + { 151 + char buffer[1024]; 152 + bool unused; 153 + 154 + if (!xcselect_find_developer_contents_from_path(path, buffer, unused, sizeof(buffer))) 155 + { 156 + fprintf(stderr, "xcode-select: error: invalid developer directory '%s'\n", path); 157 + exit(1); 158 + } 159 + 160 + doReset(); 161 + 162 + umask(022); 163 + if (symlink(buffer, "/var/db/xcode_select_link") != 0) 164 + { 165 + fprintf(stderr, "xcode-select: error: unable to create symlink: %s\n", 166 + strerror(errno)); 167 + exit(1); 168 + } 169 + } 170 + 171 + void doPrintManPaths(void) 172 + { 173 + xcselect_manpaths *xcp; 174 + const char *path; 175 + unsigned i, count; 176 + 177 + xcp = xcselect_get_manpaths(NULL); 178 + if (xcp != NULL) { 179 + count = xcselect_manpaths_get_num_paths(xcp); 180 + for (i = 0; i < count; i++) { 181 + path = xcselect_manpaths_get_path(xcp, i); 182 + if (path != NULL) { 183 + puts(path); 184 + } 185 + } 186 + xcselect_manpaths_free(xcp); 187 + } 188 + } 189 +
+1 -1
src/xcselect/xcrun-shim.c
··· 16 16 You should have received a copy of the GNU General Public License 17 17 along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 18 */ 19 - #include "libxcselect.h" 19 + #include "xcselect.h" 20 20 #include <stdlib.h> 21 21 #include <string.h> 22 22
+1 -1
src/xcselect/xcrun.c
··· 16 16 You should have received a copy of the GNU General Public License 17 17 along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 18 */ 19 - #include "libxcselect.h" 19 + #include "xcselect.h" 20 20 #include <stdlib.h> 21 21 #include <string.h> 22 22