svkaiser / Doom64EX

Doom64EX is a reverse-engineering project aimed to recreate Doom64 as close as possible with additional modding features.
http://doom64ex.wordpress.com/
GNU General Public License v2.0
239 stars 49 forks source link

Fix building on macOS #62

Closed Tatsh closed 7 years ago

Tatsh commented 7 years ago

This fixes building on macOS with latest Xcode and developer tools installed, using MacPorts to provide dependencies. Fixes make install although on macOS in a semi-hacky way, but this way makes it the same as on Linux. It is acceptable for developers.

For some reason, the forward declarations did not work with the latest Clang/Xcode, so I switched them to includes.

Also, I do not recall atoi() being in the std namespace? Was this a typo?

To make this more normal to macOS users, on make install you could recursively copy the ${CMAKE_CURRENT_BINARY_DIR}/doom64ex.app directory to /Applications. But then I think you should copy ${CMAKE_BINARY_DIR}/kex.wad to ~/Library/Appication Support/doom64ex/ to complete the job. And you would need to add what to run to generate the wad file, and where to put it (~/Library/Appication Support/doom64ex/).

Updated to install a proper bundle in /Applications. Added notes.

pinkwah commented 7 years ago

Fantastic, thanks. I only got it to work yesterday, and my changes were the pretty much the same. Great minds think alike, I guess.

All standard functions, including those from C, should be in the std namespace. (§17.6.1.2.3/4). So the Apple is in the wrong here.

The forward-declaration of std classes, however, is apparently UB. I guess they're correct in this regard.

pinkwah commented 7 years ago

Do you know anything about how to distribute binaries for macOS? Ie. creating a dmg and including dylibs properly in the app.

Tatsh commented 7 years ago

Right now the install target installs a fully distributable binary, especially since it does not include any copyrighted stuff. It includes all the dylibs used to compile. This is acceptable for now for the majority of users who will see this.

One thing that affects any project for macOS is signing. There has to be someone who can sign the binary who is on Apple's developer program (l am one), otherwise macOS will give a warning about launching this app and I don't think you want that. Note the equivalent exists on Windows, as you know Windows will ask if you want to run the 'unsafe' binary downloaded from the internet (unsigned). This may just be a game clone, but binary signing makes any project look far more professional.

To make this really distributable, we should put the generated kex file in dex64.app/Contents/Resoruces and read it from there. Configuration would still be as it is right now. Anyone playing this on Mac should not expect much support yet in terms of GUI and what not. So we would expect them to know to run the correct command to generate the files out of the ROM.

In the future, and this is for any OS, I think the app should offer to convert from a specified ROM file in just a series of dialog boxes (all native to avoid more dependencies: Cocoa on Mac, on Windows MessageBox/OpenFile/etc). Even on Linux it's possible to use kdialog by process (and the equivalent for Gtk) to ask this sort of question and provide a somewhat decent experience all without CLI. I'm willing to do this GUI part soon (all 3 platforms).

pinkwah commented 7 years ago

Thanks. I'm not too worried about signing on Windows, but on macOS it might be nice, yes.

I'm currently busy working on having the engine load the ROM directly without generating the WAD in advance. I think it should be possible to get it working soonish.

I realise that a GUI is still needed, so I'm also thinking of writing a "module" that implements the API below. On Windows and macOS I can just have a single implementation, since I only need to target a single toolkit. On Linux I can have two additional libraries: nativeui_gtk3.so and nativeui_qt5.so. I can then check if the user has the required toolkit libraries before dlsym-ing the relevant functions.

namespace imp {
  namespace native_ui {
    // Show an error message box. Guaranteed to be available even without
    // calling `init`. Uses SDL_ShowSimpleMessageBox on Linux if neither GTK3+
    // or Qt5 are present.
    void show_error(StringView message);

    // Initialize Native UI. Dynamically load the GTK3 or Qt5 library at runtime
    // depending on display environment
    void init();

    void quit();

    // Returns true if Native UI options are available. On Windows/macOS it
    // returns true as WINAPI or Cocoa are available, On Linux it returns false
    // if neither GTK3, nor Qt5 were found. If false, it's expected that
    // messages are printed to `stdout`.
    bool is_available();

    // If true, display the console and bring it to front. If false, hide it.
    void console_show(bool);

    // Append a line to the console.
    void console_add(StringView);

    // If the user has typed something into the console text input widget.
    // Returns true as long as there is data that was modified. User's text gets
    // copied into the `input` reference.
    bool console_poll(String& input);

    // Show a dialog box telling the user that they're missing the Doom 64 ROM.
    // Let the user select the rom file with a file chooser dialog. Check to see
    // if the ROM is a valid Doom 64 ROM. If not, display an error and let the
    // user choose again. If it's valid, ask the user if they want the ROM to be
    // copied (and renamed) to the Doom64EX data directory. Returns true if a
    // ROM was found, false if the dialog was cancelled.
    bool rom_dialog(String& rom_path, bool& copy_rom);
  }
}
Tatsh commented 7 years ago

Interface looks good. Also looked into SDL_ShowSimpleMessageBox and its pretty good without needing anything special on Win/Mac, although the X11 primitives thing it does on LInux sounds horrible so I agree Gtk+/Qt should be tried first there. In particular, if you find XDG_SESSION_DESKTOP=KDE in environment, go with Qt, otherwise search for GNOME/Xfce and go with Gtk+, or try the two so files assuming there's no such environment (i.e. using i3), or fall-through to SDL_ShowSimpleMessageBox.

Tatsh commented 7 years ago

Also regarding std::atoi() that fix was my original fix, to remove the std:: part and see that it works. You can put std:: back, as we do not want to use deprecated syntax. The include is still required though.

pinkwah commented 7 years ago

Nah, It's fine. It's too much hassle to change it.

Tatsh commented 7 years ago

Maybe could do this with the kex file? http://csl.sublevel3.org/post/embedding-binary-data/ On Windows you need to create a .res with header file giving it a number and what not.

pinkwah commented 7 years ago

I looked at it before, but I think it's unnecessary. This would only be applicable to Windows users, but as it currently stands, the "installation" is horrible and adding the kex.wad as a resource would only deter potential modders who may want to inspect all of the data.