Skip to content

Instantly share code, notes, and snippets.

@Yanrishatum
Last active April 8, 2023 15:50
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Yanrishatum/d69ed72e368e35b18cbfca726d81279a to your computer and use it in GitHub Desktop.
Save Yanrishatum/d69ed72e368e35b18cbfca726d81279a to your computer and use it in GitHub Desktop.
How to compile HL/C

How to compile HL/C

Prepwork/terms

Because I have no trust in people.

  • <hashlink> points to your installation of Hashlink, e.g. folder in which hl.exe (or Unix executable) is, alongside with library binaries (.hdll files), and include folder.
  • <src> points to the folder containing generated HL/C sources. One that contains hlc.json file.
  • <app> refers to your output executable name, including extension.
  • <main> refers to your entry-point file name, including extension (see below).
  • I provide example of doing it on Windows via MSVC cl.exe, but Unix should be more or less same with replacement of argument flags and compiler.
  • I expect that you DO have a compiler installed and can call cl.exe or other compiler from command-line.
  • As far as I'm aware - static linking of libraries not possible atm.
  • hlc.json contains information you need in order to compile the sources. It's contents are referenced as <hlc.*>. <hlc.libs> for example.
    • version tells what format version this hlc.json is. Instructions are based on version 4000, but should work on newer ones if they are to follow.
    • libs array contains the list of referenced hdll libraries.
    • defines provide defines used during compilation, and can be safely ignored.
    • files array contains all generated files, with first file always being the entry-point.
  • std library as a file is libhl.dll, not std.hdll.
  • Some libraries need you to copy dependency files alongside the hdll file.
    • sdl -> SDL2.dll
    • openal -> OpenAL32.dll
  • If you are using any external hdll libraries - find them in respective library locations.

Generating HLC

First of all, to generate HLC sources instead of HL bytecode you just replace -hl command extension from .hl to .c. That name also will be your entry-point file name. And be sure to use subfolder (-hl hlc/game.c), because you don't want to pollute your root with .c output ;)

MSVC

General template

cl.exe /Ox /Fe <app> -I "<hashlink>\include" -I "<src>" "<src>\<main>" "<hashlink>\libhl.lib" ...libs

Meaning

  • /Fe <app>: Output to an executable, for example /Fe game.exe would produce a game.exe executable in cwd.
  • -I "<hashlink>\include": Includes hashlink headers, as they are mandatory in order to compile.
  • -I "<src>": Includes source files.
  • "<src>\<main>": Specifies entry-point.
  • Libraries: Here you should link all libraries that are listed in <hlc.libs>. At the very least it's libhl.lib, but in case of Heaps - it expands to at least fmt.lib, ui.lib, openal.lib, and sdl.lib or directx.lib.
  • /Ox is optional optimization flag.

Command sample

cl.exe /Ox /Fe app.exe -I "%hashlink%\include" -I "hlc" "hlc\app.c" "%hashlink%\ssl.lib" "%hashlink%\directx.lib" "%hashlink%\openal.lib" "%hashlink%\fmt.lib" "%hashlink%\libhl.lib"

Notes

Make sure you're running 64-bit MSVC on newer Hashlink, because it defaults to 32-bit if you're running MSVC dev shell.

GCC

Note: This is untested. Ping me in discord if there are errors or if it worked for you.

General template

gcc -O3 -o <app> -std=c11 -I <src> <src>/<main> -lhl /usr/local/lib/libhl.so ...libs

Meaning

  • -o <app>: Output to an executable.
  • -std=c11: Some mandatory GCC stuff. ;)
  • -I <src>: Includes source files.
  • <src>/<main>: Specified entry-point.
  • -lhl: Includes hashlink includes via -l flag. Alternatively should work with -I <hashlink>/include.
  • Libraries: See above. Note that for unix systems it should be .hdll / .so instead of .lib, depending on which library you refer to. Also if you can't be assed: Include all hdlls possible, see below.
  • -O3 is optional optimization flag.

Command sample

gcc -O3 -o app -std=c11 -I out hlc/app.c -lhl /usr/local/lib/*.hdll

Bundling

To get your compilation portable, you should not forget to copy over all linked .hdll files near executable, as well as libhl and all dependency libraries (sdl/openal).

??????

Profit!

That's it. Really. There's nothing more to it.

Ma, I can't get assed to do this shit!

Well, I don't give a damn. Sucks to be you I guess. ¯\_(ツ)_/¯

Aka alternative approaches.

Windows visual studio template

haxelib install hashlink # Install HL support library.
haxelib run hashlink build <src> -D hlgen.makefile=vs2015 # Generate template

Then just open your vs project file and compile.

Bundle Hashlink with the game

  • Route A: Rename your .hl to hlboot.dat and run hl.exe (Afaik, DeadCells used this before switching to precompiled HLC)
  • Route B: Use cmd file that just does hl game.hl (I use that approach for development builds internally)
@nyash
Copy link

nyash commented Oct 27, 2020

@nyash I'm getting this output:

C:\Users\Jerry\projects\heaps-examples\heaps-game>cl out/main.c /Ox /Fe:app.exe -I "C:\HaxeToolkit\hl-1.11.0-win\include" -I "out" "C:\HaxeToolkit\hl-1.11.0-win\ssl.lib" "C:\HaxeToolkit\hl-1.11.0-win\directx.lib" "C:\HaxeToolkit\hl-1.11.0-win\openal.lib" "C:\HaxeToolkit\hl-1.11.0-win\fmt.lib" "C:\HaxeToolkit\hl-1.11.0-win\libhl.lib"
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.c
Microsoft (R) Incremental Linker Version 14.27.29111.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:app.exe
main.obj
C:\HaxeToolkit\hl-1.11.0-win\ssl.lib
C:\HaxeToolkit\hl-1.11.0-win\directx.lib
C:\HaxeToolkit\hl-1.11.0-win\openal.lib
C:\HaxeToolkit\hl-1.11.0-win\fmt.lib
C:\HaxeToolkit\hl-1.11.0-win\libhl.lib
main.obj : error LNK2001: unresolved external symbol sdl_gl_tex_image2d_multisample
main.obj : error LNK2001: unresolved external symbol sdl_is_cursor_visible
main.obj : error LNK2001: unresolved external symbol sdl_gl_create_renderbuffer
main.obj : error LNK2001: unresolved external symbol sdl_gl_init
main.obj : error LNK2001: unresolved external symbol sdl_gl_vertex_attrib_divisor

The rest errors
I wonder how those /Ox /Fe flags are working, never seen attributes starting with /, seems like some odd feature. I've used them as you suggest there though, and I've used "Cross Tools Command Prompt" instead of bash, and at least it started doing something, and generated some main.obj binary file, but yet: still fails with many errors and still no executables :(

From the looks of it, you are missing "C:\HaxeToolkit\hl-1.11.0-win\sdl.lib" in cl.exe command. (Linker fails to find sdl_ functions).

Regarding the flags to cl.exe, that's the style used by a lot of windows batch programs.

@jerrygreen
Copy link

jerrygreen commented Oct 27, 2020

@nyash, oh, you're right! I've just added it, along with ui.lib, and it worked!

However, I find two inconveniences here:

  1. The final executable is a command prompt.
    And this command prompt creates a new window with actual game, so there's two windows running... Weird. How is that possible to get rid of this command prompt, leaving the game window only?

  2. Usage of "Native Tools Command Prompt" instead of bash when compiling.
    By adding /c/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64" to my environment variables, I made cl.exe visible in bash, but by running the same command, it still stucks into Cannot open include file: 'math.h': No such file or directory error I mentioned earlier, so it seems it lacks some part of environment of this "Native Tools Command Prompt"... How can I compile it with bash, directly from Visual Studio Code, from an integrated terminal, instead of this "Native Tools Command Prompt"?

RE /Ox /Fe and such flags, - I may probably seen it long before, but last several years I was using macos and linux, so they seem weird to me, because I've seen only -flag, --flag and --flag=value approaches :)

@nyash
Copy link

nyash commented Oct 28, 2020

@nyash, oh, you're right! I've just added it, along with ui.lib, and it worked!

However, I find two inconveniences here:

  1. The final executable is a command prompt.
    And this command prompt creates a new window with actual game, so there's two windows running... Weird. How is that possible to get rid of this command prompt, leaving the game window only?
  2. Usage of "Native Tools Command Prompt" instead of bash when compiling.
    By adding /c/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64" to my environment variables, I made cl.exe visible in bash, but by running the same command, it still stucks into Cannot open include file: 'math.h': No such file or directory error I mentioned earlier, so it seems it lacks some part of environment of this "Native Tools Command Prompt"... How can I compile it with bash, directly from Visual Studio Code, from an integrated terminal, instead of this "Native Tools Command Prompt"?

RE /Ox /Fe and such flags, - I may probably seen it long before, but last several years I was using macos and linux, so they seem weird to me, because I've seen only -flag, --flag and --flag=value approaches :)

  1. Hm... you are right. I spent some time on it, and there are two solutions.
    a) You can insert hl.UI.closeConsole(); inside your heaps Main classes' init function. (Not ideal, because the console will still be visible for a split second).
    b) We need to change the subsystem (by adding a parameter to cl.exe) from console (meant for console apps (default) - the reason why the console window is visible in the first place) to windows (meant for gui apps) when compiling with cl.exe

So the entire command (from my examples) would be:

cl.exe out\main.c /Fe:main.exe /Ox -I C:\HaxeToolkit\hl\include -I out C:\HaxeToolkit\hl*.lib /link /subsystem:windows

However, the chances are you will see an error like: "int __cdecl __scrt_common_main_seh(void)" (?__scrt_common_main_seh@@yahxz)
main.exe : fatal error LNK1120

Apparently, the hlc_main.c file that is included with the hashlink installation that I have unpacked to C:\HaxeToolkit\hl\include lacks a WinMain function which is a required entry point for gui apps on windows.

But on github I can see that such declarations were added to hashlink, so if you get the above error, do the following:

  1. Copy the contents of hlc_main.c from https://github.com/HaxeFoundation/hashlink/blob/f5e7b4ffb50bcad13945cc536ee049b38ee8d771/src/hlc_main.c
  2. Paste them to your location where you keep hlc_main.c (In my case it's under C:\HaxeToolkit\hl\include\hlc_main.c)
  3. Rebuild heaps app and Compile again with cl.exe

After these steps the console window is completely gone.

@jerrygreen
Copy link

@nyash, just tried this new hlc_main.c, and heck, that worked! No command prompt now, just a game :) That's so hacky though... Thx.

Copy link

ghost commented Mar 4, 2022

i managed to build using mingw-w64 on windows and it run perfectly
im using a simple heaps project that show text on the screen

gcc out/main.c -o main.exe -std=c11 -I out -I C:\HaxeToolkit\hashlink\include -L C:\HaxeToolkit\hashlink\ C:\Windows\System32\dbghelp.dll C:\HaxeToolkit\hashlink\*.hdll -libhl

@Pasha-Makarenko
Copy link

I using hlc-compilerhttps://github.com/fal-works/hlc-compiler.
My command in conlose:

haxelib run hlc-compiler --srcDir bin --srcFile app.c --outFile redist/app.exe --hlcJsonFile hlc.json --hlLibDir C:/HaxeToolkit/hl --hlIncludeDir C:/HaxeToolkit/hl/include --copyRuntimeFiles --exFile C:/Windows/System32/dbghelp.dll --saveCmd redist/run_gcc.bat -w --relative --compiler gcc

and this command compiling c code to exe, but when i opened exe file i saw many green lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment