@@ -221,11 +221,14 @@ void NativeExecutedTarget::setOutputFile()
221221 if (Scope == TargetScope::Build)
222222 {
223223 if (getSelectedTool () == Librarian.get ())
224- getSelectedTool ()->setOutputFile (getOutputFileName2 ());
224+ getSelectedTool ()->setOutputFile (getOutputFileName2 (" lib " ));
225225 else
226226 {
227- getSelectedTool ()->setOutputFile (getOutputFileName (getOutputBaseDir ()));
228- getSelectedTool ()->setImportLibrary (getOutputFileName2 ());
227+ if (getType () == TargetType::NativeExecutable)
228+ getSelectedTool ()->setOutputFile (getOutputFileName2 (" bin" ));
229+ else
230+ getSelectedTool ()->setOutputFile (getOutputFileName (getOutputBaseDir ()));
231+ getSelectedTool ()->setImportLibrary (getOutputFileName2 (" lib" ));
229232 }
230233 }
231234 else
@@ -263,7 +266,7 @@ path NativeExecutedTarget::getOutputFileName(const path &root) const
263266 return p;
264267}
265268
266- path NativeExecutedTarget::getOutputFileName2 () const
269+ path NativeExecutedTarget::getOutputFileName2 (const path &subdir ) const
267270{
268271 if (SW_IS_LOCAL_BINARY_DIR)
269272 {
@@ -274,7 +277,7 @@ path NativeExecutedTarget::getOutputFileName2() const
274277 if (IsConfig)
275278 return getOutputFileName (" " );
276279 else
277- return BinaryDir.parent_path () / " lib " / getOutputFileName ();
280+ return BinaryDir.parent_path () / subdir / getOutputFileName ();
278281 }
279282}
280283
@@ -907,40 +910,8 @@ Commands NativeExecutedTarget::getCommands1() const
907910 // link deps
908911 if (getSelectedTool () != Librarian.get ())
909912 {
910- for (auto &l : gatherDependenciesTargets ())
911- {
912- if (auto c2 = ((NativeExecutedTarget*)l)->getCommand ())
913- c->dependencies .insert (c2);
914- }
915-
916- // check circular, resolve if possible
917- for (auto &d : CircularDependencies)
918- {
919- auto dt = ((NativeExecutedTarget*)d->target );
920- auto non_circ_cmd = dt->getSelectedTool ()->getCommand (*this );
921-
922- // one command must be executed after the second to free implib files from any compiler locks
923- // we choose it based on ptr address
924- // if (c < non_circ_cmd)
925- c->dependencies .erase (non_circ_cmd);
926-
927- if (dt->CircularLinker )
928- {
929- auto cd = dt->CircularLinker ->getCommand (*this );
930- c->dependencies .insert (cd);
931- }
932- // cmds.insert(cd);
933- }
934-
935- if (CircularLinker)
936- {
937- // execute this command after unresolved (circular) cmd
938- c->dependencies .insert (CircularLinker->getCommand (*this ));
939-
940- // we reset generator of implib from usual build command (c = getCommand()) to circular linker generator to overcome
941- // automatic circular dependency generation in command.cpp
942- // File(getImportLibrary()).getFileRecord().generator = CircularLinker->getCommand();
943- }
913+ if (circular_dependency)
914+ cmds.insert (Librarian->getCommand (*this ));
944915 }
945916
946917 cmds.insert (c);
@@ -1997,6 +1968,8 @@ bool NativeExecutedTarget::prepare()
19971968 case 6 :
19981969 // link libraries
19991970 {
1971+ auto L = Linker->as <VisualStudioLinker>();
1972+
20001973 // add link libraries from deps
20011974 if (!HeaderOnly.value () && getSelectedTool () != Librarian.get ())
20021975 {
@@ -2011,30 +1984,19 @@ bool NativeExecutedTarget::prepare()
20111984
20121985 auto dt = ((NativeExecutedTarget*)d->target );
20131986
2014- for (auto &d2 : dt->Dependencies )
1987+ // circular deps detection
1988+ if (L)
20151989 {
2016- if (d2->target != this )
2017- continue ;
2018- if (d2->IncludeDirectoriesOnly )
2019- continue ;
2020-
2021- CircularDependencies.insert (d.get ());
2022- }
2023-
2024- if (!CircularDependencies.empty ())
2025- {
2026- CircularLinker = std::static_pointer_cast<NativeLinker>(getSelectedTool ()->clone ());
2027-
2028- // set to temp paths
2029- auto o = IsConfig;
2030- IsConfig = true ;
2031- CircularLinker->setOutputFile (getOutputFileName (getOutputBaseDir ()));
2032- CircularLinker->setImportLibrary (getOutputFileName2 ());
2033- IsConfig = o;
2034-
2035- if (auto c = CircularLinker->as <VisualStudioLinker>())
1990+ for (auto &d2 : dt->Dependencies )
20361991 {
2037- c->Force = vs::ForceType::Unresolved;
1992+ if (d2->target != this )
1993+ continue ;
1994+ if (d2->IncludeDirectoriesOnly )
1995+ continue ;
1996+
1997+ circular_dependency = true ;
1998+ L->ImportLibrary .clear ();
1999+ break ;
20382000 }
20392001 }
20402002
@@ -2077,30 +2039,26 @@ bool NativeExecutedTarget::prepare()
20772039 auto obj = gatherObjectFilesWithoutLibraries ();
20782040 auto O1 = gatherLinkLibraries ();
20792041
2080- if (CircularLinker )
2042+ if (!HeaderOnly. value () && getSelectedTool () != Librarian. get () )
20812043 {
2082- // O1 -= Li
2083- for (auto &d : CircularDependencies)
2084- O1.erase (std::remove (O1.begin (), O1.end (), ((NativeTarget*)d->target )->getImportLibrary ()), O1.end ());
2085-
2086- // CL1 = O1
2087- CircularLinker->setInputLibraryDependencies (O1);
2044+ for (auto &f : ::sw::gatherSourceFiles<RcToolSourceFile>(*this ))
2045+ obj.insert (f->output .file );
2046+ }
20882047
2089- // O1 += CLi
2090- for (auto &d : CircularDependencies)
2048+ if (circular_dependency)
2049+ {
2050+ Librarian->setObjectFiles (obj);
2051+ Librarian->setOutputFile (getOutputFileName2 (" lib" ));
2052+ if (auto L = Librarian->as <VisualStudioLibrarian>())
20912053 {
2092- if (d-> target && ((NativeExecutedTarget*)d-> target )-> CircularLinker )
2093- O1. push_back (((NativeExecutedTarget*)d-> target )-> CircularLinker -> getImportLibrary () );
2054+ L-> CreateImportLibrary = true ;
2055+ L-> DllName = Linker-> getOutputFile (). filename (). u8string ( );
20942056 }
20952057
2096- // prepare command here to prevent races
2097- CircularLinker->getCommand (*this );
2098- }
2099-
2100- if (!HeaderOnly.value () && getSelectedTool () != Librarian.get ())
2101- {
2102- for (auto &f : ::sw::gatherSourceFiles<RcToolSourceFile>(*this ))
2103- obj.insert (f->output .file );
2058+ auto exp = Librarian->getImportLibrary ();
2059+ exp = exp.parent_path () / (exp.stem ().u8string () + " .exp" );
2060+ Librarian->createCommand ()->addOutput (exp);
2061+ obj.insert (exp);
21042062 }
21052063
21062064 getSelectedTool ()->setObjectFiles (obj);
0 commit comments