I'm new to make. I am working on a C++ shared library, and I want it to have the option to compile with or without support for a certain feature (block of code). In other words, how do I enable the user to choose whether or not to compile the library with that feature by (maybe) passing a parameter to the make command?
For example, I need the user to be able to do this:
make --with-feature-x
How do I do this? Do I need to write a configure file for example? Or can I do this directly within my Makefile?
I believe the following way should work. You define an environment variable when running make. In the Makefile, you check the status of the environment variable. Depending on the status, you define the options that will be passed to g++ when compiling the code. g++ Uses the options in the preprocessing phase to decide what to include in the file (e.g. source.cpp).
The command
make FEATURE=1
Makefile
ifeq ($(FEATURE), 1) #at this point, the makefile checks if FEATURE is enabled
OPTS = -DINCLUDE_FEATURE #variable passed to g++
endif
object:
g++ $(OPTS) source.cpp -o executable //OPTS may contain -DINCLUDE_FEATURE
source.cpp
#ifdef INCLUDE_FEATURE
#include feature.h
//functions that get compiled when feature is enabled
void FeatureFunction1() {
//blah
}
void FeatureFunction2() {
//blah
}
#endif
To check if FEATURE is passed in or not (as any value):
ifdef FEATURE
#do something based on it
else
# feature is not defined. Maybe set it to default value
FEATURE=0
endif
Related
Hi i am working on C++11 related feature , i need to include header file such as
#include <zmqpp/zmqpp.hpp>
in my source code and i wrote some simple g++ script to compile it such as
g++ client.c -o client
i just realized i need to run it with additional argument
g++ -std=gnu++11 client.c .......
in order for me compile successfully.
I am curious what is the default compiler for g++? is it possible for me set
-std=gnu++11 as my default c++ compiler?
Let me know if this duplicated, i was googling around but i don't see any information related to my scenario. Thanks
as stated here, the only way to change the standard version is to rebuild a custom version of g++. If you are using Linux, I recommend having a custom alias in .bashrc, like so:
alias g++11='g++ -std=c++11';
CMake is another common method to do this, simply add this directive to make the default version C++11 :
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Keep in mind CMake is typically used for projects, so it may not be applicable to your use case.
Building my application from Makefile I have found that excluding from code some class and its using doesn't affected on size of the built application.
// some file
// #include "SomeClass.h"
.......
void myfunc()
{
SomeClass _cl;
// do something with _cl etc...
// _cl.SomeFunc();
.........
}
Makefile
......
SOURCES = ... SomeClass.cpp .... etc
But If I remove SomeClass.cpp from Makefile then size of the built application really becomes less. Why gcc doesn't optimize compiled code and don't exclude unused SomeClass from final result?
You can configure this through compile flags. On linux/gcc, unused symbols are not eliminated from the binary - they may be of use when you dl_open() a binary. If you want to eliminate unused code, add -ffunction-sections and -fdata-sections to your compile options and --gc-sections to your linker options. The compile options will ensure that every function is placed in a separate section (as opposed to a section per file), the linker option will throw unused sections away.
I'm trying to compile a simple HelloWorld Prgramm from C++ to Javascript using emscripten.
It works fine when I include a main function which call's e.g. the multi function.
Here is my code (HelloWorld.cpp).
#include <stdio.h>
class HelloWorld {
public: void sayHello() {
printf("Hello World Klasse! %f", multi(7));
}
public: double multi(double x){
return x * x;
}
};
However if I don't include a main function the emcc compile always put's out
ERROR root: No functions to process. Make sure you prevented LLVM
from eliminating them as dead (use EXPORTED_FUNCTIONS if necessary,
see the FAQ)
I know about the 'EXPORTED_FUNCTIONS' option which tells what functions should be included into the compile .js file.
I tried various diffrent things:
Using the mangling name, as far as I understood this the name should be '_multi_d10HelloWorldd'. I also tried without classname and some other combinations.
emcc -s HelloWorld.cpp -s EXPORTED_FUNCTIONS='["_multi_d10HelloWorldd"]'
Using the modifier EXPORT_ALL
emcc -s HelloWorld.cpp -s EXPORT_ALL=1
Whatever I do the functions won't be included in the final js file.
From what I understand from the EMCC FAQ I need to use EXPORTED_FUNCTIONS so I can later on call the desired function e.g. 'sayHello' from JS unsing the same method name.
And this is exactly what I need to do later on.
Could someone please point me to a solution or any other possible option which I may have not thought of ?
Is the mangling name I thought of correct ?
Create an "extern c" block. Inside this block define the functions you want to expose to javascript. These functions should be prefixed with an underscore. Inside one of these functions you can instantiate your C++ class.
This is the same approach as one would take when writing a dynamic library, which has the advantage that you can reuse your library in a native program should you wish.
How can I change the value of a boolean macro when I run my program through the command line? For instance, suppose I have the following macro in my cpp file, call it MyCpp.cpp
#define DEBUG 1
How can I change this when I run my program? through the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp
I am pretty sure you specify some kind of command line option, does this ring any bells?
Also, I do NOT want to use argv[]
First, change your source code:
#ifndef DEBUG
# define DEBUG 1
#endif
Now you can say on the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp -DDEBUG=5
# ^^^^^^^^^
The command line argument -DFOO=bar has the same effect as putting #define FOO bar in your source code; you need the #ifndef guard to avoid an illegal redefinition of the macro.
Sometimes people use an auxiliary macro to prevent the definition of another macro:
#ifndef SUPPRESS_FOO
# define FOO
#endif
// ... later
#ifdef FOO
// ...
#endif
Now say -DSUPPRESS_FOO to not define FOO in the code...
How can I change the value of a boolean macro when I run my program through the command line?
As it stands, you can't. You are using a preprocessor symbol so the decision as to whether debug information should be printed is a compile time decision. You are going to have to change that compile-time DEBUG symbol to a run-time variable that you set by parsing the command line, via some configuration file read in at run time, or both.
Parsing the command line isn't that hard. There are plenty of low-level C-style tools to help you do that. Boost has a much more powerful C++ based scheme. The trick then is to change those compile-time debug decisions to run-time decisions. At the simplest, it's not that hard: Just replace that DEBUG preprocessor symbol with a global variable. You can get quite a bit more sophisticated than this of course. Eventually you'll have a configurable logging system. Boost has that, too.
Please note the following. If you have in your c/cpp file or one of your included header files:
#define DEBUG 1
then you cannot modify this definition using the command line of the compiler (makefile). There is simply no chance. The cpp file will simply overwrite the command line setting.
I use AX_CXX_COMPILE_STDCXX_0X(can look on autoconf-archive) to check for c++11 capabilities of the compiler. It correctly determines that -std=c++0x required, but does not add it to CXXFLAGS. I took a look at the macro source and it actually checks but then restores previous flags.
What should I do to get CXXFLAGS set to be able to compile c++11 source?
Just adding -std=c++0x to AM_CXXFLAGS is not nice solution, because I'd like to put the burden of making the compiler compile in C++11 mode on the autoconf developers, not me.
What you're looking for has already been made as AX_CXX_COMPILE_STDCXX_11, part of autoconf-archive. It will add the required option to the environment (formerly through CXXFLAGS, now through CXX) and error out if no C++11 support is available.
In general you can compile a simple code and set a variable based the outcome of your compilation
DIALECT="-std=c++14"
echo 'int main() {return 0;}' > ./log.cpp && $CXX -std=c++14 ./log.cpp || $DIALECT="no"
if test $DILAECT = no; then
AC_MSG_ERROR([c++ compiler does not support c++14])
else
echo $DILAECT
fi