Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Brian_Murphy
New Contributor II
426 Views

project rebuilds every time debugger is started

This is more of an annoyance than a problem.

I am using visual studio 2019.  What sorts of things would cause a rebuild every time I press F5 to start a debug session?

This is a mixed language project, with fortran and c++ DLL's calling each other.  When I designate a c++ project as the startup project, the rebuilding doesn't happen.  But when a fortran project is the startup project, the fortran projects recompile the files that contain calls to C++.

0 Kudos
16 Replies
jimdempseyatthecove
Black Belt
408 Views

Have you checked your project dependencies for circular dependency?

You stated: with fortran and c++ DLL's calling each other

So either cannot be dependent upon the other.

Jim Dempsey

Brian_Murphy
New Contributor II
401 Views

In the Project Dependencies dialog, there are no circular dependencies.

I will focus on one fortran DLL and one C++ DLL.  Each calls routines in the other.  The LIB file for each has been added to the file list of the other.  The Project Dependencies dialog is not used here.  A remark from Steve Lionel in a recent thread told me to not use the P.D. dialog in this situation.  The application runs like it should.  It launches and debugs very nicely, stepping back and forth between VBA, fortran and c++.

The two DLL's are called from Excel.  So pressing F5 to start a debug session launches Excel, and VBA calls the DLL's.  It is my understanding that because Excel is the parent application, it doesn't matter whether the fortran or c++ project is designated in visual studio as the "startup project".

If the designated "startup project" is the fortran, pressing F5 triggers a rebuild of the fortran project.  If the c++ is the startup project, no rebuilding happens.

Get this.  With fortran as the startup, F5 -> fortran rebuilds -> stop debugging -> F5 again -> fortran rebuilds again -> stop debugging -> and so on.  Only the fortran is rebuilding, not the c++.  So why would visual studio think it needs rebuilding?

I can evidently avoid the rebuilding by simply making c++ the startup project.  The reason I'm asking is I worry I have a bug in my setup that will eventually bite me.

Steve_Lionel
Black Belt Retired Employee
395 Views

You do have a circular dependency - I suggest that you break it.

FortranFan
Honored Contributor II
333 Views

 

@Steve_Lionel wrote:

You do have a circular dependency - I suggest that you break it.

 

 

 

@Brian_Murphy ,

It will be very useful if you can explore the circular dependency issue(s) in your current configuration and either get to the root cause by yourself or by by sharing the files on this forum i.e., if you are Ok to do so.  You can of course work around the issue(s) by reconfiguring the projects and dependencies but that may not reveal what caused the problem in the first place.

If the original problem was definitely something in the configuration, knowing that can help you avoid it the next time.

Now, do you have support included in your license with Intel Fortran product?  If not, please feel free to ignore the rest of this note.

Because there's a possibility always of a bug in Intel Fortran integration with Visual Studio and in that event, it will help Intel team and all the customers to get it resolved.

Please note I mention the latter because a team I worked with was using Intel Fortran compiler 18.0 Update 5 and they had a Fortran DLL where the code made use of SUBMODULEs (you will know a facility introduced starting Fortran 2008).  With this DLL, the team faced the exact same issue you report - the project would rebuild every time the target (as per the Visual Studio term) was executed e.g., using F5, or Ctrl-F5 command.  The team expended an ENORMOUS amount of time to resolve what they presumed was a circular dependency in their configuration.  Ultimately it turned out a bug in the Intel Fortran integration with Visual Studio with SUBMODULEs.  I worked with that team to put together a reproducer - we now can see definitively that reproducer rebuilds every time using IFORT v18.0u5 when executed using Microsoft Excel as the target in VS, but it does not do so with the current version v19.1u2.  We are convinced there were NO circular dependences in this team's code and configuration, the issue was without doubt Intel Fortran integration with Visual Studio.  An indirect casualty in all this - a last straw perhaps - that team does NOT use Fortran any more, they migrated to other languages.

Now you may not be using SUBMODULEs and may not face the same issues this team did, but perhaps there are other aspects with your Fortran and/or C++ code that trips the product.  However small might be the probability of this, you may want to keep that in mind as well.

My message: as a support paying customer of Intel Fortran, you're allocating a fair chunk of your resources for Intel's product - it's alright and rather considerate of you to place the onus on yourself and try to resolve the problems on your side, however at some stage you may want to consider turning the situation around and be a customer who expects better of the product you buy.

Brian_Murphy
New Contributor II
314 Views

FortranFan - Thank you very much for the reply.  I indeed have a current Intel Fortran support agreement.  I tried to get their help with a recent problem configuring intel fortran with visual studio, but they said to contact Microsoft. 

My setup of intel fortran with visual studio 2019 has definite problems.  I have completely uninstalled and reinstalled both.  Unfortunately, that made things worse, not better.  This is a brand new windows 10 computer which has never had visual studio or intel fortran installed before.  I am pretty much stuck with using visual studio for this project, so I'll just have to live with its problems.

There are no SUBMODULE's in this code, and I don't know what they are.  So I don't think that plays a role.

The repeated re-building behavior I have now sure looks like a visual studio thing.  Based on my recent experience, Intel Paid Support will be unable or unwilling to help.

The cross-dependency of the C.DLL and F.DLL projects is about as simple as it could be.  F.DLL contains a routine which it calls both internally and exports it so C.DLL can call it.  That fortran routine calls a helper routine which is located in C.DLL (the helper routine performs a rather small subtask which would be very difficult to do in fotran).  C.DLL exports it so F.DLL can call it.  That is the full extent of interaction between F.DLL and C.DLL.

When I have some spare time, I will take a shot at merging the fortran and c++ into a single DLL.  However, that will need to be easy for me to do it.

jimdempseyatthecove
Black Belt
385 Views

Even though each DLL reference each other, you should not make either dependent upon the other. It is not necessary to do so. The "linkage" to/amongst the DLLs occurs at runtime and at which point you have no control over dependency. Note, if your PATH is mucked up, you won't even load the DLL upon which you made your dependency.

Jim Dempsey

IanH
Black Belt
369 Views

Why is the C++ code in a separate DLL to the Fortran code? 

If they are calling each other via imports, then they are closely coupled and can never be used in isolation.  Chances are that if you have to service one, you'll have to service the other and/or the cost of servicing both code bases these days is incrementally tiny compared to the cost of servicing one side of the code base.  So why split things?

~~

You don't want to go down this path, but...

The Microsoft linker has capability (link to Microsoft documentation) that permits construction of executable modules (EXEs and DLLs) with cyclical dependencies.  Based on your description I don't think you are using this capability.  You would typically need three projects in Visual Studio - project one to build through to the import and export libraries only for DLL A, project two to build DLL B (consuming the import library from project one), project three to complete the build of DLL A (consuming the export library from project one and the import library from project two).

There are other complications with DLLs with cyclical dependency - such as potential variation in the ordering of DLL initialization.  You need to be aware of what is going on at quite a low level (e.g. how your compilers' runtimes initialise themselves) to avoid issues.

In the absence of a good reason for why the C++ and Fortran are in separate DLLs, having one DLL is very much the way to go.

 

 

Brian_Murphy
New Contributor II
352 Views

Thanks for the replies.  I now understand the circular dependency, and I think I see how using three visual studio projects would do the build steps in a more logical way.  e.g. with a build order of  F.LIB -> C.DLL+C.LIB  -> F.DLL

I like the idea of combining F.DLL and C.DLL into a single Allin1.DLL.  Until recently, the two codes complemented each other, but did not call each other, and were built independently into separate DLL's.

Let me see if I got this right.  My F.DLL and C.DLL projects are changed to LIB projects, and third project makes Allin1.DLL from F.LIB and C.LIB?  The Allin1.DLL project performs a linking step, but contains no source code to compile?  What visual studio project type should be used for Allin1.DLL ?

I am studying the C_Calls_Fortran sample solution.  I see it has FLIB and FDLL projects which each utilize the same FSUB.f90 source file.

Steve_Lionel
Black Belt Retired Employee
346 Views

In the C_Calls_Fortran sample, FLIB and FDLL are distinct projects - one does not depend on the other. They're there to demonstrate how to have C call Fortran code in either a static library or a DLL. The source uses conditional code to choose whether or not to DLLEXPORT the procedure name. Similarly, the USELIB and USEDLL C projects do not depend on each other.

Brian_Murphy
New Contributor II
322 Views

I am looking at C_Calls_Fortran because it builds C.exe with the fortran embedded internally, which would be a new trick for me.

Steve_Lionel
Black Belt Retired Employee
311 Views


@Brian_Murphy wrote:

I am looking at C_Calls_Fortran because it builds C.exe with the fortran embedded internally, which would be a new trick for me.


Not really - it is a mixed-language solution with the C and Fortran code in separate projects. USEDLL depends on FDLL, USELIB depends on FLIB.

jimdempseyatthecove
Black Belt
337 Views

>>The Allin1.DLL project performs a linking step, but contains no source code to compile? 

This is where you would place the DLLMAIN load/unload routine.

Jim Dempsey

Brian_Murphy
New Contributor II
320 Views

Jim - there is no DLLMAIN routine anywhere that I can find.  What is it?

Steve_Lionel
Black Belt Retired Employee
309 Views

The only time you would use a DllMain function is if you wanted a routine to be called when the DLL is loaded or unloaded. Most DLLs don't care about that. 

Here is the Microsoft documentation on DllMain. In Fortran this would be a STDCALL (on IA-32) routine with an external name of "DllMain".

IanH
Black Belt
295 Views


@Brian_Murphy wrote:
...
I like the idea of combining F.DLL and C.DLL into a single Allin1.DLL.  Until recently, the two codes complemented each other, but did not call each other, and were built independently into separate DLL's.

Let me see if I got this right.  My F.DLL and C.DLL projects are changed to LIB projects, and third project makes Allin1.DLL from F.LIB and C.LIB?  The Allin1.DLL project performs a linking step, but contains no source code to compile?  What visual studio project type should be used for Allin1.DLL ?

If you are doing a single DLL, you can use two projects.  The first project (in whatever language) builds a static library, the second project (in the other language) consumes that static library and then builds the DLL. An example setup attached in the zip (not thoroughly tested - I am in a remote area on a bus).

It is probably easiest for the static library to be the C part of the code and the DLL to be built by the Fortran part because of the additional runtime libraries that the Fortran code requires that will be automatically included by a Fortran project, but you can get things to work either way.

If you go down the path of one DLL built by three projects (two static library projects and a DLL project), then for the same reasons it is probably easiest to have the DLL project be a Fortran project.  The project that builds the DLL does not have to have any source files - it is just a fancy way of invoking the linker.  (You do not want a DLLMain.)

Personally, I prefer to have as much code in static libraries as possible - so I would consider the three project approach.  I can consume static libraries in different executable modules - perhaps in some DLLs, perhaps in some EXEs (which are a bit more convenient for testing purposes).

(Presumably this DLL (or DLLs) are going to be used by something else (a spreadsheet?).  If you also have control over the thing that will use the DLL(s) (e.g. you are also the author of the spreadsheet), then you can structure things however you like in terms of how code is packaged in DLLs (in the absence of good reasons to the contrary, I recommend you like a single DLL!). 

But if you do not have control over the downstream consumer of the DLLs  (e.g. you are providing them to a client who then does whatever they want with them), then changing things like the number or names of DLLs (or the signatures of the entry points in a DLL) can be rather disruptive - you are effectively changing the way the client needs to interface with your code.  In that case you may still want to stick with two DLLs.  But there are still quite simple ways in which to arrange your code to avoid circular link dependencies - one of the DLLs can simply be a thin shim that forwards calls to the other (mixed language) DLL, where all the meaty work is done.

Note that I'm guessing as to what your requirements around this are.  Different requirements lead to different solutions.)

Brian_Murphy
New Contributor II
279 Views

Thanks for the starter project, Ian.  I will study it and decide what path to follow.  The DLL(s) are invoked only from Excel addin code over which I have full control.  The VBA code will of course need revising to work with a single DLL.

I currently build and ship eight separate DLL's.  All could potentially be merged into one.

Reply