Mercurial > projects > ddmd
comparison dmd/Util.d @ 22:fd4acc376c45
Implemented object file output and linking on linux.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Thu, 08 Apr 2010 04:21:03 +0100 |
parents | 5c9b78899f5d |
children | cfa3747ebe4c |
comparison
equal
deleted
inserted
replaced
21:26b9f97f6162 | 22:fd4acc376c45 |
---|---|
14 import std.c.string; | 14 import std.c.string; |
15 import std.stdio : writef, writefln, write; | 15 import std.stdio : writef, writefln, write; |
16 version (Windows) | 16 version (Windows) |
17 { | 17 { |
18 import std.c.process : spawnl, spawnlp; | 18 import std.c.process : spawnl, spawnlp; |
19 } | |
20 version (POSIX) | |
21 { | |
22 import core.sys.posix.unistd; | |
19 } | 23 } |
20 import core.stdc.stdlib; | 24 import core.stdc.stdlib; |
21 import core.stdc.ctype; | 25 import core.stdc.ctype; |
22 import core.stdc.stdarg; | 26 import core.stdc.stdarg; |
23 public import core.stdc.stdio; | 27 public import core.stdc.stdio; |
812 remove(toStringz(lnkfilename.toChars())); | 816 remove(toStringz(lnkfilename.toChars())); |
813 ///delete lnkfilename; | 817 ///delete lnkfilename; |
814 } | 818 } |
815 return status; | 819 return status; |
816 } else version (POSIX) {/// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 | 820 } else version (POSIX) {/// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
817 assert(false, "Unimplemented"); | |
818 /+ | |
819 pid_t childpid; | 821 pid_t childpid; |
820 int i; | 822 int i; |
821 int status; | 823 int status; |
822 | 824 |
823 // Build argv[] | 825 // Build argv[] |
824 Array argv; | 826 Array argv = new Array(); |
825 | 827 |
826 const char *cc = getenv("CC"); | 828 const(char)* cc = core.stdc.stdlib.getenv("CC"); |
827 if (!cc) | 829 if (!cc) |
828 cc = "gcc"; | 830 cc = "gcc"; |
829 argv.push((void *)cc); | 831 argv.push(cast(void *)cc); |
830 argv.insert(1, global.params.objfiles); | 832 Array objfiles = new Array; |
833 for( i = 0; i < global.params.objfiles.dim; i++ ) | |
834 { string str = (cast(String)global.params.objfiles.data[i]).str; | |
835 objfiles.push(cast(void*)toStringz(str)); | |
836 } | |
837 argv.insert(1, objfiles); | |
831 | 838 |
832 // None of that a.out stuff. Use explicit exe file name, or | 839 // None of that a.out stuff. Use explicit exe file name, or |
833 // generate one from name of first source file. | 840 // generate one from name of first source file. |
834 argv.push((void *)"-o"); | 841 argv.push(cast(void *)cast(char*)"-o"); |
835 if (global.params.exefile) | 842 if (global.params.exefile) |
836 { | 843 { |
837 argv.push(global.params.exefile); | 844 argv.push(cast(void*)toStringz(global.params.exefile)); |
838 } | 845 } |
839 else | 846 else |
840 { // Generate exe file name from first obj name | 847 { // Generate exe file name from first obj name |
841 char *n = (char *)global.params.objfiles.data[0]; | 848 string n = (cast(String)global.params.objfiles.data[0]).str; |
842 char *e; | |
843 char *ex; | |
844 | |
845 n = FileName.name(n); | 849 n = FileName.name(n); |
846 e = FileName.ext(n); | 850 string e = FileName.ext(n); |
847 if (e) | 851 string ex = e ? n[0..$-(e.length+1)] : "a.out"; |
848 { | 852 |
849 e--; // back up over '.' | 853 argv.push(cast(void*)toStringz(ex)); |
850 ex = (char *)mem.malloc(e - n + 1); | |
851 memcpy(ex, n, e - n); | |
852 ex[e - n] = 0; | |
853 } | |
854 else | |
855 ex = (char *)"a.out"; // no extension, so give up | |
856 argv.push(ex); | |
857 global.params.exefile = ex; | 854 global.params.exefile = ex; |
858 } | 855 } |
859 | 856 |
860 // Make sure path to exe file exists | 857 // Make sure path to exe file exists |
861 { char *p = FileName.path(global.params.exefile); | 858 { string p = FileName.path(global.params.exefile); |
862 FileName.ensurePathExists(p); | 859 FileName.ensurePathExists(p); |
863 mem.free(p); | |
864 } | 860 } |
865 | 861 |
866 if (global.params.symdebug) | 862 if (global.params.symdebug) |
867 argv.push((void *)"-g"); | 863 argv.push(cast(void *)cast(char*)"-g"); |
868 | 864 |
869 if (global.params.isX86_64) | 865 if (global.params.isX86_64) |
870 argv.push((void *)"-m64"); | 866 argv.push(cast(void *)cast(char*)"-m64"); |
871 else | 867 else |
872 argv.push((void *)"-m32"); | 868 argv.push(cast(void *)cast(char*)"-m32"); |
873 | 869 |
874 if (0 && global.params.exefile) | 870 if (0 && global.params.exefile) |
875 { | 871 { |
876 /* This switch enables what is known as 'smart linking' | 872 /* This switch enables what is known as 'smart linking' |
877 * in the Windows world, where unreferenced sections | 873 * in the Windows world, where unreferenced sections |
880 * Although it is documented to work with ld version 2.13, | 876 * Although it is documented to work with ld version 2.13, |
881 * in practice it does not, but just seems to be ignored. | 877 * in practice it does not, but just seems to be ignored. |
882 * Thomas Kuehne has verified that it works with ld 2.16.1. | 878 * Thomas Kuehne has verified that it works with ld 2.16.1. |
883 * BUG: disabled because it causes exception handling to fail | 879 * BUG: disabled because it causes exception handling to fail |
884 */ | 880 */ |
885 argv.push((void *)"-Xlinker"); | 881 argv.push(cast(void *)cast(char*)"-Xlinker"); |
886 argv.push((void *)"--gc-sections"); | 882 argv.push(cast(void *)cast(char*)"--gc-sections"); |
887 } | 883 } |
888 | 884 |
889 for (i = 0; i < global.params.linkswitches.dim; i++) | 885 for (i = 0; i < global.params.linkswitches.dim; i++) |
890 { char *p = (char *)global.params.linkswitches.data[i]; | 886 { char *p = cast(char *)global.params.linkswitches.data[i]; |
891 if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l')) | 887 if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l')) |
892 // Don't need -Xlinker if switch starts with -l | 888 // Don't need -Xlinker if switch starts with -l |
893 argv.push((void *)"-Xlinker"); | 889 argv.push(cast(void *)cast(char*)"-Xlinker"); |
894 argv.push((void *) p); | 890 argv.push(cast(void *) p); |
895 } | 891 } |
896 | 892 |
897 /* Add each library, prefixing it with "-l". | 893 /* Add each library, prefixing it with "-l". |
898 * The order of libraries passed is: | 894 * The order of libraries passed is: |
899 * 1. any libraries passed with -L command line switch | 895 * 1. any libraries passed with -L command line switch |
901 * 3. libraries specified by pragma(lib), which were appended | 897 * 3. libraries specified by pragma(lib), which were appended |
902 * to global.params.libfiles. | 898 * to global.params.libfiles. |
903 * 4. standard libraries. | 899 * 4. standard libraries. |
904 */ | 900 */ |
905 for (i = 0; i < global.params.libfiles.dim; i++) | 901 for (i = 0; i < global.params.libfiles.dim; i++) |
906 { char *p = (char *)global.params.libfiles.data[i]; | 902 { char *p = cast(char *)global.params.libfiles.data[i]; |
907 size_t plen = strlen(p); | 903 size_t plen = strlen(p); |
908 if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a') | 904 if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a') |
909 argv.push((void *)p); | 905 argv.push(cast(void *)p); |
910 else | 906 else |
911 { | 907 { |
912 char *s = (char *)mem.malloc(plen + 3); | 908 char *s = cast(char *)malloc(plen + 3); |
913 s[0] = '-'; | 909 s[0] = '-'; |
914 s[1] = 'l'; | 910 s[1] = 'l'; |
915 memcpy(s + 2, p, plen + 1); | 911 memcpy(s + 2, p, plen + 1); |
916 argv.push((void *)s); | 912 argv.push(cast(void *)s); |
917 } | 913 } |
918 } | 914 } |
919 | 915 |
920 /* Standard libraries must go after user specified libraries | 916 /* Standard libraries must go after user specified libraries |
921 * passed with -l. | 917 * passed with -l. |
922 */ | 918 */ |
923 const char *libname = (global.params.symdebug) | 919 const char *libname = (global.params.symdebug) |
924 ? global.params.debuglibname | 920 ? global.params.debuglibname |
925 : global.params.defaultlibname; | 921 : global.params.defaultlibname; |
926 char *buf = (char *)malloc(2 + strlen(libname) + 1); | 922 char *buf = cast(char *)malloc(2 + strlen(libname) + 1); |
927 strcpy(buf, "-l"); | 923 strcpy(buf, "-l"); |
928 strcpy(buf + 2, libname); | 924 strcpy(buf + 2, libname); |
929 argv.push((void *)buf); // turns into /usr/lib/libphobos2.a | 925 argv.push(cast(void *)buf); // turns into /usr/lib/libphobos2.a |
930 | 926 |
931 // argv.push((void *)"-ldruntime"); | 927 // argv.push((void *)"-ldruntime"); |
932 argv.push((void *)"-lpthread"); | 928 argv.push(cast(void *)cast(char*)"-lpthread"); |
933 argv.push((void *)"-lm"); | 929 argv.push(cast(void *)cast(char*)"-lm"); |
934 | 930 |
935 if (!global.params.quiet || global.params.verbose) | 931 if (!global.params.quiet || global.params.verbose) |
936 { | 932 { |
937 // Print it | 933 // Print it |
938 for (i = 0; i < argv.dim; i++) | 934 for (i = 0; i < argv.dim; i++) |
939 printf("%s ", (char *)argv.data[i]); | 935 printf("%s ", cast(char *)argv.data[i]); |
940 printf("\n"); | 936 printf("\n"); |
941 fflush(stdout); | 937 fflush(stdout); |
942 } | 938 } |
943 | 939 |
944 argv.push(null); | 940 argv.push(null); |
945 childpid = fork(); | 941 childpid = fork(); |
946 if (childpid == 0) | 942 if (childpid == 0) |
947 { | 943 { |
948 execvp((char *)argv.data[0], (char **)argv.data); | 944 execvp(cast(char *)argv.data[0], cast(char **)argv.data); |
949 perror((char *)argv.data[0]); // failed to execute | 945 perror(cast(char *)argv.data[0]); // failed to execute |
950 return -1; | 946 return -1; |
951 } | 947 } |
952 | 948 |
953 waitpid(childpid, &status, 0); | 949 waitpid(childpid, &status, 0); |
954 | 950 |
955 status=WEXITSTATUS(status); | 951 status=WEXITSTATUS(status); |
956 if (status) | 952 if (status) |
957 printf("--- errorlevel %d\n", status); | 953 printf("--- errorlevel %d\n", status); |
958 return status; | 954 return status; |
959 +/ | 955 |
960 } else { | 956 } else { |
961 writef ("Linking is not yet supported for this version of DMD.\n"); | 957 writef ("Linking is not yet supported for this version of DMD.\n"); |
962 return -1; | 958 return -1; |
963 } | 959 } |
964 } | 960 } |