I've never ever gotten absolute or relative paths to work. It always says no such file or directory. With symbolic links within the project directory, the code just builds.
You can generate a batch file that will copy all of the pertinent files to the sketch folder and then launch the IDE. I have tried many times to solve that problem with the IDE. It works fine with the .h files, but it will compile the first .cpp file it finds with the same name. The only reliable solution was to put both the .h and .cpp files in the sketch directory. This becomes very important if you modify a library file and make a second copy. The include order also affects the search order. The IDE does a lot of nice things, but it is not perfect.
What I am suggesting is instead of copying, make a symbolic link. That way, all the changes will be saved in the original library so you do not need to waste time copying files to and fro.
I don't think this will work with relative paths.
Arduino IDE doesn't compile your sketch in the folder where the .ino file is located. Before starting the build, IDE copies the entire folder to the temp directory, and all builds happen there, so when building, your path ..\include\xxx.h will point to a completely different location than the .h file.
One important detail is that the sources are generated and copied into a temp directory, and the compile is done there. The .ino file is converted to an .ino.cpp. (If you have more than one .ino, they are glued together to generate a single .cpp) Then the "eligble" source files in the sketch directory tree are copied. This includes the main translation units -- .cpp, .c, .cc, .cxx, .S -- and supported headers like .h and .hpp. One hint might be whether the IDE allows creating such a file in a new tab, or complains "is not a valid extension".
Even though all the sources in the sketch's tree are copied, only those in the
sketch directory
src/ subdirectory
entire tree under that
are compiled. For example, if you have lib2/ as a sibling of src/, those files would be copied, so #include "lib2/whatever.h" would work, but whatever.cpp there would not be compiled. If that was needed, the sketch would fail to link -- in the C compiler sense.
A file link (hard link, symlink) should work because that is effectively a file in the sketch, and its content will be copied over. But it won't work when
the #include relatively navigates up back into the sketchbook, since the parent of the temp directory is another temp directory, and your files aren't there
running Windows and the temp directory is on a different drive than the sketchbook and the absolute path does not include the drive letter
If you enable Show verbose output during compile, it shows the temp directory in the line right after "Compiling sketch". The command is essentially: "compile .ino.cpp -o .o" to compile the generated .ino.cpp into the named object file. If you scroll all the way to the end, the temp path is there for both. For example on Windows, with extra word wrap added
You can compare files put in the sketch directory by checking that temp directory (<random>/sketch) after a build to see what actually got copied over.
Once you have done the mklink command, the file will appear as a normal file in the directory. For example
U:\arduino\project1>mklink xxx.h ..\include\xxx.h
symbolic link created for xxx.h <<===>> ..\include\xxx.h
U:\arduino\project1>dir
Volume in drive U has no label.
Volume Serial Number is CA18-63CF
Directory of U:\arduino\project1
20/12/2025 09:52 <DIR> .
20/12/2025 09:52 <DIR> ..
20/12/2025 09:51 4 project1.ino
20/12/2025 09:52 <SYMLINK> xxx.h [..\include\xxx.h]
2 File(s) 4 bytes
2 Dir(s) 102,170,308,608 bytes free
U:\arduino\project1>
You can then compile your .ino file with #include "xxx.h". Like Linux, when you modify the .h file, the original in the include directory gets modified.
This is an incorrect conclusion. Your example shown that it is not the case:
The symlink includes a relative path.
The reason this still works is apparently because IDE, when copying your sketch to a separate location for building, copies all nested files and directories, dereferencing symlinks.