GNU Make "gsrc/%.v: %.rdl" file generation - makefile

Hello I'm currently using GNU Make and one of my targets is as shown.
gsrc/%.v: %.rdl
run tool on the .rdl
The tool generates a gsrc/example.v, example.vh, and a example.xml file (normally into my current working directory). The example.v file is moved into the gsrc directory off the target definition I'm assuming and I'm trying to figure out way for all of the files generated to be moved into the gsrc directory.
I guess firstly, does the gsrc/%.v cause the generated file to be moved to the gsrc directory, and if so how can I get my .vh and .xml into the same directory using make?
-Thanks

Make doesn't ever move any files anywhere. If you write a rule like:
gsrc/%.v : %.rdl
<run some command>
you're telling make that when it wants to build a file named gsrc/example.v it can execute <run some command> and that command will create and/or update that file. The contents of that recipe must do all the updating and moving of files. Make doesn't do it for you.
So, if you want your output to go into gsrc but the command you run doesn't put it there, then you can just add more stuff to your recipe to move it:
gsrc/%.v gsrc/%.vh gsrc/%.xml: %.rdl
<run some command>
mv $*.vh $*.xml gsrc

Related

Making single executable includes all program file and folders with nsis?

I have zip file containing my installation files. I'm extracting this zip and copying these files into installation directory with the script shown below:
ZipDLL::extractall "$OUTDIR\demo.zip" "C:\myapp\demo\"
if I remove zip file from $OUTDIR than installer is not able to find zip file as expected. What I want to do is embedding this zip or its extracted folders into exe itself. I added
File -r "$OUTDIR/demo"
but this script didn't worked as well.
When you use the ZipDll plugin, you are referring to the file you want to process (demo.zip) by using its place at run time: along the installer.exe.
When you use the File statement to embed some files into the produced installer, you need to refer to the files by using their place at compile time.
Replace the $OUTDIR in the File statement by the path relative to the .nsi script.
BTW, you should take the habit to check at the compilation log, NSIS probably tells you about that kind of problem when paths are incorrect at compile-time.

How to have make build from one directory if the source file exists, otherwise build from another?

I'm working on modifying a huge recursive makefile project that has 6000+ source files. All of which are clearcase controlled. Since I don't want to copy the whole source tree, I'm trying to create a new project only containing the modified source files and thus pull the source from the original tree if they don't exist in my modified tree.
I have already modified the makefile in ModDir to check if each folder exists locally and execute make in that folder if it does. Otherwise it executes make in the sourceDir. My issue lies in the subdir makefiles.
Each subdir makefile contains a list of all of the source files needed for that module. I need to find a way to build the file locally if it exists, else build the file from SourceDir/subdir.
I.e. in my image, the Dir1 makefile needs to build F1 from ModDir/Dir1/F1, and build the other files from SourceDir/Dir1/F2-F3.
I tried to use VPATH to tell make to locate the source files in both locations (ModDir first of course) which works beautifully. However, since make assumes the object files are in the ModDir, it can't find any of the object files built in SourceDir.
I also tried making a pre-build rule to modify the make file list with bash, but I don't know if that's even possible.
How do I use make to build from one directory if the source file exists (ModDir), otherwise build from another (SourceDir)?
The easiest way will be to put your "if ... then ... else" logic in an external bash or batch (whichever OS you use) script and swap makefiles before calling make

How to make open sourced scripts 'installable'?

I've finished a little useful script written in Bash, hosted on github. It's tested and documented. Now, I struggle with how to make it installable, i.e. where should I put it and how.
It seems other such projects use make and configure but I couldn't really find any information on how to do this for bash scripts.
Also I'm unsure into which directory to put my script.
I know how to make it usable by myself but if a user downloads it, I want to provide the means for him to install it easily.
There is no standard for this because most of the time, a project isn't a single script file. Also single file scripts don't need a build step (the script is already in an executable form) and configuration usually comes from an external config file (so no need for a configure script, either).
But I suggest to add a comment near the top of the file which explains what it does and how to install it (i.e. chmod +x + copy to folder).
Alternatively, you could create an installer script which contains your original script plus a header which asks the user where she wants to install the real script and which does everything (mkdir, set permissions with sudo, etc) but it really feels like overkill in your case.
If you want to make it installable so the package manager can easily install and remove (!) it, you need to look at the documentation for rpm or Debian packaging. These are the two most used package managers but they can't install a script per-user (so it would probably end up in /usr/bin)
instruct them to create a file named after the script in their home directory, chmod ug+x the file so it has executable permissions than put the script inside the file, don't forget the #!/bin/bash up top of the vim. This example is a script to copy a file, archive the copied file than remove the copied file leaving only the original file and the archived file.
#!/bin/bash
#### The following will copy the desired file
cp -r /home/wes/Documents/Hum430 /home/wes/docs
#### Next archives the copied file
tar -zcvf Hum430.tar.gz /home/wes/docs
#### and lastly removes the un-archived copy leaving only the original and the archived file.
rm -r /home/wes/docs
### run the file with ./filename (whatever the file is named)

Executing binary files with a shebang

I created a simple program that takes the path of a directory as an input, creates an archive of that directory (converting it into a single file), adds a shebang to that file (so that the contents of the file can be easily extracted), and writes the file to the base directory of the specified path.
The problem is that the file does not extract itself when I double click on it. Instead the operating system (I'm using Ubuntu 11.10) tries to open it with gedit. This obviously shows the shebang, random gibberish, and the contents of the archived files.
I made the file executable, first by using chmod +x; and when it still didn't work I tried chmod 777. However it still refuses to execute the file with the shebang when I double click on it. Perhaps this is because it's not a pure text file.
Interestingly when I try to execute the file directly from command line it reads the shebang and extracts the contents of the archive properly. So there's nothing wrong with my file format. I don't know much about what operating systems do when you double click on a file but I would sure like to understand.
It surely makes no sense to add a shebang to a file if you still need to manually execute it from the command line. One advantage could be that you don't need to specify the program to open it with but I believe that's hardly an advantage. Any help will be greatly appreciated.
Update 1:
The program that creates the archive is called opm. It can be installed via the node package manager using the following command:
npm install opm
After that you simply use opm to pack and unpack directories for you. For example if I have a directory called test in my home directory then I can open a terminal and execute the following command to pack it:
opm test
This will create an archive of the directory called test.pack in the home directory. The .pack file has the shebang #!/usr/bin/opm. Opening a file with the extension .pack with opm tells it that it's an archive and opm unpacks it in the same directory.
Note: Change the name of the test.pack file if you do not want it to overwrite your existing test directory.
I added the shebang to the .pack file so that it would extract itself when I opened it. However that doesn't seem to work. Nevertheless if I run one of the following command then it works:
./test.pack
You may check my source code and make any modifications to the program as you may wish to.
Update 2:
Alright I created the following .desktop file for opm and stored it in the $HOME/.local/share/applications/ directory:
[Desktop Entry]
Type=Application
Version=1.0
Encoding=UTF-8
Name=OPM
GenericName=Object Packer and Minifier
NoDisplay=true
Comment=JavaScript Package Manager
TryExec=opm
Exec=opm %f
Terminal=false
MimeType=application/opm
Now I was able to associate .pack files with opm by right clicking on a .pack file, going to the Properties window, the Open With tab, and setting opm.desktop as the default application. Now I am able to unpack a .pack file by simply opening it.
However I would like to know how to associate .pack files with the mime type application/opm. Currently the .pack files are associated with application/x-java-pack200. How do I do so? Is it better if I use a different extension (e.g. .opm)? By associating the packed archives with the mime type application/opm will the OS open them with opm by default without having to explicitly set a default application from Properties > Open With?
If there's already a MIME-type associated with .pack then you'll want to use a different extension (.opm) to associate with your MIME-type (application/opm). The way you automatically associate a program that opens files of a specific MIME-type is with xdg-mime .
Alternatively,
Edit ~/.local/share/applications/mimeapps.list and put your MIME/application combo under [Default Applications] like so:
[Default Applications]
application/opm=opm.desktop;
Place your opm.desktop file in ~/.local/share/applications/ folder. (You've already done this)

How to force the build to be out of date, when a text file is modified?

The Scenario
My project has a post-build phase set up to run a batch file, which reads a text file "version.txt". The batch file uses the information in version.txt to inject the DLL with a version block using this tool.
The version.txt is included in my project to make it easy to modify. It looks a bit like this:
#set #Description="TankFace Utility Library"
#set #FileVersion="0.1.2.0"
#set #Comments=""
Basically the batch file renames this file to version.bat, calls it, then renames it back to version.txt afterwards.
The Problem
When I modify version.txt (e.g. to increment the file version), and then press F7, the build is not seen as out-of-date, so the post-build step is not executed, so the DLL's version doesn't get updated.
I really want to include the .txt file as an input to the build, but without anything actually trying to use it.
If I #include the .txt file from a CPP file in the project, the compiler fails because it obviously doesn't understand what "#set" means.
If I add /* ... */ comments around the #set commands, then the batch file has some syntax errors but eventually succeeds. But this is a poor solution I think.
So... how would you do it?
This works in VS2005. If you're not using that, some of the settings may be in different places or with different names.
Add the text file to your project, right click on it in the Solution Explorer and select 'Properties'. Under Configuration Properties > General make sure that the file is not excluded from the build. Under Custom Build Step > General, put your existing post-build command as the Command Line setting. Make sure you specify your .txt file as the output file. Now F7 should spot changes to the text file and run your batch file.
This may be too "hacky" but this might work:
Write a quick Perl (etc.) script to check version.txt has been updated.
If the file has been modified, have this script update a dummy source file that is compiled with your project.
Run the script as a pre-build event.
This way if the script sees that the file has changed, it will change the other one, which will force a re-build.
Hacky, but try it if you're scraping the bottom of the barrel.

Resources