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

Generated sources and dependencies in Visual Studio

maartenb
New Contributor I
1,706 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
Honored Contributor III
1,679 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.

0 Kudos
maartenb
New Contributor I
1,656 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.

0 Kudos
Steve_Lionel
Honored Contributor III
1,615 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.

0 Kudos
maartenb
New Contributor I
1,584 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?

0 Kudos
Steve_Lionel
Honored Contributor III
1,580 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.

0 Kudos
maartenb
New Contributor I
1,536 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++?

0 Kudos
Steve_Lionel
Honored Contributor III
1,523 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.

0 Kudos
andrew_4619
Honored Contributor II
1,652 Views

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

0 Kudos
maartenb
New Contributor I
1,650 Views

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

0 Kudos
andrew_4619
Honored Contributor II
1,531 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?
0 Kudos
maartenb
New Contributor I
1,508 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.

0 Kudos
andrew_4619
Honored Contributor II
1,501 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

 

0 Kudos
Reply