aBothe / Mono-D

D Add-In for MonoDevelop
http://wiki.dlang.org/Mono-D
Other
113 stars 26 forks source link

additional object directories or "merge dependant libs" #603

Open nicolasjinchereau opened 9 years ago

nicolasjinchereau commented 9 years ago

I did a feature request a while back to include support for building C++ files in Mono-D. I've dropped this idea because MonoDevelop's built in C++ support really isn't very good, and would require a lot more work than just re-routing some wires. Also, my project requires Objective-C++, and AFAIK, a parser for it does not exist as an MD addin.

So at this point, I'm using an "After Build" command to call Xcode's command line tools to build an Xcode project.

Finally, the reason for this feature request is to seamlessly integrate the Xcode build result into a D binary. Currently, I'm using ar to extract and combine the Obj-C++ and D libs, but if Mono-D could accept a dir full of *.o files, or automatically merge static libs, it would simplify this process a lot.

aBothe commented 9 years ago

I could let it recognize object files and static lib files - although I'm not sure whether one should explicitly allow them to be linked-in or whether everything happens implicitly. I'm for setting the "Compile"-action for .a/.lib files to "build" explicitly manually.

nicolasjinchereau commented 9 years ago

I'm not sure I understand what you mean.

In the case of *.o files, I would like to provide a directory full of them and have all files in that directory passed to dmd. It would have to be all the files in the directory because there wouldn't be a way to get a list of files that were outputted from xcode.

My preferred option may turn out to be more work, but I could implement it myself if it's approved. This option would be to add another checkbox under this option: "Link in static/shared libraries from nested dependancies"

The new checkbox would say something like "Merge dependent static libraries" or something. If this option was selected, all libraries in the "Project Options/Linking/Libraries" text box would be automatically merged into the resulting static library. I was just trying to test this, but I'm out of time for now. It's still unclear what dmd/ldc/gdc will do if you pass it a static library while using "-lib". Maybe an error, maybe nothing. In those cases, ar(configurable) could be used to extract/recombine the libraries.

I don't think it should be default to merge libs this way, because it may cause unexpected/undesired bloat of static libs, which someone may want to use in arbitrary combinations. In my case though, I want my lib to be used as a D library without having to link extra libraries or anything to accommodate the C++ cruft.

aBothe commented 9 years ago

Basically it's a good idea, but I thought about reusing already existing options. When you right-click a file in the Project Pad, you can select a Build Action for a specific file. Now, when you want to link in a static library or object, you can select these files, right-click, and select 'Compile' (or 'Link', I may have to add this) as a build action. (Only) then, the files become linked. So there will be no hassle with some files that shall not be linked in.

aBothe commented 9 years ago

(The actual treatment in the builing process for D projects isn't implemented yet, of course. But you can select the Build Action for a file)

nicolasjinchereau commented 9 years ago

Ok, that sounds good. I've been doing some testing though, and neither DMD nor LDC want to take a static library as an argument at the same time as -lib. When I run the following, I just get a segmentation fault:

clang++ test.cpp -otest.o -c -stdlib=libc++ ar rcs test.a test.o dmd -lib -oflibTest.a test.d test.a <-- segfault here

So the build process would have to be 1) compile static lib to object files 2) extract dependent libraries' objects 3) use ar to link all objects into the final library

as far as usage though, If I could drag a static library into my D project and have it merged with whatever I'm building, that would be fine, because I could set xcode's output target to overwrite it.

nicolasjinchereau commented 9 years ago

apparently, libtool can also be used on osx: libtool -static -o new.a old1.a old2.a

nicolasjinchereau commented 9 years ago

and on windows: LIB.EXE /OUT:c.lib a.lib b.lib

aBothe commented 9 years ago

and at this place, I wouldn't put any further effort into it -- it would simply exceed Mono-D's goals. I'd rather have a makefile that does specifically configurated things instead of fiddle argument chains together in some GUI that contains infinite amounts of bugs and so on.

aBothe commented 9 years ago

(Ah, well, yes, just linking in some dedicated object files is still making sense though!)

nicolasjinchereau commented 9 years ago

"(Ah, well, yes, just linking in some dedicated object files is still making sense though!)"

If you could call it "additional source directories" and just have Mono-D pass everything in there to dmd, that would work too. Super easy solution.

nicolasjinchereau commented 9 years ago

Maybe under the "Objects directory" spot on the compiling panel

nicolasjinchereau commented 9 years ago

I guess libtool is ok for now. One liners are ok for custom commands, but beyond that, you have to call a script, which cannot be edited from within mono-d. To make matters worse, you can't disable Custom Commands. So if you want it temporarily disabled, you have to remove the entire thing and add it back, which is annoying. Maybe I should go do a feature request for a checkbox in XS Custom Commands.

nicolasjinchereau commented 9 years ago

Anyways, I hadn't realized that you considered this project feature complete at this point. I was hoping for a static analyzer and a team server, but I guess I'll survive ;)

nicolasjinchereau commented 9 years ago

So what's the verdict on this?

-Update Mono-D to use lib.exe and libtool to merge static libraries in the project panel into the final binary if present -Add "Additional Source Directories" to Project Compile Options and pass contained sources in the compilation command -Veto this idea

aBothe commented 9 years ago

I think these couple of lines will already do it - you just have to put a link to your lib/a/obj/o-Files into the project, make them "Compile" as build action, and that's it.

aBothe commented 9 years ago

I honestly don't want to change any GUI for getting this feature implemented.

aBothe commented 9 years ago

Concerning the lib.exe merge command, you may always put in a pre-build-command in your project configuration. :)

nicolasjinchereau commented 9 years ago

Ok, so it seems I can *.a files into my project to build, but they will only link if I'm compiling an executable. It seems trivial at this point to insert a call to libtool or lib.exe depending if the target is a static library.

...build as usual... if(project.type == static library) libs = project.files.filter(f => f.type == .a or .lib) linkerTool = windows? lib.exe : libtool; linkerTool( target.name, libs);

aBothe commented 9 years ago

It should work as well when building shared or static libraries since the same procedures are used for these build types as well.

nicolasjinchereau commented 9 years ago

It doesn't work though. If you call dmd with -lib, and pass it a static library, it just crashes. dmd will only link libs if it's compiling an executable or shared library.

nicolasjinchereau commented 9 years ago

Building: LibTest (Debug) Performing main compilation... Current dictionary: -- dmd -debug -gc "test.a" "test.d" "-Iusr/share/dmd/src/phobos" "-Iusr/share/dmd/src/druntime/import" -lib "-odobj/Debug" "-oflibTest.a" -w -vcolumns Exit code 139 Build complete -- 1 error, 0 warnings

if you type the build string into terminal yourself, it says "Segmentation fault: 11"

aBothe commented 9 years ago

segfault? So we found another dmd bug! :stuck_out_tongue:

Please excuse my sunday-driven laziness, but as the most appropriate solution right now I recommend tweaking the "linker" executable and debug/release arguments for linking static libraries together in the global "Compiler Toolchains"-options.

aBothe commented 9 years ago

The reason I chose dmd for linking static libs was the different default lib tool on windows and linux/osx -- I didn't want to extend the option matrix any further.

nicolasjinchereau commented 9 years ago

segfault? So we found another dmd bug! I am wondering if this is by design, because LDC doesn't work either, but instead of segfaulting, it seems to just ignore the static lib you pass in

nicolasjinchereau commented 9 years ago

I recommend tweaking the "linker"

This doesn't work either, because Mono-D still passes the static lib to dmd expecting to get a .o file that it can link, but dmd doesn't output anything. I think this is correct, as the static library could be composed of multiple .o files. The static library would have to be extracted to some temporary directory by the linker tool using something like "ar -x test.a".

The reason I chose dmd for linking static libs was the different default lib tool on windows and linux/osx

I understand this, but as you said, now it's a bug, we must fix it =)

aBothe commented 9 years ago

This doesn't work either, because Mono-D still passes the static lib to dmd

How about removing $libs from the linker arguments? In the target executable, the third party libs must then be referenced, of course(?)

nicolasjinchereau commented 9 years ago

How about removing $libs from the linker arguments?

If you mean not passing *.a files to dmd when compiling a static library, then I guess that would fix the problem.

aBothe commented 9 years ago

-gc $sources $includes -lib "-od$objectsDirectory" "-of$lib" -w -vcolumns It already is not taking any libs, but in your log

dmd -debug -gc "test.a" "test.d" "-Iusr/share/dmd/src/phobos" "-Iusr/share/dmd/src/druntime/import" -lib "-odobj/Debug" "-oflibTest.a" -w -vcolumns

,it is emitting a "test.a" - that seems to be a bug.

nicolasjinchereau commented 9 years ago

Ok. I actually forgot to update to the newest build. I'm trying to do it right now, but I'm still getting an error when I try to install the Mono-D addin package...but this time, XS has been completely broken by trying to install it. I've completely reinstalled XS, and it still won't start. Any idea where the installed addins go on OSX?

nicolasjinchereau commented 9 years ago

Never mind.. /Users/Bitwise/Library/Application Support/XamarinStudio-5.0/LocalInstall/Addins

nicolasjinchereau commented 9 years ago

Ok, so with 2.11.4, if you include a .a file in your static library project and set the build action to 'compile', it will still send the .a file to dmd and break.

dmd -debug -gc "libTest.a" "test.d" "-I/usr/share/dmd/src" -lib "-odobj/Debug" "-of/Users/Bitwise/Desktop/DLinkTest/bin/Debug/libDLinkTest.a" -w -vcolumns Exit code 139 (this is actually the segfault)

So the options seem to be: 1) to send the compiled output and .a file through a library tool instead(libtool/lib.exe) 2) disable build-action=compile for .a files in static library projects

nicolasjinchereau commented 9 years ago

any news on this?

aBothe commented 9 years ago

I'm busy with writing my thesis atm :/ - So no, not for now.

nicolasjinchereau commented 9 years ago

Ok, no prob. Just let me know if you want me to do a pull request for option (2) for now.

aBothe commented 9 years ago

I just checked possible method overloads that could be introduced in the DProject class - you can't disable build action for specific file/item types. The only thing one might do is to prevent lib-files getting added to the list of source files.

aBothe commented 9 years ago

Hmm, I still don't want to introduce further build behaviour changes. Having external libraries built and individual objects extracted and so on is a too wide problem area that isn't related to D anymore - sry then.

nicolasjinchereau commented 9 years ago

It's fine. Don't worry about it. Maybe I'm being greedy. I guess it's more important to be stable at this point. Thanks anyways.

aBothe commented 9 years ago

Okay :/