[patch]using GDC freely on Windows

heromyth avatarheromyth created an issue

This patch makes it possible that running GDC on different diskdrive or placing it into any sub-directory.

Tested with MingW GCC 4.5.2 + CMD Shell on Windows XP SP3.

Comments (11)

  1. Daniel Green

    There may be an simpler way with 4.5.2. If you apply pathfix.patch and make-rel-pref.patch from the tdm-gcc sources. Only two lines of code need modifying to allow relocatable gdc. The initial test works for me, I want to try recompiling everything to be sure.

    GDC does support relocation, which may be broken with 4.5.2. The method it uses is to compare GCC_INCLUDE_DIR with D_PHOBOS_DIR. The reason I say it may be broken is because, on windows, GCC_INCLUDE_DIR is not defined when compiling d-lang.cc.

    The issue with mingw is that GCC_INCLUDE_DIR contains C:/MinGW for a root and D_PHOBOS_DIR contains /mingw. GDC uses a length comparison so on windows the length is always different and fails the test. In previous versions I would edit d-confdefs.h and change the /mingw to c:/mingw and it would work.

  2. heromyth

    My patch not only fixes the relocatation of GDC but also does these:

    1) reorganize the codes for adding import path
    2) try to remove the repeated path
    3) try to slim a path like 
       /mingw/lib/gcc/i686-pc-mingw32/4.5.2/../../../../include/d2/4.5.2 
    into 
       /mingw/include/d2/4.5.2
    4) try to add some standard import dir which are relative to the executable file of gdc like 
        "../include/d2/4.5.2" and "../include/d2/4.5.2/i686-pc-mingw32"
    

    It can't be assured that the comparison in the function of prefixed_path is always true, even if you change the D_PHOBOS_DIR from /mingw to c:/mingw in d-confdefs.h. For example, the Mingw with GDC has been installed into some sub-directory like C:/dirA/dirB/mingw.

  3. Daniel Green

    I can't comment directly on any of the additional things your patch does. However, I am curious if 4 would affect local relative imports such as "../mymodule". Also couldn't 3 and 2 be done using GDC's current implementation and what is your rationale behind 1. Looking at the patch you are replacing 40 lines of code with about 300.

    I based my response on the title of your post since I had some experience in that area and attempted to the same thing until I took a closer look at how GDC does it and why it worked on linux.

    It can be assured that the comparison in the function is always true since both D_PHOBOS_DIR and GCC_INCLUDE_DIR are defined based upon configuration option --prefix. I used /mingw as an example since that is generally what I set it as. prefixed_path compares the length of those two strings based upon that fact, which is why it is necessary to change /mingw to c:/mingw. If the comparison is true, it will concat iprefix to the unique portion of D_PHOBOS_DIR. iprefix is set to the directory that gdc executed from at runtime.

    GCC_INCLUDE_DIR /mingw/lib/gcc/i686-pc-mingw32/4.5.2/include

    D_PHOBOS_DIR /mingw/lib/gcc/i686-pc-mingw32/4.5.2/../../../../include/d/4.5.2

    iprefix c:\crossdev\mingw32\mingw\bin\../lib/gcc/i686-pc-mingw32/4.5.2/

    Path after prefixed_path is called.

    c:\crossdev\mingw32\mingw\bin\../lib/gcc/i686-pc-mingw32/4.5.2/../../../../include/d/4.5.2

    Reduced c:\crossdev\mingw32\mingw\include/d/4.5.2

    GCC_INCLUDE_DIR lacks the C:/ I mentioned in my previous post because TDM-GCC released a patch for the 4.5 series that changed that behavior.

  4. Daniel Green

    To clarify even more, the comparison is strncmp. Using the length of GCC_INCLUDE_DIR - 8. The minus 8 gives us the root, by removing /include, that GDC can use to get the actual include path.

  5. heromyth

    The rationale behind 1 is that the import path should be added by various way like standard relative path, environment path, predefined path such as D_PHOBOS_DIR.

    On Win32 I commented the prefixed_path, because I can't find a better way to assure the comparison is always true. You are right, if GCC_INCLUDE_DIR is predefined. By the way, can D_PHOBOS_DIR be directly defined as relative path.

    As for handling the relative path in make_absolute in my patch, I return NULL to indicate that I can't handle it (It seems not necessary to do a duplication.). Hope the slimmed path could speed up the path search a little. I'm not sure if the GDC can do this.

    Here are some examples the make_absolute can handle:

    char* str = "/abc/../gcc-4.5.2/libphobos";        // ok
    char* str = "/abc/../../gcc-4.5.2/libphobos";     // error
    char* str = "/../gcc-4.5.2/libphobos";            // error
    char* str = "D:/../gcc-4.5.2/libphobos";          // error
    char* str = "D:/D/../gcc-4.5.2/libphobos";        // ok
    char* str = "A/../gcc-4.5.2/libphobos";           // ok
    char* str = "aa/bb/cc/../../gcc-4.5.2/libphobos"; // ok
    

    Thanks for your watching my patch.

  6. Daniel Green

    I'd like to get a clarification on what you mean with standard relative path. To me, I've always thought that to be relative to where the compiler was executed. You state relative to the location of the binary file. I'm not sure those can be differentiated using the -I option.

    Environment paths would be nice but I've only ever seen it used with makefiles which manually handle them. Still should be trivial to implement so I see no reason to oppose this.

    As for slimming paths, I get the impression that GCC uses lots of unslimmed paths. Just create a dummy file with a main function and do gcc main.c -v and see how many paths contain dots. However it should be fairly trivial to add that feature after loading all the imports. Just iterate through them all and try to convert. Whether or not that could speed of path searching is something you would have to benchmark. I've heard an argument similar to that when dealing with WAF and my first thought was the actual compiling of code would make any sort of gains or penalties insignificant. Another thing about the way D imports work, is that the last one inputted is the first one searched. So -I myimports/ is searched before the default import path.

    Having D_PHOBOS_DIR be directly defined as a relative path, I imagine that could be done. I have no idea what would break in the process or even how it's determined. I do know it's current form is required by prefixed_path to convert GCC_INCLUDE_DIR into a base path to gcc. GCC_INCLUDE_DIR actually refers to ${prefix}/lib/gcc/i686-pc-mingw32/4.5.2/include.

    It's good to see more people take an interest in GDC especially on Windows.

    If you want to try adapting some of your changes to use what GDC already has in place that would be great. I can't see a reason to replace a system that works, even if it's not well documented as to why it works(that can always be fixed). It would also be useful if you could separate your features into different patches.

  7. heromyth

    These operations:

    static void register_imports_chains ();
    static void add_import_path (const char *, bool verbose=false);
    static void add_env_var_paths (const char *, bool verbose=false);
    static void add_standard_paths (bool verbose=false);
    static void free_path (char *path, int reason, bool verbose=false);
    

    are based on those in GCC' incpath.c, however, has been simplied for GDC.

    The make_absolute is my own, and can be commented out safely.

  8. Daniel Green

    Iain recently updated the prefixed_path code. So I've tweaked your patch for that revision(da7dc4ae6277 ) and to use gdc's method of path prefixing. This allows the removal of all the #ifdef WIN32's.

    For reference purposes, a handy way to disable the changes would be to disable the checks in add_import_path.

  9. Log in to comment
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.