2023-10-10 12:00:35 +00:00
# define DQN_IMPLEMENTATION
# include "External/tely/External/dqn/dqn.h"
2023-10-12 11:20:29 +00:00
# define DQN_CPP_BUILD_IMPLEMENTATION
# include "External/tely/External/dqn/dqn_cppbuild.h"
2023-10-10 12:00:35 +00:00
2023-12-01 05:46:58 +00:00
struct BuildTime
2023-10-11 13:04:01 +00:00
{
2023-12-01 05:46:58 +00:00
Dqn_Str8 name ;
uint64_t timestamps [ 2 ] ;
} ;
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
enum Compiler
{
Compiler_MSVC ,
Compiler_GCC ,
Compiler_EMCC ,
Compiler_Count ,
} ;
2023-10-11 13:04:01 +00:00
2023-11-26 05:54:21 +00:00
# define PRINT_HELP Dqn_Print_StdLnF(Dqn_PrintStd_Out, "USAGE: feely_pona_build [--help|--dry-run|--web|--fast-dev-build|--msvc|--gcc]")
2023-10-12 11:20:29 +00:00
int main ( int argc , char const * * argv )
2023-10-11 13:04:01 +00:00
{
2023-12-01 05:46:58 +00:00
// NOTE: Preamble ==============================================================================
2023-10-12 11:20:29 +00:00
Dqn_Library_Init ( Dqn_LibraryOnInit_Nil ) ;
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < BuildTime > build_timings = { } ;
BuildTime * global_build_timings = Dqn_FArray_Make ( & build_timings , Dqn_ZeroMem_Yes ) ;
global_build_timings - > name = DQN_STR8 ( " Dqn_CPPBuild Summary (Total) " ) ;
global_build_timings - > timestamps [ 0 ] = Dqn_OS_PerfCounterNow ( ) ;
#if 0
RebuildProgramIfRequired ( argc , argv ) ;
# else
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " -- Dqn_CPPBuild v0 " ) ;
# endif
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
bool build_using_compiler [ Compiler_Count ] = { } ;
// NOTE: Parse arguments =======================================================================
2023-10-25 09:17:30 +00:00
bool dry_run = false ;
2023-12-01 05:46:58 +00:00
bool fast_dev_build = false ;
2023-11-23 13:22:07 +00:00
for ( Dqn_isize arg_index = 1 ; arg_index < argc ; arg_index + + ) {
2023-10-24 12:41:15 +00:00
Dqn_Str8 arg = Dqn_Str8_InitCStr8 ( argv [ arg_index ] ) ;
if ( arg = = DQN_STR8 ( " --help " ) ) {
2023-10-12 11:20:29 +00:00
PRINT_HELP ;
return 0 ;
2023-10-24 12:41:15 +00:00
} else if ( arg = = DQN_STR8 ( " --dry-run " ) ) {
2023-10-12 11:20:29 +00:00
dry_run = true ;
2023-10-29 03:59:53 +00:00
} else if ( arg = = DQN_STR8 ( " --fast-dev-build " ) ) {
2023-12-01 05:46:58 +00:00
fast_dev_build = true ;
2023-11-26 05:54:21 +00:00
} else if ( arg = = DQN_STR8 ( " --gcc " ) ) {
2023-12-01 05:46:58 +00:00
build_using_compiler [ Compiler_GCC ] = true ;
2023-11-26 05:54:21 +00:00
} else if ( arg = = DQN_STR8 ( " --msvc " ) ) {
2023-12-01 05:46:58 +00:00
build_using_compiler [ Compiler_MSVC ] = true ;
} else if ( arg = = DQN_STR8 ( " --web " ) ) {
build_using_compiler [ Compiler_EMCC ] = true ;
2023-10-12 11:20:29 +00:00
} else {
PRINT_HELP ;
return 0 ;
}
2023-10-11 13:04:01 +00:00
}
2023-12-01 05:46:58 +00:00
// NOTE: Add a default compiler target if none were specified
{
size_t total_compiler_targets = 0 ;
for ( bool is_set : build_using_compiler )
total_compiler_targets + = DQN_CAST ( size_t ) is_set ;
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
if ( total_compiler_targets = = 0 ) {
# if defined(DQN_OS_WIN32)
build_using_compiler [ Compiler_MSVC ] = true ;
# else
compiler_targets [ Compiler_GCC ] = true ;
# endif
}
2023-11-25 07:28:55 +00:00
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Setup build ===========================================================================
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch ( nullptr ) ;
Dqn_Str8 const exe_dir = Dqn_OS_EXEDir ( scratch . arena ) ;
Dqn_Str8 const code_dir = exe_dir ;
Dqn_Str8 const build_dir = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Build " , DQN_STR_FMT ( exe_dir ) ) ;
Dqn_Str8 const tely_dir = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/External/tely " , DQN_STR_FMT ( exe_dir ) ) ;
# define RecordScopeTime(...) \
BuildTime * build_time_ = Dqn_FArray_Make < BuildTime > ( & build_timings , Dqn_ZeroMem_Yes ) ; \
build_time_ - > name = Dqn_Str8_InitF ( scratch . allocator , # # __VA_ARGS__ ) ; \
build_time_ - > timestamps [ 0 ] = Dqn_OS_PerfCounterNow ( ) ; \
DQN_DEFER { build_time_ - > timestamps [ 1 ] = Dqn_OS_PerfCounterNow ( ) ; }
bool assets_copied = false ;
for ( Dqn_usize compiler_index = 0 ; compiler_index < Compiler_Count ; compiler_index + + ) {
if ( ! build_using_compiler [ compiler_index ] )
continue ;
Compiler compiler = DQN_CAST ( Compiler ) compiler_index ;
Dqn_Str8 obj_file_extension = compiler = = Compiler_MSVC ? DQN_STR8 ( " obj " ) : DQN_STR8 ( " o " ) ;
Dqn_Str8 compiler_label = { } ;
switch ( compiler ) {
case Compiler_MSVC : compiler_label = DQN_STR8 ( " msvc " ) ; break ;
case Compiler_GCC : compiler_label = DQN_STR8 ( " gcc " ) ; break ;
case Compiler_EMCC : compiler_label = DQN_STR8 ( " emcc " ) ; break ;
case Compiler_Count : break ;
}
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Compile flags =========================================================================
Dqn_FArray32 < Dqn_Str8 > common_compile_flags_no_warnings = { } ;
if ( compiler = = Compiler_MSVC ) {
Dqn_FArray_AddCArrayAssert ( & common_compile_flags_no_warnings , {
DQN_STR8 ( " cl " ) ,
DQN_STR8 ( " -Z7 " ) ,
DQN_STR8 ( " -MT " ) ,
DQN_STR8 ( " -EHsc " ) ,
DQN_STR8 ( " -nologo " ) ,
} ) ;
} else if ( compiler = = Compiler_GCC ) {
Dqn_FArray_AddCArrayAssert ( & common_compile_flags_no_warnings , {
DQN_STR8 ( " g++ " ) ,
DQN_STR8 ( " -g " ) ,
} ) ;
} else {
DQN_ASSERT ( compiler = = Compiler_EMCC ) ;
# if defined(DQN_OS_WIN32)
Dqn_FArray_AddCArrayAssert ( & common_compile_flags_no_warnings , {
DQN_STR8 ( " cmd " ) ,
DQN_STR8 ( " /c " ) ,
DQN_STR8 ( " emcc.bat " ) ,
} ) ;
# else
Dqn_FArray_AddCArrayAssert ( & common_compile_flags_no_warnings , {
DQN_STR8 ( " emcc " ) ,
DQN_STR8 ( " -Os " ) , // Optimise for size
} ) ;
# endif
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > common_link_flags = { } ;
Dqn_FArray32 < Dqn_Str8 > common_compile_flags = common_compile_flags_no_warnings ;
Dqn_FArray_AddCArrayAssert ( & common_compile_flags_no_warnings , { DQN_STR8 ( " -w " ) } ) ;
if ( compiler = = Compiler_MSVC ) {
Dqn_FArray_AddCArrayAssert ( & common_compile_flags , { DQN_STR8 ( " -W4 " ) } ) ;
Dqn_FArray_AddCArrayAssert ( & common_link_flags , {
DQN_STR8 ( " -link " ) ,
DQN_STR8 ( " -incremental:no " ) ,
} ) ;
} else {
Dqn_FArray_AddCArrayAssert ( & common_compile_flags , {
DQN_STR8 ( " -Wall " ) ,
} ) ;
Dqn_FArray_AddCArrayAssert ( & common_link_flags , {
DQN_STR8 ( " -lm " ) ,
} ) ;
}
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Link flags ============================================================================
// NOTE: Build context =========================================================================
Dqn_CPPBuildContext common_build_context = { } ;
common_build_context . build_dir = build_dir ;
common_build_context . flags_style = compiler = = Compiler_MSVC ? Dqn_CPPBuildFlagsStyle_MSVC : Dqn_CPPBuildFlagsStyle_GCC ;
// NOTE: Build program =========================================================================
// NOTE: Copy assets ===========================================================================
if ( ! assets_copied ) {
RecordScopeTime ( " Copy assets " ) ;
assets_copied = true ;
Dqn_FArray32 < Dqn_Str8 > cmd_array = { } ;
# if defined(DQN_OS_WIN32)
Dqn_FArray_AddCArray ( & cmd_array , {
2023-11-26 03:03:46 +00:00
DQN_STR8 ( " robocopy " ) ,
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " /MIR " ) , // Mirror
DQN_STR8 ( " /NJH " ) , // No job header
DQN_STR8 ( " /NJS " ) , // No job summary
2023-11-26 03:03:46 +00:00
DQN_STR8 ( " /NDL " ) ,
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " /NP " ) , // No progress
2023-11-26 03:03:46 +00:00
} ) ;
2023-12-01 05:46:58 +00:00
# else
cmd_array = Dqn_FArray_AddCArray ( & cmd_array , {
2023-11-26 03:03:46 +00:00
DQN_STR8 ( " cp " ) ,
DQN_STR8 ( " --recursive " ) ,
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " --force " ) ,
2023-11-26 03:03:46 +00:00
} ) ;
2023-12-01 05:46:58 +00:00
# endif
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
DQN_MSVC_WARNING_PUSH
DQN_MSVC_WARNING_DISABLE ( 6063 )
DQN_MSVC_WARNING_DISABLE ( 6064 )
// TODO(doyle): The stringify macro in AddCArrayAssert triggers MSVC's code '-analyze'
// flag because it forwards the '%.*s' into Dqn_Log_TypeFCallSite which takes in a
// format string.
//
// warning C6064: Missing integer argument to 'Dqn_Log_TypeFCallSite' that corresponds to conversion specifier '1'.
// warning C6063: Missing string argument to 'Dqn_Log_TypeFCallSite' that corresponds to conversion specifier '2'.
// warning C6064: Missing integer argument to 'Dqn_Log_TypeFCallSite' that corresponds to conversion specifier '3'.
// warning C6063: Missing string argument to 'Dqn_Log_TypeFCallSite' that corresponds to conversion specifier '4'.
// NOTE: Copy the fonts
{
Dqn_FArray32 < Dqn_Str8 > font_cmd_array = cmd_array ;
Dqn_FArray_AddCArrayAssert ( & font_cmd_array , {
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Fonts " , DQN_STR_FMT ( exe_dir ) ) , // Source
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Fonts " , DQN_STR_FMT ( build_dir ) ) , // Dest
} ) ;
2023-11-25 13:52:50 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Slice < Dqn_Str8 > cmd_slice = Dqn_FArray_Slice ( & font_cmd_array ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%s' " , Dqn_Slice_Str8RenderSpaceSeparated ( scratch . arena , cmd_slice ) . data ) ;
if ( ! dry_run )
Dqn_OS_Exec ( cmd_slice , /*working_dir*/ { } ) ;
}
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Copy the audio
{
Dqn_FArray32 < Dqn_Str8 > audio_cmd_array = cmd_array ;
Dqn_FArray_AddCArrayAssert ( & audio_cmd_array , {
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Audio " , DQN_STR_FMT ( exe_dir ) ) , // Source
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Audio " , DQN_STR_FMT ( build_dir ) ) , // Dest
} ) ;
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Slice < Dqn_Str8 > cmd_slice = Dqn_FArray_Slice ( & audio_cmd_array ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%s' " , Dqn_Slice_Str8RenderSpaceSeparated ( scratch . arena , cmd_slice ) . data ) ;
if ( ! dry_run )
Dqn_OS_Exec ( cmd_slice , /*working_dir*/ { } ) ;
}
2023-11-25 07:28:55 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Copy the texture atlas
{
Dqn_Str8 atlas_dest_dir = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Textures " , DQN_STR_FMT ( build_dir ) ) ;
Dqn_Fs_MakeDir ( atlas_dest_dir ) ;
2023-10-15 12:08:47 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Str8 atlas_txt_src = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Textures/atlas.txt " , DQN_STR_FMT ( exe_dir ) ) ;
Dqn_Str8 atlas_txt_dest = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Textures/atlas.txt " , DQN_STR_FMT ( build_dir ) ) ;
Dqn_Str8 atlas_png_src = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Textures/atlas.png " , DQN_STR_FMT ( exe_dir ) ) ;
Dqn_Str8 atlas_png_dest = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Data/Textures/atlas.png " , DQN_STR_FMT ( build_dir ) ) ;
if ( ! Dqn_Fs_Copy ( atlas_txt_src , atlas_txt_dest , true /*overwrite*/ ) ) {
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Failed to copy file from '%.*s' to '%.*s' " , DQN_STR_FMT ( atlas_txt_src ) , DQN_STR_FMT ( atlas_txt_dest ) ) ;
return - 1 ;
}
if ( ! Dqn_Fs_Copy ( atlas_png_src , atlas_png_dest , true /*overwrite*/ ) ) {
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Failed to copy file from '%.*s' to '%.*s' " , DQN_STR_FMT ( atlas_png_src ) , DQN_STR_FMT ( atlas_png_dest ) ) ;
return - 1 ;
2023-11-26 03:03:46 +00:00
}
2023-11-25 07:28:55 +00:00
}
2023-12-01 05:46:58 +00:00
DQN_MSVC_WARNING_POP
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Raylib ============================================================================
Dqn_Str8 raylib_dir = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/External/raylib " , DQN_STR_FMT ( tely_dir ) ) ;
Dqn_FArray32 < Dqn_Str8 > raylib_obj_files = { } ;
2023-10-15 08:04:58 +00:00
{
2023-12-01 05:46:58 +00:00
RecordScopeTime ( " %.*s Raylib " , DQN_STR_FMT ( compiler_label ) ) ;
Dqn_FArray32 < Dqn_Str8 > base_files = Dqn_FArray_InitCArray < Dqn_Str8 , 32 > ( {
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rcore.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/utils.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/raudio.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rmodels.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rtext.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rtextures.c " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rshapes.c " , DQN_STR_FMT ( raylib_dir ) ) ,
2023-10-15 08:04:58 +00:00
} ) ;
2023-12-01 05:46:58 +00:00
if ( compiler ! = Compiler_EMCC ) {
Dqn_FArray_AddCArrayAssert ( & base_files , {
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/rglfw.c " , DQN_STR_FMT ( raylib_dir ) )
} ) ;
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > compile_flags = common_compile_flags_no_warnings ;
Dqn_FArray_AddCArrayAssert ( & compile_flags , { DQN_STR8 ( " -c " ) } ) ;
if ( compiler = = Compiler_EMCC ) {
2023-11-26 03:03:46 +00:00
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " -Os " ) ,
DQN_STR8 ( " -D " ) , DQN_STR8 ( " PLATFORM_WEB " ) ,
DQN_STR8 ( " -D " ) , DQN_STR8 ( " GRAPHICS_API_OPENGL_ES2 " ) ,
2023-11-26 03:03:46 +00:00
} ) ;
2023-11-25 07:28:55 +00:00
} else {
2023-12-01 05:46:58 +00:00
if ( compiler = = Compiler_GCC ) {
DQN_ASSERT ( compile_flags . data [ 0 ] = = DQN_STR8 ( " g++ " ) ) ;
compile_flags . data [ 0 ] = DQN_STR8 ( " gcc " ) ;
}
2023-11-26 03:03:46 +00:00
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " -D " ) , DQN_STR8 ( " PLATFORM_DESKTOP " ) ,
2023-11-26 03:03:46 +00:00
} ) ;
2023-11-25 07:28:55 +00:00
}
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
build_context . compile_flags = Dqn_FArray_Slice ( & compile_flags ) ;
build_context . include_dirs = Dqn_Slice_InitCArray ( scratch . arena , {
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/external/glfw/include " , DQN_STR_FMT ( raylib_dir ) ) ,
Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/glfw/deps/mingw " , DQN_STR_FMT ( raylib_dir ) ) ,
2023-11-26 03:03:46 +00:00
} ) ;
2023-12-01 05:46:58 +00:00
for ( Dqn_Str8 base_file : base_files ) {
Dqn_Str8 file_stem = Dqn_Str8_FileNameNoExtension ( base_file ) ;
Dqn_CPPBuildCompileFile build_file = { } ;
build_file . input_file_path = base_file ;
build_file . output_file_path = Dqn_Str8_InitF ( scratch . allocator , " %.*s_%.*s.%.*s " , DQN_STR_FMT ( compiler_label ) , DQN_STR_FMT ( file_stem ) , DQN_STR_FMT ( obj_file_extension ) ) ;
Dqn_FArray_AddAssert ( & raylib_obj_files , build_file . output_file_path ) ;
build_context . compile_files = Dqn_Slice_Init ( & build_file , 1 ) ;
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
if ( ! dry_run )
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_CacheBuild ) ;
}
2023-10-15 08:04:58 +00:00
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Sokol =============================================================================
Dqn_Str8 sokol_dir = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/External/sokol " , DQN_STR_FMT ( tely_dir ) ) ;
Dqn_FArray32 < Dqn_Str8 > sokol_obj_files = { } ;
{
RecordScopeTime ( " %.*s Sokol " , DQN_STR_FMT ( compiler_label ) ) ;
2023-10-15 08:04:58 +00:00
2023-11-25 07:28:55 +00:00
Dqn_CPPBuildCompileFile build_file = { } ;
2023-12-01 05:46:58 +00:00
build_file . input_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/External/sokol/sokol_audio.c " , DQN_STR_FMT ( tely_dir ) ) ;
build_file . output_file_path = Dqn_Str8_InitF ( scratch . allocator , " %.*s_sokol.%.*s " , DQN_STR_FMT ( compiler_label ) , DQN_STR_FMT ( obj_file_extension ) ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > compile_flags = common_compile_flags_no_warnings ;
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
DQN_STR8 ( " -c " ) ,
} ) ;
if ( compiler = = Compiler_EMCC )
Dqn_FArray_AddCArrayAssert ( & compile_flags , { DQN_STR8 ( " -Os " ) } ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
build_context . compile_flags = Dqn_FArray_Slice ( & compile_flags ) ;
build_context . compile_files = Dqn_Slice_Init ( & build_file , 1 ) ;
Dqn_FArray_AddAssert ( & sokol_obj_files , build_file . output_file_path ) ;
2023-10-15 08:04:58 +00:00
2023-11-26 03:03:46 +00:00
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
if ( ! dry_run )
2023-10-15 08:04:58 +00:00
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_CacheBuild ) ;
2023-10-12 11:20:29 +00:00
}
2023-10-30 13:02:34 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Feely Pona Sprite Packer ==============================================================
if ( compiler = = Compiler_MSVC ) {
RecordScopeTime ( " Sprite Packer " ) ;
2023-10-30 13:02:34 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
2023-10-30 13:02:34 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildCompileFile build_file = { } ;
build_file . input_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_sprite_packer.cpp " , DQN_STR_FMT ( code_dir ) ) ;
build_file . output_file_path = Dqn_Str8_InitF ( scratch . allocator , " %.*s_feely_pona_sprite_packer.%.*s " , DQN_STR_FMT ( compiler_label ) , DQN_STR_FMT ( obj_file_extension ) ) ;
if ( compiler = = Compiler_MSVC ) {
build_file . prefix_flags = Dqn_Slice_InitCArray ( scratch . arena , { DQN_STR8 ( " /Tp " ) } ) ;
} else {
build_file . prefix_flags = Dqn_Slice_InitCArray ( scratch . arena , { DQN_STR8 ( " -xc++ " ) } ) ;
build_file . suffix_flags = Dqn_Slice_InitCArray ( scratch . arena , { DQN_STR8 ( " -xnone " ) } ) ;
}
2023-11-26 05:54:21 +00:00
2023-12-01 05:46:58 +00:00
build_context . compile_flags = Dqn_FArray_Slice ( & common_compile_flags ) ;
build_context . link_flags = Dqn_FArray_Slice ( & common_link_flags ) ;
build_context . build_dir = build_dir ;
2023-10-25 09:17:30 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
if ( ! dry_run )
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_CacheBuild ) ;
2023-11-25 13:52:50 +00:00
}
2023-10-25 09:17:30 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Feely Pona Link Flags =============================================================
Dqn_FArray32 < Dqn_Str8 > feely_pona_raylib_backend_link_flags = { } ;
{
Dqn_FArray_AddArrayAssert ( & feely_pona_raylib_backend_link_flags , sokol_obj_files . data , sokol_obj_files . size ) ;
Dqn_FArray_AddArrayAssert ( & feely_pona_raylib_backend_link_flags , raylib_obj_files . data , raylib_obj_files . size ) ;
if ( compiler = = Compiler_MSVC ) {
Dqn_FArray_AddCArrayAssert ( & feely_pona_raylib_backend_link_flags , {
DQN_STR8 ( " gdi32.lib " ) , // raylib
DQN_STR8 ( " opengl32.lib " ) , // raylib
DQN_STR8 ( " winmm.lib " ) , // raylib
DQN_STR8 ( " user32.lib " ) ,
DQN_STR8 ( " shell32.lib " ) ,
} ) ;
} else if ( compiler = = Compiler_GCC ) {
Dqn_FArray_AddCArrayAssert ( & feely_pona_raylib_backend_link_flags , {
DQN_STR8 ( " -lpthread " ) ,
} ) ;
2023-10-14 00:40:07 +00:00
2023-12-01 05:46:58 +00:00
# if defined(DQN_OS_UNIX)
Dqn_FArray_AddCArrayAssert ( & csight_raylib_backend_link_flags , {
DQN_STR8 ( " -ldl " ) ,
DQN_STR8 ( " -lasound " ) ,
} ) ;
# else
Dqn_FArray_AddCArrayAssert ( & feely_pona_raylib_backend_link_flags , {
DQN_STR8 ( " -lgdi32 " ) , // raylib
DQN_STR8 ( " -lopengl32 " ) , // raylib
DQN_STR8 ( " -lwinmm " ) , // raylib
DQN_STR8 ( " -lole32 " ) , // sokol audio
DQN_STR8 ( " -lbcrypt " ) , // dqn
DQN_STR8 ( " -lwininet " ) , // dqn
DQN_STR8 ( " -ldbghelp " ) , // dqn
} ) ;
# endif
2023-10-14 00:40:07 +00:00
}
2023-10-12 11:20:29 +00:00
}
2023-10-11 13:04:01 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > feely_pona_backend_include_dirs = Dqn_FArray_InitCArray < Dqn_Str8 , 32 > ( {
sokol_dir ,
raylib_dir ,
} ) ;
2023-10-14 06:21:23 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Feely Pona No DLL =================================================================
if ( ! fast_dev_build | | compiler = = Compiler_EMCC ) {
RecordScopeTime ( " %.*s Feely Pona " , DQN_STR_FMT ( compiler_label ) ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildCompileFile build_file = { } ;
build_file . input_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_unity.cpp " , DQN_STR_FMT ( code_dir ) ) ;
if ( compiler = = Compiler_EMCC )
build_file . output_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " Terry_Cherry.html " ) ;
else
build_file . output_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s_terry_cherry " , DQN_STR_FMT ( compiler_label ) ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > compile_flags = common_compile_flags ;
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
DQN_STR8 ( " -D " ) , DQN_STR8 ( " TELY_WITH_PLATFORM " ) ,
DQN_STR8 ( " -D " ) , DQN_STR8 ( " FEELY_PONA_IMPLEMENTATION " ) ,
} ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
if ( compiler = = Compiler_EMCC ) {
// NOTE: Write Feely Pona version into Emscripten HTML Shell
Dqn_Str8 html_shell_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_emscripten_shell.html " , DQN_STR_FMT ( build_dir ) ) ;
{
Dqn_Str8 html_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_emscripten_shell.html " , DQN_STR_FMT ( code_dir ) ) ;
Dqn_Str8 html_buffer = Dqn_Fs_Read ( html_path , scratch . allocator ) ;
if ( ! DQN_CHECKF ( html_buffer . size ,
" Failed to read Emscripten HTML shell file. The file at \n \n '%.*s' \n \n does not exist or is not readable " ,
DQN_STR_FMT ( html_path ) ) )
return - 1 ;
Dqn_Str8 version_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_version.txt " , DQN_STR_FMT ( code_dir ) ) ;
Dqn_Str8 version_buffer = Dqn_Fs_Read ( version_path , scratch . allocator ) ;
Dqn_Str8SplitAllocResult version_parts = Dqn_Str8_SplitAlloc ( scratch . allocator , version_buffer , DQN_STR8 ( " \n " ) ) ;
if ( ! DQN_CHECKF ( version_parts . size = = 3 ,
" Version file '%.*s' must have 3 lines containing, date, commit hash and number of commits. The buffer we tried extracting information from was \n \n %.*s \n \n " ,
DQN_STR_FMT ( version_path ) ,
DQN_STR_FMT ( version_buffer ) ) ) {
return - 1 ;
}
Dqn_Str8 date = Dqn_Str8_TrimWhitespaceAround ( version_parts . data [ 0 ] ) ;
Dqn_Str8 commit_hash = Dqn_Str8_TrimWhitespaceAround ( version_parts . data [ 1 ] ) ;
Dqn_Str8 commit_count = Dqn_Str8_TrimWhitespaceAround ( version_parts . data [ 2 ] ) ;
Dqn_Str8 version_text = Dqn_Str8_InitF ( scratch . allocator ,
" %.*s edition rev. %.*s-%.*s " ,
DQN_STR_FMT ( date ) ,
DQN_STR_FMT ( commit_count ) ,
DQN_STR_FMT ( commit_hash ) ) ;
Dqn_Str8 html_buffer_processed = Dqn_Str8_Replace ( html_buffer ,
DQN_STR8 ( " @version@ " ) ,
version_text ,
0 /*start_index*/ ,
scratch . allocator ) ;
if ( ! DQN_CHECKF ( Dqn_Fs_Write ( html_shell_path ,
html_buffer_processed ) ,
" Failed to write Emscripten HTML shell with the project version inserted into it. We were unable to write to the target location \n \n '%.*s' \n " ,
DQN_STR_FMT ( html_shell_path ) ) )
return - 1 ;
}
2023-10-24 12:41:15 +00:00
2023-11-25 07:28:55 +00:00
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
2023-10-24 12:41:15 +00:00
DQN_STR8 ( " -Wall " ) ,
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " -s " ) , DQN_STR8 ( " USE_GLFW=3 " ) ,
DQN_STR8 ( " -s " ) , DQN_STR8 ( " TOTAL_MEMORY=512MB " ) ,
DQN_STR8 ( " -s " ) , DQN_STR8 ( " TOTAL_STACK=32MB " ) ,
DQN_STR8 ( " -s " ) , DQN_STR8 ( " ALLOW_MEMORY_GROWTH " ) ,
DQN_STR8 ( " --shell-file " ) , html_shell_path ,
DQN_STR8 ( " --preload-file " ) , DQN_STR8 ( " Data " ) ,
DQN_STR8 ( " -msimd128 " ) ,
DQN_STR8 ( " -msse2 " ) ,
2023-10-15 08:04:58 +00:00
} ) ;
2023-10-17 01:29:57 +00:00
2023-12-01 05:46:58 +00:00
bool debug_build = false ;
if ( debug_build ) {
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
DQN_STR8 ( " -s " ) , DQN_STR8 ( " ASSERTIONS=2 " ) ,
DQN_STR8 ( " -s " ) , DQN_STR8 ( " SAFE_HEAP=0 " ) ,
DQN_STR8 ( " -s " ) , DQN_STR8 ( " STACK_OVERFLOW_CHECK=2 " ) ,
DQN_STR8 ( " --profiling-funcs " ) , // Expose function names in stack trace
DQN_STR8 ( " -g " ) // Debug symbols
} ) ;
} else {
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
DQN_STR8 ( " -Os " ) ,
} ) ;
}
2023-10-30 13:02:34 +00:00
}
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
build_context . compile_files = Dqn_Slice_Init ( & build_file , 1 ) ;
build_context . include_dirs = Dqn_FArray_Slice ( & feely_pona_backend_include_dirs ) ;
build_context . compile_flags = Dqn_FArray_Slice ( & compile_flags ) ;
build_context . link_flags = Dqn_FArray_Slice ( & feely_pona_raylib_backend_link_flags ) ;
2023-10-14 06:21:23 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
if ( ! dry_run )
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_AlwaysRebuild ) ;
2023-10-15 08:04:58 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Copy generated files for web target to directory
if ( compiler = = Compiler_EMCC ) {
Dqn_Str8 folder_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Terry_Cherry " , DQN_STR_FMT ( build_dir ) ) ;
if ( ! Dqn_Fs_DirExists ( folder_path ) ) {
if ( ! Dqn_Fs_MakeDir ( folder_path ) ) {
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " Failed to make directory '%.*s' " , DQN_STR_FMT ( folder_path ) ) ;
return - 1 ;
}
}
2023-11-26 03:03:46 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Str8 const generated_file_extension [ ] = {
DQN_STR8 ( " data " ) ,
DQN_STR8 ( " html " ) ,
DQN_STR8 ( " js " ) ,
DQN_STR8 ( " wasm " ) ,
} ;
for ( Dqn_Str8 file_ext : generated_file_extension ) {
Dqn_Str8 src_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Terry_Cherry.%.*s " , DQN_STR_FMT ( build_dir ) , DQN_STR_FMT ( file_ext ) ) ;
Dqn_Str8 dest_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/Terry_Cherry.%.*s " , DQN_STR_FMT ( folder_path ) , DQN_STR_FMT ( file_ext ) ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Moving '%.*s' to '%.*s' \n " , DQN_STR_FMT ( src_path ) , DQN_STR_FMT ( dest_path ) ) ;
if ( ! dry_run & & ! Dqn_Fs_Move ( src_path , dest_path , true /*overwrite*/ ) ) {
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " Failed to copy file from '%.*s' to '%.*s' " , DQN_STR_FMT ( src_path ) , DQN_STR_FMT ( dest_path ) ) ;
return - 1 ;
}
}
2023-10-14 06:21:23 +00:00
}
}
2023-12-01 05:46:58 +00:00
// NOTE: Feely Pona Dev DLL ================================================================
if ( compiler = = Compiler_MSVC ) {
RecordScopeTime ( " %.*s Feely Pona Dev DLL " , DQN_STR_FMT ( compiler_label ) ) ;
Dqn_CPPBuildCompileFile build_file = { } ;
build_file . input_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_unity.h " , DQN_STR_FMT ( code_dir ) ) ;
build_file . output_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " terry_cherry_dev_dll " , DQN_STR_FMT ( compiler_label ) ) ;
build_file . prefix_flags = Dqn_Slice_InitCArray ( scratch . arena , { DQN_STR8 ( " /Tp " ) } ) ;
2023-10-17 11:07:20 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > compile_flags = common_compile_flags ;
Dqn_FArray_AddAssert ( & compile_flags , DQN_STR8 ( " -LD " ) ) ;
Dqn_FArray_AddAssert ( & compile_flags , DQN_STR8 ( " -D FEELY_PONA_IMPLEMENTATION " ) ) ;
if ( ! fast_dev_build )
Dqn_FArray_AddAssert ( & compile_flags , DQN_STR8 ( " -analyze " ) ) ;
2023-10-17 11:07:20 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
build_context . compile_files = Dqn_Slice_Init ( & build_file , 1 ) ;
build_context . compile_flags = Dqn_FArray_Slice ( & compile_flags ) ;
2023-10-17 11:07:20 +00:00
2023-12-01 05:46:58 +00:00
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
if ( ! dry_run )
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_AlwaysRebuild ) ;
}
2023-10-17 11:07:20 +00:00
2023-12-01 05:46:58 +00:00
// NOTE: Feely Pona Dev ====================================================================
if ( compiler = = Compiler_MSVC ) {
RecordScopeTime ( " %.*s Feely Pona Dev " , DQN_STR_FMT ( compiler_label ) ) ;
2023-11-26 05:03:53 +00:00
Dqn_CPPBuildCompileFile build_file = { } ;
2023-12-01 05:46:58 +00:00
build_file . input_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/feely_pona_unity.h " , DQN_STR_FMT ( code_dir ) ) ;
build_file . output_file_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s_terry_cherry_dev " , DQN_STR_FMT ( compiler_label ) ) ;
build_file . prefix_flags = Dqn_Slice_InitCArray ( scratch . arena , { DQN_STR8 ( " /Tp " ) } ) ;
2023-11-26 05:03:53 +00:00
2023-12-01 05:46:58 +00:00
Dqn_FArray32 < Dqn_Str8 > compile_flags = common_compile_flags ;
Dqn_FArray_AddCArrayAssert ( & compile_flags , {
2023-10-29 03:59:53 +00:00
DQN_STR8 ( " -D " ) , DQN_STR8 ( " TELY_WITH_PLATFORM " ) ,
2023-12-01 05:46:58 +00:00
DQN_STR8 ( " -D " ) , DQN_STR8 ( " TELY_WITH_PLATFORM_DLL " ) ,
2023-10-15 08:04:58 +00:00
} ) ;
2023-10-17 01:29:57 +00:00
2023-12-01 05:46:58 +00:00
Dqn_CPPBuildContext build_context = common_build_context ;
build_context . compile_files = Dqn_Slice_Init ( & build_file , 1 ) ;
build_context . compile_flags = Dqn_FArray_Slice ( & compile_flags ) ;
build_context . link_flags = Dqn_FArray_Slice ( & feely_pona_raylib_backend_link_flags ) ;
build_context . include_dirs = Dqn_FArray_Slice ( & feely_pona_backend_include_dirs ) ;
2023-10-14 06:21:23 +00:00
2023-11-26 03:03:46 +00:00
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLineStr8 ( build_context , Dqn_CPPBuildMode_AlwaysRebuild , scratch . arena ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " [BUILD] Executing '%.*s' " , DQN_STR_FMT ( cmd ) ) ;
2023-12-01 05:46:58 +00:00
if ( ! dry_run ) {
Dqn_Str8 exe_path = Dqn_FsPath_ConvertF ( scratch . arena , " %.*s/%.*s_feely_pona_dev.exe " , DQN_STR_FMT ( build_dir ) , DQN_STR_FMT ( compiler_label ) ) ;
bool exe_is_locked = false ;
if ( Dqn_Fs_Exists ( exe_path ) ) {
Dqn_FsFile exe_file = Dqn_Fs_OpenFile ( exe_path , Dqn_FsFileOpen_OpenIfExist , Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write ) ;
exe_is_locked = exe_file . error_size ;
Dqn_Fs_CloseFile ( & exe_file ) ;
}
2023-10-16 06:32:32 +00:00
2023-12-01 05:46:58 +00:00
if ( ! exe_is_locked ) {
Dqn_CPPBuild_ExecOrAbort ( build_context , Dqn_CPPBuildMode_AlwaysRebuild ) ;
}
2023-10-16 06:32:32 +00:00
}
2023-10-14 06:21:23 +00:00
}
}
2023-12-01 05:46:58 +00:00
global_build_timings - > timestamps [ 1 ] = Dqn_OS_PerfCounterNow ( ) ;
Dqn_usize longest_name = 0 ;
for ( BuildTime build_time : build_timings )
longest_name = DQN_MAX ( longest_name , build_time . name . size + 1 ) ;
for ( Dqn_usize build_index = 0 ; build_index < build_timings . size ; build_index + + ) {
BuildTime build_time = build_timings . data [ build_index ] ;
Dqn_Print_StdF ( Dqn_PrintStd_Out , " %.*s: " , DQN_STR_FMT ( build_time . name ) ) ;
if ( build_time . name . size < longest_name )
Dqn_Print_StdF ( Dqn_PrintStd_Out , " %*s " , DQN_CAST ( int ) ( longest_name - build_time . name . size ) , " " ) ;
Dqn_Print_StdLnF ( Dqn_PrintStd_Out , " %.2fms " , Dqn_OS_PerfCounterMs ( build_time . timestamps [ 0 ] , build_time . timestamps [ 1 ] ) ) ;
2023-10-15 08:04:58 +00:00
}
2023-10-10 12:00:35 +00:00
return 0 ;
}