Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Debugging an executable within another project 1

Status
Not open for further replies.

_hamm

Programmer
Dec 15, 2021
2
DE
Hello people,

I am using VFP9. The project I am working on is quite large and there are many smaller VFP9 projects within the directory structure of main project.

Debugging the main project within the IDE is no problem, but now I need to debug one of the smaller projects within my project.

I know, that I could start the smaller project in my IDE and I could just start debugging that project with some test data. But all those small projects rely heavily on the main projects directory strucutre and files. A lot of GUI components as well.

Now to avoid copying all needed source files into every single sub project, I want to step into the line, that calls the executable of the sub project:

[tt]DO exe_of_subproject WITH toParameter[/tt]

But when I try to do this, the debugger just show "Source not available". I tried calling the name of main file of the sub project instead:

[tt]DO main_of_exe IN exe_of_subproject WITH toParameter[/tt]

But still no luck. All executables are shipped with debug information, so that's not the problem.

My colleagues on site also have no clue on how to approach this problem. Does anybody here have an idea on how to resolve this? Or maybe even an alternative approach to this? My end goal is to able to play around with the code of one of those sub projects, as the source code doesn't contain any documentation and I have to refactor most of it.
 
Welcome to the forum.

The situation you describe is not at all unusual. A lot of my own development work follows the same pattern. To be honest, I don't understand why you find it a problem.

Let me explain how I go about it.

First, I would never try to debug an application within the IDE by launching an EXE file (assuming your "exe_of_subproject" is an actual EXE file). I create the EXE when I am ready to distribute the application, not during the development phase.

I have a directory tree for the various components of the application. I expect you have too. You will have a root directory, below which are sub-directories for form, reports, code, menus, etc. respectively. The main program for your main application would sit in the root directory. Let's call it MAIN.PRG.

MAIN.PRG has code to set the search path to the root directory and to the sub-directories below it. Something like this:

Code:
SET DEFAULT TO JUSTPATH(SYS(16))
SET PATH TO Forms, Reports, Code ... etc. ADDITIVE

When you are ready to test the application, you DO MAIN.PRG (optionally passing a parameter). The application will then be able to find all its forms, reports, etc. When you are ready to build the executable, all those components will get bound into the EXE.

Now, turning to the other application (what you refer to as a sub-project), this would work in exactly the same way. You would use the same directory tree. The sub-application would access the same forms, reports, etc as the main application, and ignore any that it doesn't need. Any components specific to the sub-application would go into the same sub-directories.

The main program for the sub-application (let's call it MAIN_SUB.PRG) would have exactly the same SET DEFAULT and SET PATH as the other one. When you are ready to test it, you run MAIN_SUB.PRG. To build its executable, you would create a separate project for it (using the Projexc Manager), and use that to launch the build.

At least, that's how I would do it. If I have misunderstood the problem, perhaps you clarify it.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you for your fast response Mike.

I am aware, that it's usually a really bad idea to try and debug and executable file. I also always launch the main application with it's main.prg.

Thanks to your answer I can now debug the code of the sub appliaction.

Turns out, that I just needed to replace

[tt]DO main_of_exe IN exe_of_subproject WITH toParameter[/tt]

with

[tt]DO main_of_exe.prg WITH toParameter[/tt]

preceeded by the right [tt]SET PATH TO [somePath] ADDITIVE[/tt]

Though, I haven't tested, which side effects come due to this as some .prg and .vcx files do have the same name, but do not contain the same code in main and sub application. I assume that I will have to clean up the SET("PATH") expression afterwards, if there are any conflicts.
 
Glad to have been of help.

I think part of your difficulty might have been some confusion over the term "project" (and therefore "sub-project"). I think most developers would take that term to refer to the various components that appear in the Project Manager window, and which is the target of a build. That's not quite the same as an application. It's true that there is generally a one-to-one relationship between projects and applications, but that it not necessarily the case. It's quite possible to have more than application within a project - which is the case here.

some .prg and .vcx files do have the same name, but do not contain the same code in main and sub application
.

That's something that you really need to sort out. It is bound to lead to problems.

Keep in mind the compiler directives, such as #IF / #ENDIF. Used carefully, these allow you to have code in the same PRG or VCX that allows you to support two or more different versions of your application.

Mike





__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Code:
DO main_of_exe.prg WITH toParameter

That's possible in general, yes, you can debug code without even having any project opened. This isn't debugging the EXE itself, but that's okay.

_hamm said:
I assume that I will have to clean up the SET("PATH") expression afterwards, if there are any conflicts.

I don't know, could be. Dpeneds on what the mainprg does, of course. Using absolute paths would make any path compatible with any pjx.

The other thing you can do is using the environment manager to switch between projects including current settings. The only file VFP opens exclusive is the pjx (and pjt) but not all project files, so you should not need to worry about that. Calling code also doesn't change the project items, only building a project can lead to added project files.


Chriss
 
Regarding the cleaning up of paths, this needn't be a problem - even if you switch between testing multiple applications in the same session (as I often do) - providing each application's main program contains the correct SET DEFAULT.

Keep in mind too that the directory names specified in the SET PATH can be relative, that is, something like:

Code:
SET PATH TO Code, Forms, Reports

rather than

Code:
SET PATH TO c:\dev\myapp\code, c:\dev\myapp\forms, c:\dev\myapp\reports

That way, you can move the directory tree to any other part of your file system without having to make any changes to your code.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Well, using absolute paths in SET PATH also doesn't mean hardcoding paths, you can set or get the default directory first. But if or when this differs for projects, ie they are not all in the same directory,you can't have multiple DEFAULT paths, but for the common files the absolute path does't differ, for the different versions it must differ.

So there you can identify a list of common and project specific paths and feed that into an environment of the environment manager.

For example at loading a project in a project hook.

Chriss
 
Let me try different and put this into perspective.

SET PATH, SET DEFAULT, etc. are things in main.prg you only need in the IDE or when debugging source code, ie Do a main.prg or do main.prg in some.exe or do some.app or do some.exe.
So one way to deal with this is program a startup code that uses it's own path SYS(16,0) to set a default and all other things relatively.

With environments you can remove that from main.prg and make it an IDE tool. You'r having this code, though the EXE essentially doesn't need it, so why not make it an IDE only tool, as intended with environments? I think they're underrated. There could be some more comfort, ie when clicking on a project manager of multiples it would be nice if that triggers changes of settings like the default folder. But I think you can get there with project hooks.

Chriss
 
Chris said:
But I think you can get there with project hooks.
Just curious. What are project hooks?

At the risk of over-simplifying, isn't the project manager designed to do exactly what the OP wants? He/she mentions "projects" but not project managers.

I have always put separate projects in their own folder. If there is a file used in multiple projects, I can specify its path when I add it to these projects so I don't need copies of it. That includes *.app's.

BTW, I also make desktop shortcuts to the .pjx files of projects I am currently working.

Hope this might help a little.

Steve
 
Let me step up to a more globale analogy of the ID to be your woorkshop to create your EXEs.

The project manager clearly is one major tool, when you have a pjx and open it, you can spend the rest of your development day or session in the project manager alone, many things you can get to via the menu can also be reached from within the project manager window and the designer and edit windows you start up from it. And then context menus, etc.

I think many people don't use all features and classes VFP offers, no problem. But when you learn more about the tools and features they offer, it's like knowing more than hammer, drill, nails, screws and screwdrivers to do a few household things like hanging a picture. Get to know all the tools in the workshop and you can do more things, more detailed, better aimed to the goals you want to achieve.

Now lets get to the project hook. First of all a hook in general is the concept allowing to get into some processes that happen at the point of events. Take the picture literally, A hook is like something that you insert into an existing structure. Project hooks are not thee only hooks available in VFP, I think VFP7 already introduced DBC events and that also offered hooks like BeforeOpen and AfterOpen. The project hook for example has Activate and Deactivate events. I'll get back to that later, as these events could be useful for the case the OP has.

You may know a form also has such events. So your question is very valid, why isn't it simply an extension of the project itself? A form also has no form hook class for form events, it has form methods and events in the form itself, like Load, Init, Activate. VFP doesn't always follow the same patterns. We just need to look back in the evolution of VFP. In a DBC you have one record that has stored procs in one memo, that can also have such hook code since VFP7, IIRC, when DBC events where introduced, which could also have been called DBC hook. For a project hook MS could have extended the PXJ with such a record and use the code editor for it just like for stored procs of a DBC. But they decided for a less tightly coupled implementation. A project hook simply is a class of a VCX (or in a PRG) that can be assigned to a project in project info. One hook for each project, but it might be the same hook you use in all your projects.

It's decoupled like the data environment class decouples the data environment from form classes, in comparison to the other variant Foxpro also still offers and offered first, SCX forms that have an DE simply as integral part of them. I guess one thing is it appeals more to OOP developers to have separation, you can combine separate things in several ways. It's about the separation of concerns. Project hooks can be solutions for multiple projects. So making them separate means reusablility.

And to overcome the limit of one hook per project, I know someone did a project hook that allows registering several project hooks and so you can also combine several project hook ideas without needing to merge all code into one project hook.

There would still be other ways to do this, they could have made a Project base class (actually there is, but lets not go down this rabbit hole) and enable to inherit from it with events, so you could not just have a class tree of project hooks but of projects.

I think the separation here makes sense, as projects are about your application, very different things, while project hooks are only about the work on the project, the IDE, they are not getting compiled into the final EXE they only are available during development. The project itself also is only about your development process, that's right, but each project is, well, about that specific project, so you could say a project hook can bee seen as something that extends the IDE for one or multiple projects and you decide on THE per project base which hooks should extend it.

There you have a detail of that tool that always was available in your workshop and you never knew you had it: You can write a project hook and use it in any project you already have, you can add features and now let me get back to Activate and Deactivate events. These events happen, when you have two projects open and switch between them. And now lets bring this together with the other concept I talked about and you probably also don't know is the other side of the medal and an idea to combine the two sides to the medal: The environments and the environment manager.

Here I can get back on topic to the core problem: Wouldn't it be nice you simply click from one project manger to the next, and everything is set up to now work with the activated project?

The project hook provides the right event for this - the deactivate and the activate. And environments and the environment manager offers the other part to solve the switch from settings for one project to settings of the other project.

The environment manager already was an extension introduced in VFP8 that solved the problem to easily switch between projects, environments are tightly coupled with projects, though in themselves they are again not integrated in PJXes. For other reasons then reusability. But that's why I got the idea: Why not combine all these partial solutions that alreaddy exist to solve the partial problems into something that even automates this so it becomes seamless to work on multiple projects in the same IDE session.

You can always solve this isse by having an ID related PRG to execute when you start working on a project, but the project hook eneables you to do this init's Activate/Deactivae events without thinking about it. And the envirnments are more dedicated to solving the environmental problem of DEFAULT and PATH and other settings.

Even if you're in the simple camp of putting all project files into one directory, with the (completely understanddable and correct) resonong the project manager is there to differntiate all the project items into several tabs and organize this one cluttered directory. It breaks down when you have multiple projects that you don't want to all be in the same folder. At least in subfolders. In some cases for reasons of being able to combine modules even rather in parallel folders or several topic oriented code repositories, also in the sense of project management and version control.

I guess this all is mind blowing if all of this is new, but it becomes a straight forward idea when you know the components of projects, project hooks, environments and see how they could easily come together. What I had in mind is that a one-liner, perhaps two-liner in a project hook Activate could simply use the environment meant for a project and so if you always learned all features of the ID and actively use them, this is the simplest idea to combine the two things to solve the original problem.

On top of that, I got the idea - and I also do or did that - you have some code in main.prg that is only there because you would like to debug in the IDE and not just run and test the EXE. Work without building and waiting for the next EXE, work and suspend and single step through code in the debugger. Again other tools you might not even want to use, but you're missing out a lot of opportunities there, too.

So why not make it a new paradigm, separate things you do for and in the IDE and things that are really belonging in the code of the EXE. Pepole stick to old solutions and don't learn to make use of new features. You already have your solution, maybe like Mike Lewis mentioned with a code section excluded from the final EXE by #IF..#ENDIF and only compiled and execute when _VFP.Startmode=0, for example.

Yes, there always are many ways to solve the same things. But any way it is, I think I'll make that my new way of thinking about this, throw out things of code that rather belongs to configuration and use environments, project hooks, etc.

Chriss
 
Wow, Chris! That was a lot to digest! To be honest, I'm probably "too old a dog" to learn all the new (to me anyway) tricks.

Wouldn't it be nice you simply click from one project manger to the next

When I need a second (or third) project manager on my (43") screen, I just click one of my other project desktop shortcuts and copy/paste whatever I need from project B to project A. I've done it many many times with no problem.

Yes, I'm missing all the other stuff, but for now (and maybe ever), my ignorance shall remain bliss.

I do however appreciate your response. Far more than I expected, and it will surely be helpful to other forum contributors, including the original OP.

Steve
 
The point is not to have two project manager windows, but simply activating one and not thinking about it, you also switch all envirnmental settings and configurations for the activated project.

But also a good point, you can drag&drop from one project manager to another.

Chriss
 
One of the reasons I suggest using relative paths is to make it easy to move the entire directory tree to another part of the file system. The paths are relative to the default directory. The default directory is not hard-coded, but is established by SYS(16). This makes it possible to use the same code (SET DEFAULT and SET PATH) in the main programs of multiple applications.

It's true that you can establish the same search path entirely within the IDE. There's nothing wrong with that. Doing it in code is a personal preference.

In the case of components that are shared between applications (such as my common procedure file and class libraries), I put these in a separate directory at the same level as the individual applications' root directories. But I still reference them within SET PATH with a relative path.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

I get that, but I still think computed absolute paths would be usable across multiple projects that share some common files but would have different relative paths to them.

Assume a structure like this:

[pre]base/common files
base/main project
base/main project/sub project1
base/main project/sub project2[/pre]

First of all, such a structure would make sense, wouldn't it? And now common files is ./common files to the main project, but ./../common files to a sub project. Yet it's the same absolute path. And when default is set to the base directory of a project you can always compute the absolute path, as you said yourself, using SYS(16), a project hook could also base this from JustPath(project.name), but that's just details. What matters to me is that not using relative paths in the environment variable SET PATH means these paths become a constant truth, no matter how SET DEFAULT changes. And I think that is a benefit worth doing.

My solution doesn't fail on moving projects around, too, you just take the new home folder into account automatically, when either main.prg uses SYS(16) as a basis or when a project hook takes the project.name (that's the full path of the pjx file) into account. It's not an advantage to use relative paths, you see? Absolute paths are, well, an absolute truth about the things that don't move when the project moves.

The other part of it is, when there really is something VFP searches by traversing the paths in SET('PATH') I made the experience this is faster with absolute paths than with relative paths. It could be neglectable or similar, but contrary to common usual practice I like my paths computed as absolute paths adapted to the current project home.

And please understand this doesn't make moving a project impossible. That would only be the case, If I'd hardcode absolute paths in a PRG, also those of components that are moving relative to the project base path and I said I don't do that and don't mean hardcoded absolute paths.

Another advantage over purely relative paths is, you don't depend on SET DEFAULT to stay constant. There are many components that rely on relative paths to their base directory, for example classes that manipulate frxes or data access classes changing default to the DBC directory, a share mapped to a drive letter differing from the application folder. If there's any instance that doesn't reset default your relative paths don't work anymore, absolute paths, again, computed absolute paths, don't change at runtime. And that's the important part, the location of EXE and data and other interesting base directories not necessarily staying the same relative to another don't change at runtime, they only may change when you reorganize projects and repositories at design time.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top