Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Include" & "Declare Library" resolves file path differently #124

Closed
a740g opened this issue Jun 26, 2022 · 10 comments · Fixed by #321
Closed

"Include" & "Declare Library" resolves file path differently #124

a740g opened this issue Jun 26, 2022 · 10 comments · Fixed by #321

Comments

@a740g
Copy link
Contributor

a740g commented Jun 26, 2022

Both Include and Declare Library take file names. However, the way they resolve the path is different and this should not be the case.

For example, take the following case for Include that works perfectly. Note the directories.

.\incmain.bas

'$include:'.\include\include1.bi'

Print V1; " "; V2

.\include\include1.bi

'$include:'.\include2.bi'

Const V1 = "One "

.\include\include2.bi

Const V2 = "Two"

Now, a similar case but with Declare Library that throws the error: Library not found

.\libmain.bas

'$include:'include\lib1.bi'

Print function1%

.\include\lib1.bas

Declare Library ".\lib2"
    Function function1%
End Declare

.\include\lib2.h

short function1 ()
{
    return 8;
}

The issue is the same even with static libraries (Declare Static Library).

I understand that when using Declare Dynamic Library DLLs need to be close to the executable for it to work. However, the behavior for header based and static libraries seem so wrong.

Attaching test code test.zip.

Related? QB64Team/qb64#7

@mkilgore
Copy link
Contributor

mkilgore commented Jul 4, 2022

Hey :) Not trying to ignore this, I've just had lots of work stuff recently, hopefully it should slow down in the coming week. That said I agree the behavior isn't great, it's a bad interaction with the fact that anything from '$include is treated as though it's inline at the '$include location. That said IIRC we actually had the fix this problem for '$include itself, because using it in included files would always pull files relative to the original source file. I believe it now first checks the original source location (to ensure backwards compatibility) and then checks the location of the included file. We could probably make Declare Library work in a similar fashion (though I don't know how hard it would be, admittedly).

There may be an argument that the current behavior is correct though, I'm not really sure. Declare Library is not a preprocessor statement, so it's unclear if it should really be impacted by the location of the source file when it's evaluated after preprocessing is done. I'm also not sure there are any other statements that reference files at compile time that we could compare its behavior with, I think it's somewhat unique. So, I think it's a reasonable ask, there may be some discussion to be had though.

@a740g
Copy link
Contributor Author

a740g commented Jul 4, 2022

I like to keep my source code and libraries organized. Everything like libraries (.bi .bm .h .a) go into an include directory and the main program /demos source code stay at the top level. Something like below.

demo.bas
|
|--------------lib1.bi (this uses the .h & .a below)
|--------------lib2.bi
|--------------lib.h
|--------------lib.a

Now the problem here is QB64 does not like this and I have to end up doing the following:

  1. Move the .h & .a to the top level directory
  2. Duplicate the .h & .a to the top level directory
  3. Flatten the whole thing

Workaround 1:

demo.bas
lib.h
lib.a
|
|--------------lib1.bi (this uses the .h & .a below)
|--------------lib2.bi

Workaround 2:

demo.bas
lib.h
lib.a
|
|--------------lib1.bi (this uses the .h & .a below)
|--------------lib2.bi
|--------------lib.h
|--------------lib.a

Workaround 3:

demo.bas
lib1.bi
lib2.bi
lib.h
lib.a

Now, all these workarounds seem wrong to me. I believe is not something we should be forced to do.

@RhoSigma-QB64
Copy link
Member

You should have a look into my QB64GuiTools project. It's organized in the way you suggest above.

  • the main folder QB64GuiTools is sitting in the qb64 main folder
  • it has a subfolder dev_framework with .bi/.bm/.h files and further subfolders (global includes)
  • it has a subfolder for each program/application with the .bas source and further local include subfolders

If you just look into the files, you'll see that I address the global includes assuming the qb64 folder as root, hence starting my path at $INCLUDE/DECLARE LIBRARY with QB64GuiTools, while for the local includes the program/app folder is assumed as root, as you would expect, just use it without the .\ in front of the path.

That works perfect for me on Windows, doesn't matter if I compile to the qb64 folder or to the source folder. Back the days when I started GuiTools and tried to organize the files of the ever growing project, I also had problems, until I waived to the damn '.\', that seems to cause the real problem.

@a740g
Copy link
Contributor Author

a740g commented Jul 4, 2022

I see that you've used a bunch of .h files. Let me play with your library a bit and then I'll share more.

@a740g
Copy link
Contributor Author

a740g commented Jul 5, 2022

Awesome library!

Ok. Here is what I figured out after using it.

I read your note in README.md. Everything worked as expected as long as I kept the QB64GuiTools directory inside the QB64 directory. I was able to compile all your examples. I also noticed how you used declare library - DECLARE LIBRARY "QB64GuiTools\dev_framework\GuiAppFrame" 'Do not add .h here !!.
However, everything fell apart when I moved the QB64GuiTools directory to a different location. I am quite certain that I can get the $include corrected by adding a .\ and making those relative to the new path. But this will not work for declare library (as I found out earlier).

I use GitHub extensively. On a Windows machine I let GitHub Desktop put my code to a location it wants. This may not be the QB64 directory. Similarly, on Linux I want to be able to git clone or gh repo clone anywhere I want. I should not be forced to put all my stuff under the QB64 directory. I really don't want to litter the QB64 directory with multiple files and subdirectories.

@RhoSigma-QB64
Copy link
Member

Ah, now I get the point, so you won't neccessarily the QB64 folder being the root for all relative paths, but any independent location on your drive, trying to "inject" that "base/root" location using .\, which works for $INCLUDE but not for DECLARE LIBRARY.

Well, that might be tricky to find the cause, it's nearly 800 lines in source\qb64.bas (39xx to 47xx) not counting the SUB/FUNC calls involved.

@a740g
Copy link
Contributor Author

a740g commented Jul 5, 2022

Correct. I know this may not be a top priority item but I think the logic how include and declare library resolves the paths should be the same. Basically declare library should mimic what include is doing to resolve the paths.

Now that you have given me a place to look at, I'll try to dig and see if I can find something when I get some time. 🙂

@a740g
Copy link
Contributor Author

a740g commented Jul 5, 2022

image

This? Looks like it is concatenating the IDE path before the library name if .\ or ./ are specified. What is this NoIDEMode? I was tempted to remove the inner If and else and test. But I thought to check first.

@mkilgore
Copy link
Contributor

mkilgore commented Jul 5, 2022

NoIDEMode is set when compiling with -c and -x. Why it matters in this case I'm not entirely sure, but it seems that when compiling with the IDE relative paths are based on where the IDE is located rather than the source file. Frankly that seems like bad behavior, but I don't think we can get rid of it. Beyond that, note that it will get a little messy since we're going to need to first check the current path it picks (so that existing code relying on this doesn't get broken), and then check the include file path if one exists to get the good behavior we're trying to introduce. IMO it would be ideal to just move all that logic below for detecting .h, .lib, .dll, etc. files into some kind of function, it would both benefit the code and make it easy to run it all again with a different path. That's easier said than done though :D

I also noticed that _ICON is another such statement that references a file on the file system, and should probably work the same as DECLARE LIBRARY and any others we find.

@a740g
Copy link
Contributor Author

a740g commented Jul 5, 2022

Correct. I noticed the ExeIcon thing too. To avoid breaking backward compatibility, we can have a persistent menu option to toggle the behavior. By default, it can be enabled and if required, turned off by the user.

a740g added a commit to a740g/QB64pe that referenced this issue Mar 23, 2023
@a740g a740g mentioned this issue Mar 23, 2023
a740g added a commit that referenced this issue Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants