@@ -266,6 +266,23 @@ void VSGenerator::generate(const SwBuild &b)
266266 auto &input = *inputs.begin ();
267267 s.settings = input.getSettings ();
268268
269+ // get settings from targets to make use settings equality later
270+ for (auto &[pkg, tgts] : b.getTargetsToBuild ())
271+ {
272+ decltype (s.settings ) s2;
273+ for (auto &st : s.settings )
274+ {
275+ auto itgt = tgts.findSuitable (st);
276+ if (itgt == tgts.end ())
277+ throw SW_RUNTIME_ERROR (" missing target" );
278+ s2.insert ((*itgt)->getSettings ());
279+ }
280+ if (s2.size () != s.settings .size ())
281+ throw SW_RUNTIME_ERROR (" settings size do not match" );
282+ s.settings = s2;
283+ break ;
284+ }
285+
269286 Directory d (predefined_targets_dir);
270287 d.g = this ;
271288 s.directories [d.name ] = d;
@@ -546,16 +563,24 @@ void Project::emitProject(const VSGenerator &g) const
546563 " OutputFile" ,
547564 " ProgramDatabaseFile" ,
548565 " ImportLibrary" ,
566+ " SuppressStartupBanner" ,
549567 };
550568
569+ Properties link_props;
570+ link_props.exclude_flags = skip_link_props;
571+ link_props.exclude_exts = {" .obj" , " .res" };
572+
573+ Properties cl_props;
574+ cl_props.exclude_flags = skip_cl_props;
575+
551576 for (auto &s : settings)
552577 {
553578 auto &d = getData (s);
554579 ctx.beginBlockWithConfiguration (" ItemDefinitionGroup" , s);
555580 {
556581 ctx.beginBlock (" Link" );
557582 if (d.main_command )
558- printProperties (ctx, *d.main_command , skip_link_props );
583+ printProperties (ctx, *d.main_command , link_props );
559584 ctx.endBlock ();
560585 }
561586 ctx.endBlock ();
@@ -582,7 +607,7 @@ void Project::emitProject(const VSGenerator &g) const
582607 if (itcmd != cmds.end ())
583608 {
584609 auto c = *itcmd;
585- printProperties (ctx, *c, skip_cl_props );
610+ printProperties (ctx, *c, cl_props );
586611 // ctx.beginBlockWithConfiguration("AdditionalOptions", s);
587612 // ctx.endBlock();
588613 }
@@ -705,69 +730,90 @@ void Project::emitFilters(const VSGenerator &g) const
705730 write_file (g.sln_root / vs_project_dir / (name + vs_project_ext + " .filters" ), ctx.getText ());
706731}
707732
708- void Project::printProperties (ProjectEmitter &ctx, const primitives::Command &c, const StringSet &exclude ) const
733+ void Project::printProperties (ProjectEmitter &ctx, const primitives::Command &c, const Properties &props ) const
709734{
710735 auto ft = path (c.getProgram ()).stem ().u8string ();
711736 auto ift = flag_tables.find (ft);
712737 if (ift == flag_tables.end ())
738+ {
713739 LOG_WARN (logger, " No flag table: " + ft);
714- else
740+ return ;
741+ }
742+
743+ std::map<String, String> semicolon_args;
744+ bool skip_prog = false ;
745+ for (auto &o : c.arguments )
715746 {
716- std::map<String, String> semicolon_args;
717- for (auto &o : c.arguments )
747+ if (!skip_prog)
748+ {
749+ skip_prog = true ;
750+ continue ;
751+ }
752+
753+ auto arg = o->toString ();
754+
755+ if (!arg.empty () && arg[0 ] != ' -' && arg[0 ] != ' /' )
718756 {
719- auto arg = o->toString ();
720- auto &tbl = flag_tables[ft].ftable ;
757+ if (props.exclude_exts .find (path (arg).extension ().string ()) != props.exclude_exts .end ())
758+ continue ;
759+ semicolon_args[" AdditionalDependencies" ] += arg + " ;" ;
760+ continue ;
761+ }
762+
763+ auto &tbl = flag_tables[ft].ftable ;
721764
722- auto print = [&ctx, &arg, &semicolon_args, &exclude](auto &d)
765+ auto print = [&ctx, &arg, &semicolon_args, &props](auto &d)
766+ {
767+ if (props.exclude_flags .find (d.name ) != props.exclude_flags .end ())
768+ return ;
769+ if (bitmask_includes (d.flags , FlagTableFlags::UserValue))
723770 {
724- if (exclude.find (d.name ) != exclude.end ())
725- return ;
726- if (bitmask_includes (d.flags , FlagTableFlags::UserValue))
771+ if (bitmask_includes (d.flags , FlagTableFlags::SemicolonAppendable))
727772 {
728- if (bitmask_includes (d.flags , FlagTableFlags::SemicolonAppendable))
729- {
730- semicolon_args[d.name ] += arg.substr (1 + d.argument .size ()) + " ;" ;
731- return ;
732- }
733- else
734- {
735- ctx.beginBlock (d.name );
736- ctx.addText (arg.substr (1 + d.argument .size ()));
737- }
773+ semicolon_args[d.name ] += arg.substr (1 + d.argument .size ()) + " ;" ;
774+ return ;
738775 }
739776 else
740777 {
741778 ctx.beginBlock (d.name );
742- ctx.addText (d. value );
779+ ctx.addText (arg. substr ( 1 + d. argument . size ()) );
743780 }
744- ctx.endBlock (true );
745- };
746-
747- // fast lookup first
748- auto i = tbl.find (arg.substr (1 ));
749- if (i != tbl.end ())
750- {
751- print (i->second );
752- continue ;
753781 }
754-
755- // TODO: we must find the longest match
756- for (auto &[_, d] : tbl)
782+ else
757783 {
758- if (d.argument .empty ())
759- continue ;
760- if (arg.find (d.argument , 1 ) != 1 )
761- continue ;
762- print (d);
763- break ;
784+ ctx.beginBlock (d.name );
785+ ctx.addText (d.value );
764786 }
787+ ctx.endBlock (true );
788+ };
789+
790+ // fast lookup first
791+ auto i = tbl.find (arg.substr (1 ));
792+ if (i != tbl.end ())
793+ {
794+ print (i->second );
795+ continue ;
765796 }
766- for (auto &[k, v] : semicolon_args)
797+
798+ // TODO: we must find the longest match
799+ // bool found = false;
800+ for (auto &[_, d] : tbl)
767801 {
768- ctx.beginBlock (k);
769- ctx.addText (v);
770- ctx.endBlock (true );
802+ if (d.argument .empty ())
803+ continue ;
804+ if (arg.find (d.argument , 1 ) != 1 )
805+ continue ;
806+ print (d);
807+ // found = true;
808+ break ;
771809 }
810+ // if (!found)
811+ // LOG_WARN(logger, "arg not found: " + arg);
812+ }
813+ for (auto &[k, v] : semicolon_args)
814+ {
815+ ctx.beginBlock (k);
816+ ctx.addText (v);
817+ ctx.endBlock (true );
772818 }
773819}
0 commit comments