How to compile C++ for the same preprocesor variable - c++

In main.c ++ I have several preprocessor variables defined.
#ifndef FIRST
#define FIRST "./path/for/output/files"
#endif
#ifndef SECOND
#define SECOND 0.0125
#endif
#ifndef THIRD
#define THIRD "./input_file.mesh"
#endif
I have to compile this .cpp by varying the three preprocessor macros. To do this, I tried to make a bash file with a for loop to vary the values that these macros took, that is:
#!/bin/bash
for i in *.mesh
do
g++ -Ofast -fopenmp main.cpp eig3.cpp vema.cpp -o main10 -DFIRST=\"\.\/$i\" -DSECOND=0.0125 -DTHIRD=\'\"\.\/$i\"\'
done
This loop constantly reports error, it does not recognize the input file and neither does the output folder. I imagine that I am making many mistakes, I am new to C ++ and I am still a bit lost.
I would like to know if there is any possibility to compile this code with many different values for each parameter. Thank you!

If you really don't want to change the program all that much, compile it once as follows:
g++ -Ofast -fopenmp main.cpp eig3.cpp vema.cpp -o main10 -DFIRST='getenv("OUTPUT")' -DSECOND=0.0125 -DTHIRD='getenv("INPUT")'
And call it as follows:
for i in *.mesh; do
INPUT=./$i OUTPUT=./path/for/output/files ./main10
done

Related

MACRO definition both for a number and a string [duplicate]

I'd like to pass the name of an include file as a compiler argument so that I can modify a large number of configuration parameters. However, my C++ build is via a makefile like process that removes quotes from arguments passed to the compiler and pre-processor. I was hoping to do something equivalent to
#ifndef FILE_ARG
// defaults
#else
#include "FILE_ARG"
#endif
with my command line including -DFILE_ARG=foo.h. This of course doesn't work since the preprocessor doesn't translate FILE_ARG.
I've tried
#define QUOTE(x) #x
#include QUOTE(FILE_ARG)
which doesn't work for the same reason.
For scripting reasons, I'd rather do this on the command line than go in and edit an include line in the appropriate routine. Is there any way?
For adding quotes you need this trick:
#define Q(x) #x
#define QUOTE(x) Q(x)
#ifdef FILE_ARG
#include QUOTE(FILE_ARG)
#endif
You can do
#ifdef FILE_ARG
#include FILE_ARG
#endif
On the command line
$ gcc -DFILE_ARG="\"foo.h\"" ...
should do the trick.
You can also try the -include switch.
gcc manual:
-include file
Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched for file is
the preprocessor's working directory instead of the directory
containing the main source file. If not found there, it is searched
for in the remainder of the #include "..." search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.*
Works for me. Maybe you forgot to quote correctly in your Makefile?
$ cat example.c
#include FILE_ARG
$ cat test.h
#define SOMETHING
$ gcc -Wall -Wextra -W -DFILE_ARG=\"test.h\" -c example.c
$
EDIT:
The reason you might not be able to get quoting to work is because the preprocessor works in phases. Additionally I used "gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2", results may vary between compilers.

How to define DOBJC_OLD_DISPATCH_PROTOTYPES in Xcode?

I use Xcode 11 and need to replicate this compiler command:
cc -g -Wall -Wall -Wextra -std=c99 -pedantic \
-DOBJC_OLD_DISPATCH_PROTOTYPES -c -o example.o example.c
Adding OBJC_OLD_DISPATCH_PROTOTYPES as a user defined macro with no value to the Build Settings doesn't help. Also defining it in the source fails by telling me it already got defined by Xcode via the command line. Despite setting a few suspicious flags to No, it seems Xcode keeps executing #define OBJC_OLD_DISPATCH_PROTOTYPES 1. How can I disable that?
I don't know how Xcode works but I see two points.
In the image you post you ask for a define like DOBJC_OLD_DISPATCH_PROTOTYPES, but in the command line you show it is OBJC_OLD_DISPATCH_PROTOTYPES. Which one you want to define? (Note the first D in the image: it isn't in the command line.)
With the first D the command line parameter would be:
-DDOBJC_OLD_DISPATCH_PROTOTYPES
(The -D is to define, the rest is what is defined.)
Normally that define should be made in the preprocessor options, not the compiler. You can see an example here although I don't know if the example is outdated. (There should be an option somewhere to set preprocessor defines though.)
If Xcode, no matter what, defines that as 1, you can redefine it whenever you need it:
#ifdef OBJC_OLD_DISPATCH_PROTOTYPES
#undef OBJC_OLD_DISPATCH_PROTOTYPES
#define OBJC_OLD_DISPATCH_PROTOTYPES
#endif
(Or DOBJC_OLD_DISPATCH_PROTOTYPES.)
That will get rid of the 1.
You have more information here.

`undefined reference` when trying to interface C to call C++

I was trying to call C++ from C. I am not sure about the linking order. It could have been that to cause the error. For some reasons, the compiler complains undefined reference to helloWorld.
Could anyone advise?
main.c:
#include "example.h"
#include <stdio.h>
int main(){
helloWorld();
return 0;
}
example.h:
#ifndef HEADER_FILE
#define HEADER_FILE
#ifdef __cplusplus
extern "C" {
#endif
void helloWorld();
#ifdef __cplusplus
}
#endif
#endif
example.cpp:
#include "example.h"
#include <iostream>
void helloWorld(){
std::cout << "Hello World from CPP";
}
There are two ways to do this. While both work, one is "cleaner" than the other. Side note: As trojanfoe pointed out, you may have left off the .o on the compile/link command.
Here's a two step process:
cc -c main.c
c++ -o mypgm example.cpp main.o
This is a bit ugly because the usual convention is that the source that gets compiled is the one with main
Here's the more usual way:
c++ -c example.cpp
cc -c main.c
c++ -o mypgm main.o example.o
NOTE: In both cases, the "linker" must be c++ to resolve the std::* that example.cpp uses
UPDATE:
What is mypgm?
mypgm [just an example name] is the name of the [fully linked and ready to run] output executable or program. It's the argument for the -o option. The linker takes your relocatable input .o files, links them together to produce the output file [that can now be run as a command].
It's pretty standard nomenclature for something that is arbitrary in example instruction or code sequences [like here on SO]. You could replace "mypgm" with "ursa_majors_test_program" or "example", or whatever you'd like. To run the program, then type ./mypgm [or ./ursa_majors_test_program or ./example]
There's no magic to the name, just like there was no magic to you naming your source files main.c and example.cpp
It should be descriptive of function. If you had said you were working on a text editing program, in my example, I might have used -o editor

Is it possible to run tests on a cpp file which already has a main function?

Before I get the answer: "Move the code you wish to test to another .cpp file" I cannot do that. I have tried to use preprocessor #if TESTING_SUITE ... #endif but that does not work and I still get the:
multiple definition of `main'
I compile my code like:
g++ -lmxml -lccpunit -o pic pic.cpp wmcc.cp test.cpp
I have one main in pic.cpp and the other in test.cpp. Is there a way around this?
UPDATE
In my test.cpp:
#define TESTING_SUITE_1
In my pic.cpp:
#ifndef TESTING_SUITE_1
int main(...
#endif
Not working
You can specify another entry point to your linker.
For MS cl.exe either in code: (Sorry I didn't see you use gcc)
#pragma comment(linker, "/entry:alternative_main")
or through the project property pages:
Configuration Properties >
Linker >
Advanced >
Entry Point
or directly at the command line:
/entry:alternative_main
For gcc it's the following command line switch:
-Wl,-ealternative_main
For other compilers please refer to the handbook.
You can do it by compiling as
g++ -Dmain=main_pic_moved -c pic.cpp
g++ -Dmain=main_wmcc_moved -c wmcc.cp
g++ -lmxml -lccpunit -o pic pic.o wmcc.o test.cpp

Adding quotes to argument in C++ preprocessor

I'd like to pass the name of an include file as a compiler argument so that I can modify a large number of configuration parameters. However, my C++ build is via a makefile like process that removes quotes from arguments passed to the compiler and pre-processor. I was hoping to do something equivalent to
#ifndef FILE_ARG
// defaults
#else
#include "FILE_ARG"
#endif
with my command line including -DFILE_ARG=foo.h. This of course doesn't work since the preprocessor doesn't translate FILE_ARG.
I've tried
#define QUOTE(x) #x
#include QUOTE(FILE_ARG)
which doesn't work for the same reason.
For scripting reasons, I'd rather do this on the command line than go in and edit an include line in the appropriate routine. Is there any way?
For adding quotes you need this trick:
#define Q(x) #x
#define QUOTE(x) Q(x)
#ifdef FILE_ARG
#include QUOTE(FILE_ARG)
#endif
You can do
#ifdef FILE_ARG
#include FILE_ARG
#endif
On the command line
$ gcc -DFILE_ARG="\"foo.h\"" ...
should do the trick.
You can also try the -include switch.
gcc manual:
-include file
Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched for file is
the preprocessor's working directory instead of the directory
containing the main source file. If not found there, it is searched
for in the remainder of the #include "..." search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.*
Works for me. Maybe you forgot to quote correctly in your Makefile?
$ cat example.c
#include FILE_ARG
$ cat test.h
#define SOMETHING
$ gcc -Wall -Wextra -W -DFILE_ARG=\"test.h\" -c example.c
$
EDIT:
The reason you might not be able to get quoting to work is because the preprocessor works in phases. Additionally I used "gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2", results may vary between compilers.