Demo building - Build configurations
This commit is contained in:
parent
10361fec4f
commit
d77943f953
5 changed files with 319 additions and 7 deletions
1
Makefile
1
Makefile
|
@ -25,6 +25,7 @@ IMGUI = imgui.cpp imgui_draw.cpp
|
||||||
|
|
||||||
COMMON = \
|
COMMON = \
|
||||||
common.cc \
|
common.cc \
|
||||||
|
c-buildcfg.cc \
|
||||||
c-camera.cc \
|
c-camera.cc \
|
||||||
c-filewatcher.cc \
|
c-filewatcher.cc \
|
||||||
c-project.cc \
|
c-project.cc \
|
||||||
|
|
191
c-buildcfg.cc
Normal file
191
c-buildcfg.cc
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
#include "externals.hh"
|
||||||
|
#include "c-buildcfg.hh"
|
||||||
|
|
||||||
|
#include <ebcl/Files.hh>
|
||||||
|
#include <ebcl/SRDDefinitions.hh>
|
||||||
|
#include <ebcl/SRDParserConfig.hh>
|
||||||
|
#include <ebcl/SRDParser.hh>
|
||||||
|
#include <ebcl/SRDText.hh>
|
||||||
|
|
||||||
|
using namespace ebcl;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/*= SRD PARSER FOR BUILD CONFIGURATIONS ======================================*/
|
||||||
|
|
||||||
|
using SP_Table_ = T_SharedPtr< T_BuildConfigurations >;
|
||||||
|
|
||||||
|
bool BCLStartConfig_( T_SRDParserData const& data )
|
||||||
|
{
|
||||||
|
*( data.targetData ) = T_BuildConfiguration{ };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BCLEndConfig_( T_SRDParserData const& data )
|
||||||
|
{
|
||||||
|
auto const& in{ *data.input };
|
||||||
|
auto& table{ *( data.targetData->value< SP_Table_ >( ) ) };
|
||||||
|
auto& bCfg{ data.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
if ( !table.add( in[ 1 ].stringValue( ) , std::move( bCfg ) ) ) {
|
||||||
|
data.errors.add( "duplicate configuration" , in[ 1 ] );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool BCLResolutions_( T_SRDParserData const& data )
|
||||||
|
{
|
||||||
|
auto const& in{ *data.input };
|
||||||
|
auto& bCfg{ data.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
const uint32_t nin{ in.size( ) };
|
||||||
|
if ( nin == 2 && in[ 1 ].type( ) == E_SRDTokenType::WORD ) {
|
||||||
|
bCfg.resolutionChooser = true;
|
||||||
|
bCfg.resolutions.clear( );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto i = 1u ; i < nin ; i ++ ) {
|
||||||
|
auto const& l{ in[ i ].list( ) };
|
||||||
|
const auto w{ l[ 0 ].longValue( ) };
|
||||||
|
const auto h{ l[ 1 ].longValue( ) };
|
||||||
|
bool fail{ false };
|
||||||
|
|
||||||
|
if ( w <= 0 || w >= 16384 ) {
|
||||||
|
fail = true;
|
||||||
|
data.errors.add( "invalid width" , l[ 0 ] );
|
||||||
|
}
|
||||||
|
if ( h <= 0 || h >= 16384 ) {
|
||||||
|
fail = true;
|
||||||
|
data.errors.add( "invalid height" , l[ 1 ] );
|
||||||
|
}
|
||||||
|
if ( fail ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto res{ std::make_pair< uint32_t , uint32_t >( w , h ) };
|
||||||
|
if ( bCfg.resolutions.contains( res ) ) {
|
||||||
|
data.errors.add( InPlace( ) ,
|
||||||
|
"duplicate resolution" ,
|
||||||
|
in[ i ].location( ) ,
|
||||||
|
E_SRDErrorType::WARNING );
|
||||||
|
} else {
|
||||||
|
bCfg.resolutions.add( res );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
T_SRDParserConfig BCLInitDefinitions_( ) noexcept
|
||||||
|
{
|
||||||
|
using namespace ebcl::SRD;
|
||||||
|
T_SRDParserDefs defs{ "default" };
|
||||||
|
defs.enumeration( "on-off" ) << "off" << "on";
|
||||||
|
defs << OnStart( []( T_SRDParserData const& data ) -> bool {
|
||||||
|
*( data.currentData ) = NewShared< T_BuildConfigurations >( );
|
||||||
|
return true;
|
||||||
|
} );
|
||||||
|
|
||||||
|
defs.context( "default" )
|
||||||
|
<< ( Rule( ) << "cfg" << Text( ) << EnterContext( "config" )
|
||||||
|
<< OnEnter( BCLStartConfig_ )
|
||||||
|
<< OnExit( BCLEndConfig_ ) )
|
||||||
|
;
|
||||||
|
|
||||||
|
defs.context( "config" )
|
||||||
|
<< ( Rule( ) << "resolutions"
|
||||||
|
<< ( Alt( ) << "chooser"
|
||||||
|
<< ( AtLeast( 1 ) << ( List( ) << Int32( ) << Int32( ) ) ) )
|
||||||
|
<< BCLResolutions_ )
|
||||||
|
<< ( Rule( ) << "optimizer" << "off" )
|
||||||
|
<< ( Rule( ) << "optimizer" << "on" << EnterContext( "optim" ) )
|
||||||
|
;
|
||||||
|
|
||||||
|
defs.context( "optim" )
|
||||||
|
<< ( Rule( ) << "constant-folding" << "off"
|
||||||
|
<< []( T_SRDParserData const& d ) -> bool {
|
||||||
|
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
bCfg.constantFolding = false;
|
||||||
|
return true;
|
||||||
|
} )
|
||||||
|
<< ( Rule( ) << "constant-folding" << "on" << EnterContext( "opt-cf" )
|
||||||
|
<< []( T_SRDParserData const& d ) -> bool {
|
||||||
|
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
bCfg.constantFolding = true;
|
||||||
|
return true;
|
||||||
|
} )
|
||||||
|
<< ( Rule( ) << "dead-code-elimination" << Enum( "on-off" )
|
||||||
|
<< []( T_SRDParserData const& d ) -> bool {
|
||||||
|
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
bCfg.deadCodeElimination = true;
|
||||||
|
return true;
|
||||||
|
} )
|
||||||
|
;
|
||||||
|
|
||||||
|
defs.context( "opt-cf" )
|
||||||
|
<< ( Rule( ) << "fixed-resolution" << Enum( "on-off" )
|
||||||
|
<< []( T_SRDParserData const& d ) -> bool {
|
||||||
|
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
bCfg.cfFixedSize = true;
|
||||||
|
return true;
|
||||||
|
} )
|
||||||
|
<< ( Rule( ) << "inputs" << Enum( "on-off" )
|
||||||
|
<< []( T_SRDParserData const& d ) -> bool {
|
||||||
|
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
|
||||||
|
bCfg.cfInputs = true;
|
||||||
|
return true;
|
||||||
|
} )
|
||||||
|
;
|
||||||
|
|
||||||
|
return T_SRDParserConfig{ defs };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= BUILD CONFIGURATIONS LOADER ==============================================*/
|
||||||
|
|
||||||
|
struct T_BCLImpl_
|
||||||
|
{
|
||||||
|
T_SRDParserConfig pConfig;
|
||||||
|
|
||||||
|
T_BCLImpl_( ) noexcept;
|
||||||
|
|
||||||
|
T_BuildConfigurations load( T_String const& path );
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
T_BCLImpl_::T_BCLImpl_( ) noexcept
|
||||||
|
: pConfig{ BCLInitDefinitions_( ) }
|
||||||
|
{ }
|
||||||
|
|
||||||
|
T_BuildConfigurations T_BCLImpl_::load(
|
||||||
|
T_String const& path )
|
||||||
|
{
|
||||||
|
// TODO: keep errors so we get warnings/notes too
|
||||||
|
T_SRDParser parser{ pConfig };
|
||||||
|
T_SRDTextReader srdReader{ parser };
|
||||||
|
|
||||||
|
T_File input{ path , E_FileMode::READ_ONLY };
|
||||||
|
T_FileInputStream fis{ input };
|
||||||
|
srdReader.read( path , fis );
|
||||||
|
|
||||||
|
return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace <anon>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
T_BuildConfigurationLoader::T_BuildConfigurationLoader( ) noexcept
|
||||||
|
: A_PrivateImplementation( new T_BCLImpl_( ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
T_BuildConfigurations T_BuildConfigurationLoader::load(
|
||||||
|
T_String const& path )
|
||||||
|
{
|
||||||
|
return p< T_BCLImpl_ >( ).load( path );
|
||||||
|
}
|
59
c-buildcfg.hh
Normal file
59
c-buildcfg.hh
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef REAL_BUILD
|
||||||
|
# include "externals.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*= BUILD CONFIGURATIONS =====================================================*/
|
||||||
|
|
||||||
|
// Build configuration
|
||||||
|
struct T_BuildConfiguration
|
||||||
|
{
|
||||||
|
// Targets -------------------------------------------------------------
|
||||||
|
|
||||||
|
// Resolutions
|
||||||
|
bool resolutionChooser{ true };
|
||||||
|
T_Array< std::pair< uint32_t , uint32_t > > resolutions;
|
||||||
|
|
||||||
|
// Enable optimizer?
|
||||||
|
bool optimize{ false };
|
||||||
|
|
||||||
|
// Constant folding ----------------------------------------------------
|
||||||
|
|
||||||
|
// Main toggle
|
||||||
|
bool constantFolding{ false };
|
||||||
|
// Optimize $width and $height away if the size is fixed
|
||||||
|
bool cfFixedSize{ false };
|
||||||
|
// Get rid of (get-input) for constant or undefined curves
|
||||||
|
bool cfInputs{ false };
|
||||||
|
|
||||||
|
// Dead code elimination -----------------------------------------------
|
||||||
|
|
||||||
|
bool deadCodeElimination{ false };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Table of avaiable build configurations
|
||||||
|
using T_BuildConfigurations = T_KeyValueTable< T_String , T_BuildConfiguration >;
|
||||||
|
|
||||||
|
// Build configurations loader
|
||||||
|
struct T_BuildConfigurationLoader : public ebcl::A_PrivateImplementation
|
||||||
|
{
|
||||||
|
T_BuildConfigurationLoader( ) noexcept;
|
||||||
|
|
||||||
|
// Load build configurations from the specified path; may throw
|
||||||
|
// X_StreamError or X_SRDErrors
|
||||||
|
T_BuildConfigurations load( T_String const& path );
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Logger
|
||||||
|
using F_OPGenLog = std::function< T_StringBuilder( ) >;
|
||||||
|
using F_OPLogger = std::function< void( F_OPGenLog , uint32_t ) >;
|
||||||
|
|
||||||
|
// Runtime configuration (logger, etc.)
|
||||||
|
struct T_BuildRuntimeConfiguration
|
||||||
|
{
|
||||||
|
F_OPLogger logger{ [](auto,auto){} };
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "c-buildcfg.hh"
|
||||||
#include "c-filewatcher.hh"
|
#include "c-filewatcher.hh"
|
||||||
#include "c-opast.hh"
|
#include "c-opast.hh"
|
||||||
#include "c-project.hh"
|
#include "c-project.hh"
|
||||||
|
@ -7,9 +8,6 @@
|
||||||
|
|
||||||
/*= PARSER ===================================================================*/
|
/*= PARSER ===================================================================*/
|
||||||
|
|
||||||
using F_OPGenLog = std::function< T_StringBuilder( ) >;
|
|
||||||
using F_OPLogger = std::function< void( F_OPGenLog , uint32_t ) >;
|
|
||||||
|
|
||||||
// Parser output. Consists in a root node as well as other details (table of
|
// Parser output. Consists in a root node as well as other details (table of
|
||||||
// constants, data types, etc...)
|
// constants, data types, etc...)
|
||||||
struct T_OpsParserOutput
|
struct T_OpsParserOutput
|
||||||
|
|
71
m-builder.cc
71
m-builder.cc
|
@ -44,7 +44,18 @@ void WriteSRDError(
|
||||||
T_StringBuilder& sb ,
|
T_StringBuilder& sb ,
|
||||||
T_SRDError const& error )
|
T_SRDError const& error )
|
||||||
{
|
{
|
||||||
sb << error.location( ) << " - " << error.error( ) << "\n";
|
switch ( error.type( ) ) {
|
||||||
|
case E_SRDErrorType::ERROR:
|
||||||
|
sb << "[ERROR";
|
||||||
|
break;
|
||||||
|
case E_SRDErrorType::WARNING:
|
||||||
|
sb << " [WARN";
|
||||||
|
break;
|
||||||
|
case E_SRDErrorType::NOTE:
|
||||||
|
sb << " [NOTE";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sb << '(' << error.location( ) << ")] " << error.error( ) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +68,7 @@ int main( int argc , char** argv )
|
||||||
// Parse command line
|
// Parse command line
|
||||||
T_Optional< uint32_t > oLogLevel;
|
T_Optional< uint32_t > oLogLevel;
|
||||||
T_String oSrcPath;
|
T_String oSrcPath;
|
||||||
|
T_String oBuildCfg;
|
||||||
int c;
|
int c;
|
||||||
while ( ( c = getopt_long( argc , argv , "L:s:c:" , CmdLineOpts_ , nullptr ) ) != -1 ) {
|
while ( ( c = getopt_long( argc , argv , "L:s:c:" , CmdLineOpts_ , nullptr ) ) != -1 ) {
|
||||||
switch ( c ) {
|
switch ( c ) {
|
||||||
|
@ -68,13 +80,17 @@ int main( int argc , char** argv )
|
||||||
case 's':
|
case 's':
|
||||||
if ( oSrcPath ) {
|
if ( oSrcPath ) {
|
||||||
fprintf( stderr , "Duplicate source path\n" );
|
fprintf( stderr , "Duplicate source path\n" );
|
||||||
exit( EXIT_FAILURE );
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
oSrcPath = optarg;
|
oSrcPath = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
fprintf( stderr , "-c/--config option ignored for now\n" );
|
if ( oSrcPath ) {
|
||||||
|
fprintf( stderr , "Duplicate build configuration\n" );
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
oBuildCfg = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,9 +104,56 @@ int main( int argc , char** argv )
|
||||||
}
|
}
|
||||||
auto sb{ func( ) };
|
auto sb{ func( ) };
|
||||||
sb << '\0';
|
sb << '\0';
|
||||||
printf( "LOG{%d} %s\n" , level , sb.data( ) );
|
printf( "(%d) %s\n" , level , sb.data( ) );
|
||||||
} };
|
} };
|
||||||
|
|
||||||
|
// Build configurations
|
||||||
|
const T_String bcfgFile( [&]() {
|
||||||
|
T_StringBuilder sb;
|
||||||
|
if ( oSrcPath ) {
|
||||||
|
sb << oSrcPath;
|
||||||
|
if ( !oSrcPath.endsWith( "/" ) ) {
|
||||||
|
sb << '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb << "build.srd";
|
||||||
|
return T_String{ std::move( sb ) };
|
||||||
|
}( ) );
|
||||||
|
const T_BuildConfiguration cfg{ [&]() {
|
||||||
|
try {
|
||||||
|
T_BuildConfigurationLoader bcfgLoader;
|
||||||
|
T_BuildConfigurations cfs{ bcfgLoader.load( bcfgFile ) };
|
||||||
|
if ( oBuildCfg && !cfs.contains( oBuildCfg ) ) {
|
||||||
|
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
|
||||||
|
fprintf( stderr , "Build configuration not found\n" );
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
if ( oBuildCfg ) {
|
||||||
|
return *cfs.get( oBuildCfg );
|
||||||
|
}
|
||||||
|
if ( cfs.size( ) ) {
|
||||||
|
return cfs[ 0 ];
|
||||||
|
}
|
||||||
|
return T_BuildConfiguration{ };
|
||||||
|
|
||||||
|
} catch ( X_StreamError const& e ) {
|
||||||
|
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
|
||||||
|
PrintStreamError( "Could not open" , bcfgFile , e );
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
|
||||||
|
} catch ( X_SRDErrors const& e ) {
|
||||||
|
T_StringBuilder sb;
|
||||||
|
sb << "===== BUILD CONFIGURATIONS\n";
|
||||||
|
const auto nErrors( e.errors.size( ) );
|
||||||
|
for ( auto i = 0u ; i < nErrors ; i ++ ) {
|
||||||
|
WriteSRDError( sb , e.errors[ i ] );
|
||||||
|
}
|
||||||
|
sb << '\0';
|
||||||
|
fprintf( stderr , "%s" , sb.data( ) );
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
} () };
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
const T_String inputName( [&]() {
|
const T_String inputName( [&]() {
|
||||||
T_StringBuilder sb;
|
T_StringBuilder sb;
|
||||||
|
|
Loading…
Reference in a new issue