Installer compilation errors (strstr function related and otherwise) - windows

I couldn't find this in any searches and have been fighting with these scripts this past week, trying to learn how NSIS' scripting works from scratch in the process. Cutting to the chase, here's what I'm encountering and take note I'm working with another person's scripts in the process:
Initial state of the scripts:
Fails to enable the program's functionality (which is to present an easy to use .exe to call in the command line that may then be followed by other commands in relation to another file to extract its contents).
Presents warnings that AddEnvVar and un.RemoveFromEnvVar functions are not called.
Add calls to the functions in the .nsi file in the appropriate sections.
Installer compiles, but when run presents an Installer Corrupted: Invalid Opcode error.
Okay...Not sure why that's happening. There's another script called EnvVarUpdate present, maybe that's it. Add a line in the .nsi to include it. Then I run into this:
Error: Function named "StrStr" already exists. Error in macro
STRFUNC_FUNC on macroline 16 Error in macro FUNCTION_STRING_StrStr on
macroline 1 Error in macro _IncludeStrFunction on macroline 2
!include: error in script: "EnvVarUpdate.nsh" on line 50
Okay. Try commenting out those lines to get it through...And I hit this:
!insertmacro: macro "FUNCTION_STRING_StrStr" requires 0 parameter(s),
passed 3! Error in macro EnvVarUpdate on macroline 84
I have no idea if EnvVarUpdate needs to be included to begin with (since it wasn't originally included in the .nsi script I'm at a loss for what it's even doing there) and I can't figure out why the calls to AddEnvVar and un.RemoveFromEnvVar are corrupting the installer. It seemed logical to me that for since these files were published with the intent being easy compilation that all the files would be necessary, but with the function calls missing and the exclusion of one of the scripts in the .nsi file rendering the compiled installer dysfunctional, I'm led to believe he may have made some mistakes in the process.
My guess is since he also published a compiled installer that works hosted on his own site, he incidentally left the open files a little broken as he figured out the right way to do it. However, personally, I'd still like to repair them if I can figure out how to enable others to manually compile the installers if they like.
If it might help, here's a link to the fellow's code on GitHub.

AddToPath.nsh contains two functions that manipulate %path% (AddToPath and un.RemoveFromPath) and two generic functions that can manipulate any environment variable (AddToEnvVar and un.RemoveFromEnvVar) but those two functions are never used so you get a warning.
To remove the warnings you can just comment out those two unused functions.
EnvVarUpdate.nsh uses the StrStr that is a part of NSIS so you get a problem because it is already defined in AddToPath.nsh
A common pattern for utility functions like these is to put the function inside a macro and then allow the .nsi to select the functions it uses by inserting the macro (And the macro creates the function at that point):
!macro Foo un
Function ${un}Foo
MessageBox mb_ok "Hello from Foo"
FunctionEnd
!macroend
...
!insertmacro Foo "" ; Use function Foo in installer?
#!insertmacro Foo "un." ; Use function Foo in uninstaller?
Section
call Foo
SectionEnd

Related

How to test my dll file written in fortran?

I have written a Fortran code for being compiled as a '*.DLL' file.
The program which reads that file is a Finite Elements Method software named Plaxis, I already achieved to generate the '*.DLL' file in Visual Studio and Plaxis recognizes my model but the model does not work fine.
I would like to evaluate all the variables involved in my code and the procedure that Plaxis is using to read them, but when I use commands like "write(*,*) 'variable'" Plaxis does not show me what I asked in the source code.
Probably you want to open a file and write to that for debug logging, because presumably Plaxis doesn't run with standard output connected to anything useful. Or maybe it would if you just ran Plaxis from a command line window?
It's not going to create a dialog box for you.
But anyway, another option would might be attach to Plaxis with a debugger, and set a breakpoint in a function in your DLL. Then you can single-step your code as called by Plaxis.
Or you can write your own test callers and write unit tests for your functions, making them easy to debug. This could work well if your function just gets an array + size as args.
If instead it passes some wrapped object that you need to call special functions to deal with, then maybe make another version of your function that does just take an array so you can call it from a simple test caller.

Reading an array from a text file

I have a problem. When the program reads a text file, it always get out of the line and crashed.
var f:text;
i,j,cs:byte;
a:array[0..10,0..10] of int64
begin
assign(f,'anything.txt');
reset(f);
cs:=0;
while eoln(f)=false do
begin
read(f,a[0,cs]);
inc(cs);
end;
close(f);
end.
Here is the content of anything.txt:
2 4 8 16
exitcode=201
You have not told us which compiler you are using.
In Delphi and Turbo Pascal which preceded it, run-time error 201 means "range check error". I don not still have Turbo Pascal installed but your program compiles and runs as a "console application" correctly in Delphi with only one minor change, namely to insert a semi-colon (';') after int64. It runs correctly whether the compiler has range-checking turned on or not.
It also runs correctly in FreePascal + Lazarus.
So, unless you are using a different compiler which also happens to have a run-time error code 201, your problem seems to be caused by something you have not included in your question. In any case you should learn to debug this kind of problem yourself. So:
Look up how to use use the debugger in your Pascal compiler. Place a breakpoint on the line inc(cs) e.g. by pressing F5and run the program. When it stops at the BP, place debug watches (using Ctrl-F5 in Delphi/TP) on the values of cs and a and observe the values carefully. Press F8 repeatedly to single step the program, and see if you can see where and why it goes wrong.
One possibility for what is causing your problem is that you are not reading the copy on anything.txt you think you are: because you don't include a path to the file in assign(f Windows will use the copy of anything.txt, if any, in whatever it thinks the current directory is. To avoid this, include the path to where the file is, as in
assign(f, 'C:\PascalData\Anything.Txt');
Also btw, you don't need to compare a boolean function (or expression) againt true or false as in
while eoln(f)=false do
Instead you can simply do
while not eoln(f) do

F# interactive - how to use precompiler directives when multiple files reference the same assembly?

So, in Project AB I have FileA.fs and FileB.fs. FileB uses definitions from FileA, and both FileA and FileB use definitions from Project C (written in C#).
In FileA.FS, I have:
#if COMPILED
namespace ProjectAB
#else
#I "bin\debug"
#r "ProjectZ.dll"
#endif
...which works how it's supposed to -- I can run the whole file in F#-Interactive and it's great.
In FileB.fs, my header is:
#if COMPILED
module ProjectAB.ModuleB
#else
#load "FileA.fs"
#I "bin\debug"
#r "ProjectZ.dll"
#endif
But when I run this (from FileB), I get the error:
FileA.fs(6,1): error FS0222: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.
According to the fsi.exe reference, the #load directive "Reads a source file, compiles it, and runs it". But it seems like it must be doing so without the COMPILED directive defined, because it doesn't see the "namespace ProjectAB" declaration.
How can I set up my headers so that I can run either file in F#-interactive?
Edit Per latkin's answer below, I created a script as the last file in the project, _TestScript.fsx. I removed all the precompiler stuff from the other files and set this as the header of the .fsx file:
#if INTERACTIVE
#I "bin\debug"
#r "ProjectZ.dll"
#load "FileA.fs"
#load "FileB.fs"
#endif
When I run this in the interactive, it correctly loads ProjectZ, FileA, and FileB for me to access in the interactive window.
However, in _TestScript.fsx, I get squiggly red lines and no intellisense on any of the functions/types from the referenced files (including the "open" statements).
Is there something else I need to set up in the script file to make the intellisense work? (The answer might be pretty basic since I have not used .fsx files before.)
I don't think there is a way to do this smoothly. A few things to consider:
INTERACTIVE is always defined when you are being processed by fsi.exe, whether you are a .fsx, .fs, #load'ed, whatever. COMPILED is similarly always defined when you are being processed by fsc.exe. I can see how the quoted phrase from the docs maybe doesn't make this totally crystal clear.
You can only declare namespaces in fsi from a #load'ed file
So if you want your file to declare a namespace, and to work as the single file in interactive, then the namespace has to be #ifdef'ed out. But that also means the namespace will be #ifdef'ed out when the file is #load'ed...
You might be able to work around this by conditionally declaring it as a module, not a namespace. Or perhaps creating additional, more granular defines. It will be tricky.
Trying to get source files to work properly as part of a compiled library and simultaneously as single-file scripts is not easy, and I don't think the tooling was designed with this scenario in mind. More common is to have all of your library files behave purely as library files, then use dedicated standalone scripts which #loads the .fs files they need. This keeps the driving code and the library code separate, and things fit together more cleanly.

GDB: Seeing the source code lines?

Does any program compiled with the -g command have its source code available for gbd to list even if the source code files are unavailable?? Also when you set the breakpoints at a line in a program with a complicated multi source file structure do you need the names of the source code files??
OP's 1st Question:
Does any program compiled with the -g command have its source code available for gbd to list even if the source code files are unavailable??
No. If there is no path to the sources, then you will not see the source.
OP's 2nd Question:
[...] when you set the breakpoints at a line in a program with a complicated multi source file structure do you need the names of the source code files??
Not always. There are a few ways of setting breakpoints. The only two I remember are breaking on a line or breaking on a function. If you wanted to break on the first line of a function, use
break functionname
If the function lives in a module
break __modulename_MOD_functionname
The modulename and functionname should be lowercase, no matter how you've declared them in the code. Note the two underscores before the module name. If you are not sure, use nm on the executable to find out what the symbol is.
If you have the source code available and you are using a graphical environment, try ddd. It stops me swearing and takes a lot of guesswork out of gdb. If the source is available, it will show up straight away.

Xcode error: Command /Developer/usr/bin/clang++ failed with exit code 1 due to duplicate symbol

I'm trying to write a program in C++ which runs Conway's Game of Life. I think I have everything that I need, but I'm having some trouble with compiling.
The program is composed of four files: gameoflife.h, a header file which contains my global constants and function declarations, gameoflife.cpp, which defines the functions, main.cpp, which uses the functions, and seeds.cpp, which contains a list of predefined seeds to be used.
When I go to compile the application, I seem to have a clash of duplicate symbols between main.cpp and gameoflife.cpp over an array called currGen which is declared in gameoflife.h.
Both main.cpp and gameoflife.cpp include gameoflife.h, which of course is necessary so that they have access to the global constants and function declarations.
The exact error I receive is the following:
duplicate symbol _currGen in /(same_path)/ConwaysGameOfLife.build/Objects-normal/
x86_64/gameoflife.o and
/(same_path)/ConwaysGameOfLife.build/Objects-normal/x86_64/main.o
for architecture x86_64
Command /Developer/usr/bin/clang++ failed with exit code 1
I've looked around on Stack Overflow but haven't found anything which matches my problem. Any help would be greatly appreciated!
You are probably defining the variable currGen in your header file, not just declaring it.
There needs to be exactly one definition, in one .cpp file. The .h file should just declare it, using extern.
This answer goes into much more detail.

Resources