Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
27093 Discussions

Generated sources and dependencies in Visual Studio

maartenb
New Contributor I
751 Views

I have a Fortran project which I'm porting to Intel Visual Fortran (Parallel Studio). The Visual Studio project and solution files are generated by CMake. A number of the source files are generated in pre-build steps. Some of the generated files depend on non-generated files.

The problem I'm having is that the order of compilation of the source files is not correct which results in errors due to missing module (.mod) files. I assume that this is because the generated source files are not present at the start of the build, so the dependencies cannot be determined.

Is there any way to fix this? For example, is it possible to manually specify the the source file dependencies?

Cheers,
Maarten

0 Kudos
12 Replies
Steve_Lionel
Black Belt Retired Employee
724 Views

When you create a custom build step, you can specify file dependencies and outputs. I suggest that this is where you run your cmake script.

maartenb
New Contributor I
701 Views

Thanks for your reply, but I think I didn't explain myself clearly.
CMake is run to generate the VS solution and project files, but it's not used after that.

The generation of source files in VS is done by means of dummy source files, suffixed by ".rule". These files are in the VS project but don't actually exist. They have a custom build step which calls the script to generate an actual source file. This actual source file is also in the project but don't exist until the custom build step of the corresponding dummy source file has been performed.

So for example my project has a dummy source file: "generate_sourceA.rule". The custom build step of this file generates the actual source file "sourceA.f90". Now sourceA.f90 depends on (i.e. imports a module from) a non-generated file, say, "source_base.f90"--but since sourceA.f90 does not exist at the start of the build, the build system has no way of knowing that. And it might happen that sourceA.f90 is compiled before source_base.f90, resulting in an missing module error.

What would be needed is some way of telling VS that sourceA.f90 depends on source_base.f90.

I hope that's clear. I could supply a minimal example, if that would help.

Steve_Lionel
Black Belt Retired Employee
660 Views

I think you're very close. Make sourceA.f90 be a simple INCLUDE of sourceA_generated.f90, which you DON'T add to the project. Have the custom build action for generate_sourceA.rule create sourceA_generated.f90 and specify it as an output.

maartenb
New Contributor I
629 Views

I think I follow what you mean, but just to be sure: did you mean "Make source_base.f90 be a simple INCLUDE of sourceAf90"? And by "INCLUDE" you mean add 'include "source_base.f90"' to the top of sourceA.f90?

Steve_Lionel
Black Belt Retired Employee
625 Views

I didn't mean either of those - I meant what I wrote. source_base.f90 would be:

INCLUDE 'sourceA_generated.f90'

Visual Studio will see that sourceA_generated.f90 is the output of the custom rule and will run that rule before compiling source_base.f90.

maartenb
New Contributor I
581 Views

I tried your proposed solution but it didn't work.
There might still be a misunderstanding. The problem is not that the build step to generate the files is not run on time; that's the first thing that's done. The problem is that, after generating the files, the order in which the files are compiled is incorrect.

The approach I thought you meant--including source_base.f90 from sourceA.f90--did work. But only if I did it as a preprocessor include (i.e. "#include"). With a regular include the compiler complains that source_base.f90 cannot not be found. The reason is that the generated and non-generated files are in different directories. I guess I can add the directory of source_base.f90 to the include directories, but I haven't figured out how to do that with CMake yet. I'm not sure why it `does work with a preprocessor include but I'll take it.

The only thing now is that there are multiple files that use the module defined in source_base.f90, (sourceB.f90, etc) and I need to add the include line to every one. Then during the linking a git a bunch of warnings` that mo`dule source_base was previously defined. I tried to solve this with "include guards":

#ifndef source_base_included
#include "source_base.f90"
#define source_base_included
#endif

But this didn't work. Does the preprocessor for Fortran work differently than for C/C++?

Steve_Lionel
Black Belt Retired Employee
568 Views

@maartenb wrote:

But this didn't work. Does the preprocessor for Fortran work differently than for C/C++?


Yes, it does, though I am surprised by it not working for you. I'll try playing with this sometime. For Fortran, preprocessing is done by running a separate program (fpp) before the compiler runs. C/C++ has this built-in to the compiler. I fail to see why this should matter, however. It could be that the Fortran dependence analyzer isn't properly picking up on output files, but what I suggested is very similar to how a "Windowing" application runs deftofd to create a .fd file from the resource editor's .h file.

andrew_4619
Honored Contributor I
697 Views

Do the dependencies of a generated source file ever change? If they do change I think you have a  difficult problem.

maartenb
New Contributor I
695 Views

No they don't change. At least, if they would, the project/solution files would be recreated by running CMake.

andrew_4619
Honored Contributor I
576 Views
Why not have the pre build steps outside the main project. Then with all the sources the main project can get the correct build order. Maybe the pre build steps can be in a separate project?
maartenb
New Contributor I
553 Views

You mean creating a separate project just for generating the sources? Yeah that would probably work. Another option would be have CMake generate the sources, i.e. completely outside of VS, together with generating the solution and project files.

I'll discuss the possibilities with the project's maintainer, since I'm hoping to get my changes merged.

andrew_4619
Honored Contributor I
546 Views

Yes that is what meant. It is also possible to have a project that is dependent on another project but I have no knowledge to say if that would work or not in this case.

The problem is that VS analyses the dependencies at the start but your pre-build step then changes the data on which dependency analysis was made. The two project method would break that catch 22 as you would get two depenancy analyses

 

Reply