Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

al_mangled_main linking issues with bundles #555

Open
SiegeLord opened this Issue Jan 9, 2016 · 24 comments

Comments

Projects
None yet
5 participants
@SiegeLord
Copy link
Member

SiegeLord commented Jan 9, 2016

@SiegeLord SiegeLord added 5.x OSX labels Jan 9, 2016

@ghost

This comment has been minimized.

Copy link

ghost commented Jan 10, 2016

My thoughts (taken from the thread linked above...)

Configuring CMake on OS X gives this warning:

CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
  --help-policy CMP0042" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   allegro
   allegro_acodec
   allegro_audio
   allegro_color
   allegro_dialog
   allegro_font
   allegro_image
   allegro_main
   allegro_memfile
   allegro_physfs
   allegro_primitives
   allegro_ttf
   allegro_video

Using _@_rpath with these libraries should make it possible to use them in bundles just by copying them to the Frameworks subdirectory,

except allegro_main - if this can be made into a static library it will be able to link to _al_mangled_main in the user's code even after symbol stripping.

@ghost

This comment has been minimized.

Copy link

ghost commented Jan 10, 2016

Further to this - the rpath stuff is already covered in #532. CMake never works the way I expect it to.

@goobliata

This comment has been minimized.

Copy link
Member

goobliata commented Jan 26, 2016

One thing I'm seeing as I try this is homebrew is naming libraries like liballegro.5.1.dylib as symlinks to liballegro5.1.12.dylib and so on... once these go into a Framework, the libraries that depend on liballegro.5.1.dylib (example, don't remember if this is one of the actual dependencies) are going to fail because in the .app/Contents/Frameworks there is only liballegro.5.1.12.dylib...

I'm sure it's possible to get this to work using install_name_tool. However, after 30 minutes of changing names I still have a lot left to change. I suggest looking at otool -l and otool -L output of libs and executables. With the example given on allegro.cc, there's a ton of missing links.

On OS X, you have to build libraries a certain way if you want to use them in bundles. Then they won't work right standalone. CMake has things like BUILD_WITH_INSTALL_RPATH and INSTALL_RPATH that help with this. I set the former to on and the latter to "@executable_path/" (you could add ../Frameworks) when I build dynamic libraries. Then, when they're linked to everything is already set to go. I don't know how you'd do it with homebrew though.

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Jan 27, 2016

Would things be better if we generated frameworks instead of dylibs?

@fatcerberus

This comment has been minimized.

Copy link
Contributor

fatcerberus commented Jan 27, 2016

As an outsider looking in, I get the impression OS X is quite a bit of a moving target. This is jarring for me being a Windows developer, where I could, if I were so inclined, install MSVC 6 on Windows 10 and use it to build programs that would run happily on that OS. Say what you will about Windows, but the API and ABI stability is very much appreciated.

I don't yet have a Mac of my own, but I do intend to acquire one eventually--and I'm not looking forward to officially supporting OS X for minisphere at all. 😝

@ghost

This comment has been minimized.

Copy link

ghost commented Jan 27, 2016

I think I can fix this but I won't have time until the weekend, is that OK? I need to get up to speed with CMake more than anything.

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Jan 27, 2016

It's not urgent, it's just something that probably should take a bit of a priority over other things. Thanks for taking a look at it!

@ghost

This comment has been minimized.

Copy link

ghost commented Feb 4, 2016

Well, I did look at it over the weekend, I just haven't got around to replying here until now.

On the original problem, I think the best way is to always force the alleg_main library to be static. That way the real main function in alleg_main knows the address of the mangled main in the executable at link time, before the symbols are stripped. Otherwise it's got to resolve it at runtime which it can't if the executable has been stripped.

The alternative was as suggested by Malcolm - pass flags into the strip program to ensure it leaves the mangled main entry alone. This seems more complicated and error-prone to me.

To make alleg_main always static is simple enough in CMake. Unfortunately there's a bit more messing about if the user wants the monolith option, which I haven't sorted out yet.

However alleg_main is a funny sort of 'add-on', isn't it? It's actually empty for all platforms except OS X (even iOS, not sure how that can be?) So someone developing on Linux would probably forget to include it and then find it wouldn't build on the Mac. Ideally it would just hitch a ride with the allegro core library, so pkg-config --libs would yield -lalleg_main -lalleg.

Any thoughts on this:

  • Quick fix (once I've sorted out monolith), or
  • Roll it into the core?
@fatcerberus

This comment has been minimized.

Copy link
Contributor

fatcerberus commented Feb 4, 2016

allegro_main really isn't an add-on in the normal sense of, say, allegro_audio - it's just a shim to make things work properly on all platforms without code changes.

Personally I would be okay with allegro_main always being a separate library and static, even when compiling a dynamic monolith. It doesn't really make much sense being in the core, I don't think.

@ghost

This comment has been minimized.

Copy link

ghost commented Feb 4, 2016

On @trentg 's comments,

It seems to me that homebrew is designed to support the Unix way of organising things, separating /bin and /lib directories for example.
In addition there's the 'bundle' approach which I'd say is more Mac-like. It's certainly possible to use homebrew-provided libraries to make bundles but it's sort-of swimming against the tide a bit. If I were making a Mac app I'd go for static linking first, otherwise (embeddable) frameworks, rather than trying to work with homebrew's dylibs.
I'd love to hear your input Trent you've had far more experience than me on these things.
What we really need is the canonical example on how best to package an Allegro game for Mac (maybe Cosmic Protector is already it, I'm not sure)

@fatcerberus Apple do seem to deprecate things very aggressively in the SDK compared to MS - but once built, the backward compatibility is good. Anyway Allegro should shoulder all that pain for you 😁

@ghost

This comment has been minimized.

Copy link

ghost commented Feb 4, 2016

It doesn't really make much sense being in the core, I don't think.

Yes sorry I didn't mean make it part of the core, that would be no better than the current situation. What I meant was just make pkg-config always pull in alleg_main when asked for the allegro libs.
This applies to OSX, on other platforms it could stay as it is, or it could pull in the current 'do-nothing' alleg_main.

@goobliata

This comment has been minimized.

Copy link
Member

goobliata commented Feb 4, 2016

When I mentioned homebrew, it was only because the a.cc thread was trying to use it to make bundles. That was essentially the original problem, which might not be fixed completely by making a static allegro_main. I'm Ok with that though... I don't think if you're putting any effort into your game you're going to use homebrew libraries in a bundle if only for the fact that it includes a ton of stuff you probably wouldn't even be using (third party libraries and addons.) Personally I've always used static linking.

I guess at worst this fix would ALLOW using homebrew, you just still have to mess with install_name_tool and stuff.

@fatcerberus

This comment has been minimized.

Copy link
Contributor

fatcerberus commented Feb 4, 2016

Is static linking considered the norm on OS X? On Linux it's practically blasphemous.

@goobliata

This comment has been minimized.

Copy link
Member

goobliata commented Feb 4, 2016

It is normal on OS X yes, very few libraries install globally. At the least embedded frameworks are also common. On Linux, things might change since Ubuntu is planning on using a type of static linking for all installed applications soon to make maintenance easier (or just create a whole different set of problems...)

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Feb 6, 2016

So it seems like the solution would be to also build a static version of Allegro for homebrew? I could ask homebrew folks if they would be okay with it (after all, they do have to pay for the servers that build the binaries).

I don't understand the point about pkg-config. Does that even work on OSX?

@fatcerberus

This comment has been minimized.

Copy link
Contributor

fatcerberus commented Feb 6, 2016

I think the idea was to just build allegro_main statically - the rest can remain dynamic since they don't cause issues.

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Feb 6, 2016

From my understanding, if you want to create a bundle, then it's easiest to link allegro_main statically. For non-bundle programs, dynamically linked allegro_main seems to work fine.

That said, Allegro builds the demos as bundles and they seem to work fine with a dynamic allegro_main as well, so I still don't quite get what is different between what is done for demos and what is done when making a bundle manually.

@ghost

This comment has been minimized.

Copy link

ghost commented Feb 7, 2016

The original problem was that Xcode, when deploying, strips the symbols
from the executable so the mangled main can't be found. In development mode
it's fine, when making a 'UNIX-style' application it's fine.
On Sat, 6 Feb 2016 at 22:28, SiegeLord notifications@github.com wrote:

From my understanding, if you want to create a bundle, then it's easiest
to link allegro_main statically. For non-bundle programs, dynamically
linked allegro_main seems to work fine.

That said, Allegro builds the demos as bundles and they seem to work fine
with a dynamic allegro_main as well, so I still don't quite get what is
different between what is done for demos and what is done when making a
binary manually.


Reply to this email directly or view it on GitHub
#555 (comment).

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Feb 7, 2016

I looked a bit closer at what Allegro does for its demo bundles. Indeed, it creates them sort of fine with dynamically linked allegro_main, but it uses absolute paths, so it's not quite ready for distribution. That said, I tried using https://github.com/auriamg/macdylibbundler which tries to automatically copy over things into the bundle and fix up the paths, and that seemed to work just fine. I think the difference is that CMake constructs the bundles manually and maybe it doesn't do the symbol stripping.

So overall, it seems like to me that it's simplest and best to just also provide the entirety of Allegro statically linked, and depending on what's easier, let the user choose whether or not to link allegro_main statically.

@harrowm

This comment has been minimized.

Copy link

harrowm commented Feb 14, 2016

Hi it's Malcolm. Sorry I didn't realize the conversation was continuing here. Providing a set of static libraries would be great! Fixing the rpath on the dynamic libraries via cmake and also having a static main library is also great!

With regards to why the examples work ok, I can't remember .. But my guess is if you don't specify to use xcodebuild as the tool chain in cmake then it defaults to using gcc? and a different linker ?

Regards
Malcolm

@SiegeLord SiegeLord removed the 5.x label Mar 19, 2016

@harrowm

This comment has been minimized.

Copy link

harrowm commented May 6, 2016

All,
Here's the link to my latest effort .. which include my own instructions on how to build Allegro on OSX. Note that I stripped out all the dependencies that I don't use .. e.g. FLAC .. but its still quite complex. Thomas commented on my post that we should look at Cocoapods to automate the dependencies. Has anyone tried this before? I must say that Nuget on Windows is so simple in comparison !

Malcolm

http://www.stardot.org.uk/forums/viewtopic.php?f=44&t=9065&start=90

@tonmanayo

This comment has been minimized.

Copy link

tonmanayo commented Jun 19, 2017

how is this still not fixed?

@SiegeLord

This comment has been minimized.

Copy link
Member Author

SiegeLord commented Jun 19, 2017

It was considered that the workaround (macdylibbundler) was good enough for now, but in fact recently I've seen people have trouble with it. The way forward is to build Allegro statically on homebrew, which requires fixing #773 at the very least.

@tonmanayo

This comment has been minimized.

Copy link

tonmanayo commented Jun 19, 2017

@SiegeLord so i'm busy creating a dynamic library on osx which statically links to allegro5 but the problem is when you call the new dynamic lib and try and link it, it cries because there is no main. dlopen(libs/lib1-opengl/libOpenGL.so, 8): Symbol not found: __al_mangled_main
Referenced from: /nfs/zfs-student-6/users/tmack/.brew/opt/allegro/lib/liballegro_main.5.2.dylib
Expected in: flat namespace
in /nfs/zfs-student-6/users/tmack/.brew/opt/allegro/lib/liballegro_main.5.2.dylib

and if I take out the linking of the allegro main function no window shows but the program logic works, because it detects the snake crashing into a wall?

all my code and suff is here, under lib/lib1-opengl
https://github.com/tonmanayo/nibbler

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.