Mono-D icon indicating copy to clipboard operation
Mono-D copied to clipboard

additional object directories or "merge dependant libs"

Open nicolasjinchereau opened this issue 10 years ago • 38 comments

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.

nicolasjinchereau avatar Apr 23 '15 15:04 nicolasjinchereau

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.

aBothe avatar Apr 23 '15 15:04 aBothe

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.

nicolasjinchereau avatar Apr 23 '15 17:04 nicolasjinchereau

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 avatar Apr 23 '15 17:04 aBothe

(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)

aBothe avatar Apr 23 '15 18:04 aBothe

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 avatar Apr 23 '15 22:04 nicolasjinchereau

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

nicolasjinchereau avatar Apr 23 '15 22:04 nicolasjinchereau

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

nicolasjinchereau avatar Apr 23 '15 22:04 nicolasjinchereau

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 avatar Apr 23 '15 22:04 aBothe

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

aBothe avatar Apr 23 '15 22:04 aBothe

"(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 avatar Apr 23 '15 23:04 nicolasjinchereau

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

nicolasjinchereau avatar Apr 23 '15 23:04 nicolasjinchereau

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 avatar Apr 23 '15 23:04 nicolasjinchereau

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 avatar Apr 23 '15 23:04 nicolasjinchereau

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

nicolasjinchereau avatar Apr 24 '15 15:04 nicolasjinchereau

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 avatar Apr 24 '15 16:04 aBothe

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

aBothe avatar Apr 24 '15 16:04 aBothe

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

aBothe avatar Apr 24 '15 16:04 aBothe

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);

nicolasjinchereau avatar Apr 24 '15 17:04 nicolasjinchereau

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

aBothe avatar Apr 25 '15 10:04 aBothe

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 avatar Apr 25 '15 20:04 nicolasjinchereau

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"

nicolasjinchereau avatar Apr 25 '15 20:04 nicolasjinchereau

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 avatar Apr 26 '15 09:04 aBothe

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.

aBothe avatar Apr 26 '15 09:04 aBothe

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 avatar Apr 26 '15 14:04 nicolasjinchereau

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 =)

nicolasjinchereau avatar Apr 26 '15 14:04 nicolasjinchereau

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(?)

aBothe avatar Apr 26 '15 19:04 aBothe

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.

nicolasjinchereau avatar Apr 26 '15 19:04 nicolasjinchereau

-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.

aBothe avatar Apr 26 '15 20:04 aBothe

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 avatar Apr 26 '15 22:04 nicolasjinchereau

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

nicolasjinchereau avatar Apr 26 '15 22:04 nicolasjinchereau