One feature that I find impressive about the Godot Engine is how it is so lightweight and quick to compile. I realize that Godot exports using its precompiled export templates but I am confused about how it does so. I am working on macOS so that's mostly what I'm curious about. How is Godot able to add code to a precompiled executable. I've spent hours looking through the source code but can't figure it out.
Godot's export templates are compiled binaries that use a specific set of SCons options. They're always built using tools=no which disables editor functionality, and official export templates use either target=release_debug or target=release optimizations (for debug and release export templates respectively).
Note that Godot doesn't compile native code when exporting a project -- it just bundles data, scripts and the export template together. Game data and scripts are packed into a PCK file, which is a custom archive format that can store arbitrary files (without compression). The export template then runs the main script contained in the PCK file.
Scripts are compiled to bytecode when exporting a project in release mode, which speeds up loading times but otherwise doesn't affect the script execution speed.
See this page on compiling binaries for macOS.
Related
I do have a strange behavior with a flutter package I am building. It uses FFI to integrate a custom-made c++ library.
When I run flutter run -d windows --release the code starts and I do have the window with the code running.
However, when I go to the directory where the executable is stored and I run it, the program starts but the library is not loaded. I do see also that when I run flutter test, it complains that it cannot load the library. I have checked that the dll's needed are there using dependenciesGUI.exe and it seems that everything is fine, at least on my side. I do see however that within kernel32.dll I am missing ext-ms-win-oobe-query-l1-1-0.dll.
I am using Visual Studio 2022 with the x64 configuration.
Any idea on what could be the issue? For me it is VERY puzzling to be able to run the software through flutter but not with the executable directly.
Thanks!
Yours,
Pi-r
EDIT:
I compared my package with a fresh package built with flutter. With a fresh package, the behavior is the one expected: I can have the program run normally or with flutter run.
I compared the libraries of the clean package with the ones linked in my package. They are the same (with the same missing dlls which do not seem to pose an issue).
I also checked that the exported functions I needed where present -> It is the case.
The only difference I can see is that using flutter run adds a series of libraries to the path. Has I am a Linux person, I do not know of a tool that could be used to detect what is the missing library. I am open to write a separated c++ code that would load the library if it could help me identify what is the issue... ANY tips/tricks would be greatly appreciated :)
I finally found the issue I had and it is related to a different behavior under Linux and under Windows (as you will guess, I am a Linux person).
When compiled under Linux, I can force the compiler to link multiple libraries relatively to my main library. I discovered that this is not the case under Windows. Either the dlls are in the executable folder or in the Path.
For the sake of code clarity, my package uses two different libraries. Library A, which is compiled from flutter with the ffi package, called library B. First the second library was in the asset folder and with the relative linking of Linux, it was working perfectly. But it did not work under Windows until I explicitly copied the two in the same directory of the executable.
The solution was then to ensure that both libraries are copied correctly in the directory of the flutter executable. This can be done easily if you add the dependent libraries to the bundle variable in the CMakeLists.txt of the package.
However, this doesn't work when you do the testing (flutter test). As the bundle mechanism seems to be not propagated to the test function. Therefore here, the only solution is to copy the dependent libraries to the root directory of the source code :vomiting_face:
I must point out that this is only the case under Windows, for Linux, it works out of the box...
I am using rtags which is a C++ source code indexer based on clang. I have been able to play around with it and now I want to actually index the firefox source code. I am pretty new to this stuff and this tool uses cmake to generate a compile_commands.json file to pass over to the program that indexes code.
Is there a way I can generate a the compile_commands.json file for the firefox source code that provides the exact compilation line for each translation unit inside the firefox source?
You can generate compile_commands.json by
mozilla_cnetral/mach build-backend -b CompileDB
In my environment(Ubuntu 16.04), it was created at mozilla_cnetral/obj-x86_64-pc-linux-gnu/.
Reference:
https://developer.mozilla.org/en-US/docs/Developer_Guide/Editor_Configuration#rtags_(LLVMClang-based_Code_Indexing)
Not sure if I follow the part "Is there a way I can generate a the compile_commands.json file for the firefox source code that provides the exact compilation line for each translation unit inside the firefox source?". But I can offer simply that you can generate a compile_commands.json file from a make-based system using the bear utility (which I obtained from my package manager: brew). After a make clean, I do 'bear --append make' and it traces the make build process and produces the compile_commands.json. More can be learned here: https://vxlabs.com/2016/04/11/step-by-step-guide-to-c-navigation-and-completion-with-emacs-and-the-clang-based-rtags/
As the article referenced implies, my motivation was to be able to use the wonderful rtag system inside Emacs. Hope this helps a bit.
I've written a small library as a Qt project using Qt Creator, now I want to create a small GUI application that can be used to test it as part of the development process, so it could be like this:
Project root at:
~/code/mylib
Library project and associated code:
~/code/mylib/corelib/corelib.pro
GUI test tool and associated code:
~/code/mylib/libgui/guitool.pro
So far I've only been able to make things work by setting up LIBS+= in the GUI project's .pro file, manually building the library, copying the library's .a file to the GUI directory, and rebuilding the GUI project. A tedious process. Worse: I'm developing the project now on Linux but need to make it build on Linux and Windows, and this manual build style will probably make that harder.
I suppose there's a way to do make Qt Creator aware of the relationships between the projects, so for example building the GUI tool in debug mode use the debug version of the library, or making changes to the corelib would necessitate a build in the GUI, building on some OS would use the libraries OS-configuration...etc
This kind of thing is a couple of clicks away in Eclipse and Visual Studio, but I can't seem to get it working in QtCreator. I've tried "Add library->Internal library" and creating a 'subdirs' project but neither seems to work. I feel it's probably a simple step that I'm missing somewhere, any help?
Try again to use subdirs feature. It have own wizard "Project with subdirectories", but in your case it's easier to write it manually (in example I've added "ordered" to ensure that order of compilation is always correct).
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = corelib guitool
Than you can add libary to your GUI application with wizard (accessible from context menu inside .pro).
I've created an OpenGL application using the Command Line Tool project template.
Now the output project is obviously a unix executable.
My question is How can I convert this executable into a bundle .app?
Have I to add another target?
If you created a command line tool, it is just that, a command line tool. I don't know of any way to bundle it up into an application with ease.
If I were you, and you are going to start writing Mac OpenGL application, get set up with SFML. It greatly simplifies window creation, is cross platform and has a great community. Also, getting to the resource path in a mac .app bundle is a bit tricky and the templates they provide allow you to access any file with a call:
loadFile(resourcePath() + "filename.txt");
rather than having to keep track of everything. Plus, the whole resource path code is written in objective C which can be a pain for some C++ programmers.
The whole framework is pretty robust but maintains a simplistic style and its own namespace. Use what you want, don't use what you don't need. The latest version (still beta) 2.0, comes with Xcode templates. Just create a template and in build settings for your project, scroll to the bottom. You'll see SFML_LINK_DYLIBS_SUFFIX and it has a value of '-d'. Remove the '-d' and it should compile.
Then if you are distributing, add a copy files build phase and link the .dylib(s) that you used.
How to build a .bundle from source code?
This might sound like a simple problem but it has been hurdling me for a week...
Here is my problem:
I have a bunch of .c and .h files that are organized in a folder and its sub folders. The source code was written and compiled with gcc make and tested by many other make tools. The source code has some utilities and command line tools and it has more code that serve as library for those utilities and tools. It is the files that serve as libraries that I want to reuse. (By library I don't mean static library or something, I just mean that some .c and .h files in certain subfolders provide functions that can be called by some other .c files. I want to be able to call those functions, too)
Yet my problem is more complex than that: I need to build those .c and .h into a bundle to reuse it. I am not writing my application in C; I am developing in Unity and Unity can only take in .bundle files on Mac OS.
Here is my goal:
Organize the source code folder in a proper way so that I can build them into a bundle in Xcode 4.
Here is where I got stuck:
When building the project I got the following error:
Duplicate symbol _main in
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o
and
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o
for architecture i386
I can relate to this error because I can find lots of main entries in the source code. Most of them are test utilities.
Here is what I tried:
I tried removing all those utility .c files but with no luck. The error is still there. I delete and delete until some files cannot find the definition of the function they are calling. So I had to stop there.
Though I wasn't able to build a bundle I was able to build a C/C++ static library (with an .a extension). After I got the .a file I tried to put it into another Xcode project and tried to build it into a bundle. I could build a bundle in that way, but then I had problem accessing the content of the bundle. How do I call functions defined in a .a static library if that library is hidden in a bundle? I read about Apple's documentation which says:
Note: Some Xcode targets (such as shell tools and static libraries) do
not result in the creation of a bundle or package. This is normal and
there is no need to create bundles specifically for these target
types. The resulting binaries generated for those targets are intended
to be used as is.
(quoted from: https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1)
Here is what I thought about:
I thought about replacing all main with something like main_sth. But the source code was not written by me so I didn't want to modify it. (It just doesn't feel like a proper way of doing things to me...)
I learnt that Xcode has gcc compiler built in. So I guess if gcc can make it, so can Xcode? It's just a wild guess - I am not familiar with Xcode and gcc.
Here is a summary of my questions:
Is there a way to properly organize a pile of code previously compiled and made by gcc make so that they can be built into an Xcode bundle?
Is it meaningful to put a .a library in an Xcode project and build it into a bundle? If it is meaningful, how do I call functions defined in .a after it is built into a bundle?
Is it proper to just replace all main() entries with something else?
Alright I think I have figured out at least one solution to the problem.
The duplicate main error was caused by a bunch of main entries in my source code. When the code was compiled by gcc make, I guess the author defined a sort of compilation order so that duplicate mains won't be an issue. (If you know how to do this, please let me know. I barely know make tools.) But when I just add the entire source code folder into my Xcode project, of course Xcode would complain during linking...
As I was unwilling to modify the source code (because the source code library is not developed by me), I decided to use another strategy to walk around this problem.
If your duplicate main error was reported from your own code, you can stop reading here. But if you are like me, with a bunch of gcc compiled source code and badly need a bundle yet don't know what to do, I may be able to help.
Okay here is what I did:
I set up an empty workspace.
I built a C/C++ static library project.
Import my entire source code folder into the static library project.
Set some header search path for the static library project.
Build the static library project. (Now I have a .a library which I could link against)
I set up another project, with a bundle target.
At the bundle project -> Build Phases -> Link Binary with Libraries, add the .a library that I just built.
At the bundle project -> edit scheme -> Build, add the static library project to the scheme and move it up the list so that it is built prior to my bundle project.
Then add .h files of my library project to my bundle project as references.
After that, add a .c file in my bundle project that basically functions as a wrapper. I picked a function that I want to call in Unity, wrote a wrapper function in the new .c file, and was able to build the bundle.
After several trial and error, I was able to import the bundle into Unity and was able to call the test function from Unity.
I was really excited about this! Though it's not completed yet I think this gives me hope and I am confident I can use the source code now! And the best thing about this solution is that I don't have to modify the library code developed by others. Whenever they update their code, I just update my .a library and that's it!
Though I have listed 11 steps I still feel that there are lots of details that I missed. So here are my references:
I followed this tutorial to build my source code into a static library: http://www.ccnx.org/?post_type=incsub_wiki&p=1315
I followed this blog to link static library against my bundle code and twist build phases and search headers: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/
I followed this doc to import my bundle to Unity3D Pro as a plugin: http://unity3d.com/support/documentation/Manual/Plugins.html
I strongly recommend the second reference because that's what solved my problem!
Though the problem is almost solved there are still a few things that I haven't figured out:
I don't know if a wrapper function is at all necessary. I will try this out tomorrow and come back to update.
-- I am coming back to update: the wrapper function is NOT necessary. Just make sure you have all the headers in your bundle project and you will be able to use all the data structures and call functions defined in your headers.
I haven't used NSBundle class though I read a few docs about it. Previously I was thinking about using that class to access my .a library encapsulated in my bundle, but as I found the solution I wrote above, I didn't try the class out.
Lastly, if you have better solution, please don't hesitate to let me know!
I tried to follow the steps in the accepted answer, but had no luck. In the end, I realised step 10 needed to be modified slightly:
Create a dummy.c under (.bundle) project and the dummy.c can just be totally empty.
Remove the setting for the library you want to link inside Link Binary With Libraries
Instead use -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a or -all_load to Other Linker Flags
PS: And also can use sub-project instead of workspace. and use Target Dependencies instead of Edit Scheme to achieve the same effect.