How to get scons to treat a directory itself as a target? - doxygen

I'm trying to set up a build involving an external tool which produces a directory as output (doxyindexer for the curious). So far, I've essentially got these commands:
target = "doxysearch.db/iamchert"
doxygen.Doxyindexer(target,["project1.xml","project2.xml","project3.xml"])
Default([target])
Default(Install(ARGUMENTS["cgibin"],"doxysearch.db"))
The problem that I'm having is that I think I'd like target to be the directory itself, not some random file inside the directory. There's nothing I can glob because the target doesn't exist until I build it and I don't want to presume anything that Dimitri might change! When I use the directory as the target, I get this error:
TypeError: Tried to lookup Dir 'doxysearch.db' as a File.:
which is why I picked iamchert to be the target. Those lines all seem to work as expected, even if my approach is a hack. However, I can't get that last line to work. I need to copy the directory doxysearch.db into the cgi-bin directory, which is specified on the command line by the user. Maybe someone can explain how to do this step properly? I'm a newb when it comes to scons!
I'm having trouble googling the answer because all the search words involved are too common to find me specific help!

SCons does in fact treat all the files in a dir as dependencies of that dir. There are some dark corners that need work, but it should work in a simple case like this.
What you need is the undocumented target_factory builder flag. When you define Doxyindexer do it like this:
doxyindexer = Builder(..., target_factory=env.fs.Dir)
and have your builder return the dir itself. That should avoid the TypeError you were getting.

Im not sure how well SCons will work with the target being a directory. The issue is: How should SCons determine if the directory has changed or not to know if it should be built? The obvious answer would be that a directory is considered to be changed if it has more or less files therein, but I dont think SCons currently does this check and you might have to make your own builder to get it.
I did the following example to test this, and it never builds:
env = Environment()
env.Command(target = 'targetDir',
source = 'srcTextFile',
action = Copy("$TARGET", "$SOURCE"))
When I execute SCons, I always get the same result:
scons: '.' is up to date
Regarding your SCons code, I think it would work better as follows:
targetDir = "doxysearch.db/iamchert"
srcFiles = ["project1.xml","project2.xml","project3.xml"]
doxygenTarget = doxygen.Doxyindexer(targetDir, srcFiles)
    # This may need to be called via the Command() builder like this:
    # cmd = "doxygen.Doxyindexer("$TARGET", "$SOURCE")
    # doxygenTarget = env.Command(target=targetDir, source=srcFiles, action=cmd)
# This call to Default isnt really necessary
Default(doxygenTarget)
Install(ARGUMENTS["cgibin"], doxygenTarget)

Related

Roblox ModuleScript reporting Infinite yield possible on

Helping my kid learn to develop. Using Roblox as the tool.
We are in the ServerScriptService folder and in a file called OverheadRankScript. I have a line of code like this:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataModule = require(ReplicatedStorage:WaitForChild("DataModule"))
My ModuleScript is in ReplicatedStorage folder and it is new and looks like this.
local module = {}
return module
I get the following error
Infinite yield possible on
'ReplicatedStorage:WaitForChild("DataModule")'
I copied the example from this link
https://developer.roblox.com/en-us/articles/Scope
Does ModuleScript script need to be in Replicated Storage or is Server Script Service the correct area?
Not sure what I am doing wrong should the file name be DataModule or is ModuleScript ok?
Does the variable need to change not sure the example provided in the documentation does not seem to work.
It's just a warning, but you can add a timeout to it for the warning to stop showing up.
local DataModule = require(ReplicatedStorage:WaitForChild("DataModule", 10))
The 10 is the optional timeout parameter that you can change to whatever you'd like to.
Actually what I found out was the DataModule needs to be renamed to ModuleScript. That Is the file name and it is referencing the file name. The example referenced in the link does not mention this at all. Infinite yield possible was misleading and it could not find the file.

Writing string to specific dir using chaquopy 4.0.0

I am trying a proof of concept here:
Using Chaquopy 4.0.0 (I use python 2.7.15), I am trying to write a string to file in a specific folder (getFilesDir()) using Python, then reading in via Android.
To check whether the file was written, I am checking for the file's length (see code below).
I am expecting to get any length latger than 0 (to verify that the file indeed has been written to the specific location), but I keep getting 0.
Any help would be greatly appreciated!!
main.py:
import os.path
save_path = "/data/user/0/$packageName/files/"
name_of_file = raw_input("test")
completeName = os.path.join(save_path, name_of_file+".txt")
file1 = open(completeName, "w")
toFile = raw_input("testAsWell")
file1.write(toFile)
file1.close()
OnCreate:
if (! Python.isStarted()) {
Python.start(new AndroidPlatform(this));
File file = new File(getFilesDir(), "test.txt");
Log.e("TEST", String.valueOf(file.length()));
}```
It's not clear whether you've based your app on the console example, so I'll give an answer for both cases.
If you have based your app on the console example, then the code in onCreate will run before the code in main.py, and the file won't exist the first time you start the activity. It should exist the second time: if it still doesn't, try using the Android Studio file explorer to see what's in the files directory.
If you haven't based your app on the console example, then you'll need to execute main.py manually, like this:
Python.getInstance().getModule("main");
Also, without the input UI which the console example provides, you won't be able to read anything from stdin. So you'll need to do one of the following:
Base your app on the console example; or
Replace the raw_input calls with a hard-coded file name and content; or
Create a normal Android UI with a text box or something, and get input from the user that way.

waf copy a file from source tree to the build tree

I have the following snippet, to copy a file as-is to the build dir:
for m in std_mibs:
print("Copying", m)
bld(name = 'cpstdmib',
rule = 'cp -f ${SRC} ${TGT}',
#source = m + '.mib',
source = bld.path.make_node(m + '.mib'), # <-- section 5.3.3 of the waf book
target = bld.path.get_bld().make_node(m + '.mib')
)
I see that this rule, though hit (from the print), the copy doesnt seem to be happening!
I also changed the source to use the make_node as shown, in an example in the section 5.3.3 of the waf book, still no luck! Am I missing something obvious here!?
Also, I have some rules after this, which rely on the copied files, and I tried adding
an intervening
bld.add_group()
I hope that the sequencing will work, if this copy succeeds
If you run the rule once, it will not be run again until source is updated. This is true even if the target is deleted, for instance (which is probably how you were testing.)
If you want to recopy if the target is deleted, you will need always=True, or you'll need to check for existence and set target.sig = None.
Two alternatives:
features="subst" with is_copy=True:
bld(features='subst', source='wscript', target='wscript', is_copy=True)
waflib.extras.buildcopy like this:
from waflib.extras import buildcopy
#...
def build(bld):
bld(features='buildcopy',buildcopy_source=['file'])
cp is not platform independent.
A task_gen object is created, which later will become a Task, that will be executed before process_sources. Don't expect an immediate effect.
Have a look into your out dir, there will be out/${TGT} (not exactly, but ${TGT} path relative to your top directory)
This is totally to be expected behaviour, since you do not want to modify your source tree when building.

How to reliably detect os/platform in Go

Here's what I'm currently using, which I think gets the job done, but there's got to be a better way:
func isWindows() bool {
return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}
As you can see, in my case all I need to know is how to detect windows but I'd like to know the way to detect any platform/os.
Play:
http://play.golang.org/p/r4lYWDJDxL
Detection at compile time
If you're doing this to have different implementations depending on the OS, it is more useful to
have separate files with the implementation of that feature and add build tags to each
of the files. This is used in many places in the standard library, for example in the os package.
These so-called "Build constraints" or "Build tags" are explained here.
Say you have the constant PATH_SEPARATOR and you want that platform-dependent, you
would make two files, one for Windows and one for the (UNIX) rest:
/project/path_windows.go
/project/path_unix.go
The code of these files would then be:
path_windows.go
// +build windows
package project
const PATH_SEPARATOR = '\\'
path_unix.go
// +build !windows
package project
const PATH_SEPARATOR = '/'
You can now access PATH_SEPARATOR in your code and have it platform dependant.
Detection at runtime
If you want to determine the operating system at runtime, use the runtime.GOOS
variable:
if runtime.GOOS == "windows" {
fmt.Println("Hello from Windows")
}
While this is compiled into the runtime and therefore ignores the environment,
you can nevertheless be relatively certain that the value is correct.
The reason for this is that every platform that is worth distinguishing needs
rebuilding due to different executable formats and thus has a new GOOS value.
Have you looked at the runtime package? It has a GOOS const: http://golang.org/pkg/runtime/#pkg-constants
It's 2022 and the correct answer for go 1.18+ is:
At runtime you want:
if runtime.GOOS == "windows" {
// windows specific code here...
}
If you need to determine the filesystem path separator character
Use: os.PathSeparator
Examples:
c:\program files
/usr/local/bin
If you need the Path List separator as used by the PATH environment variable
Use: os.PathListSeparator
Examples:
/usr/local/bin:/usr/local:
"C:\windows";"c:\windows\system32";
Since this is an older question and answer I have found another solution.
You could simply use the constants defined in the os package. This const returns a rune so you would need to use string conversion also.
string(os.PathSeparator)
string(os.PathListSeparator)
Example: https://play.golang.org/p/g6jnF7W5_pJ
I just stumbled on this looking for something else and noticed the age of this post so I'll add a more updated addition. If you're just trying to handle the correct filepath I would use filepath.Join(). Its takes all of the guesswork out of os issues. If there is more you need, other than just filepath, using the runtime constants (runtime.GOOS & runtime.GOARCH) are the way to go: playground example
I tested in Go 1.17.1 which really worked for me.
package main
import (
"fmt"
"runtime"
)
func main(){
fmt.Println(runtime.GOOS)
}
Output:
darwin
With regards to detecting the platform, you can use Distribution Detector project to detect the Linux distribution being run.
The first answer from #nemo is the most apropiate, i just wanted to point out that if you are currently a user of gopls language server the build tags may not work as intended.
There's no solution or workaround up to now, the most you can do is change your editor's lsp configs (vscode, neovim, emacs, etc) to select a build tag in order to being able to edit the files with that tag without errors.
Editing files with another tag will not work, and trying to select multiple tags fails as well.
This is the current progress of the issue github#go/x/tools/gopls

How to resolve Unable to find file.cpp in path(s) in Marmalade?

I'm just trying to begin develop a game in Marmalade (6.3). But when I have made my new sources (.cpp, and .h) and added them to the mkb, and then trying to run my program, then I got an error which says that Unable to find file.cpp in path(s). It's for all of my files except the files (game.h, game.cpp, main.cpp) which were made by Marmalade when I have chosen the new 2D game project. Should I add my .cpp and .h files to anywhere else?
Thanks
It is difficult to give a categorical answer without more info. However my guess is that you've copied and pasted from an example and not understood about the syntax of the files section. Basically:
files
{
(foo)
humbug.cpp
)
The "(foo)" might look very innocent, but it actually says that humbug.cpp is actually in directory foo - relative to the mkb file. It is common practice to actually use "(source)" and put all the source files in a directory of that name - making the source layout a bit neater.
Naturally if you have (source) and don't put the files actually in directory source, they won't be found. My guess is that is what you are seeing.
Just to clarify previous answer, The format of files directive is like this -
files
{
(<Path relative to MKB>,<Alternate Path>)
["Name of the parent Group in VS/XCode project","Name of the subparent group"]
fileName.cpp
fileName.h
}
for example I have two files SoundManager.h and SoundManager.cpp in System folder of Source, while MainMenu.h and MainMenu.cpp in Source/UI. Now the files directive would be -
files
{
(Source/System)
["Source","System"] #This part is not required, it's just to arrange your files in IDE project
SoundManager.h
SoundManager.cpp
(Source/UI)
("Source","UI")
MainMenu.h
ManinMenu.cpp
}