I am experiencing technical difficulties with preprocessor directives :
#ifdef, #define
I have a program built by a Makefile, and I have 2 options two build it : standalone or embedded.
I did something like :
#ifdef _mdimode_
//code for embedded
#else
//code for standalone (default)
#endif
And in my main file when I compile in embedded purpose I wrote a :
#define _mdimode_
But it seems that g++ does not recognize or understand it. It always go in the else and never compile the code for embedded version.
Infos:
GNU Make 3.82
g++ (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9)
file suffix : .C
This is a bit of a guess without more information. I assume the code is in a different file than the main file. If this is so then the #define doesn't propagate to that part of the project. You would have to set it in the file that contains the code, or in a header that is #included in it.
You can also choose to set the #define in the options of the compilation command:
g++ -c -D_mdimode_ mycode.C
Related
I'm trying to write some code using the boost libraries on windows 10. To build the application I have chosen mingw64, which I have installed together with MSYS2.
After downloading and installing the boost libraries(1.76), I tried this example code (https://www.boost.org/doc/libs/1_76_0/more/getting_started/windows.html#build-a-simple-program-using-boost), which I built fine using this command:
g++ .\example.cpp -o test.exe -IC:\Users\Benelli\BoostLib\boost_1_76_0\boost_1_76_0
This example works on my system so I assumed that the boost libraries are installed correctly, although I did not build them, but I understood that the boost.test libary can be used as "header only".
I written a simple code following this tutorial:https://www.boost.org/doc/libs/1_76_0/more/getting_started/windows.html#build-a-simple-program-using-boost.
#define BOOST_TEST_MODULE const_string test
#include <boost/test/unit_test.hpp>
This code does not compile and I really do not get why. Is the boost.test library really "header_only"?
The command I used to build it was:
g++ .\boost_test_example.cpp -o boost_test.exe -IC:\Users\Benelli\BoostLib\boost_1_76_0\boost_1_76_0
Which gives this error message:
For the header only:
I think you need to use boost/test/included/unit_test.hpp as per the boost docs at https://www.boost.org/doc/libs/1_69_0/libs/test/doc/html/boost_test/adv_scenarios/single_header_customizations/multiple_translation_units.html
I had a similar winMain error and had to the define for BOOST_TEST_DYN_LINK to the top of the code (when i was linking against the libraries).
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE const_string test
#include <boost/test/unit_test.hpp>
When not using the header only for the undefined references link with the boost test library, eg -LC:/msys64/mingw64/lib -lboost_unit_test_framework-mt.
I'm trying to integrate CUDA to an existing aplication wich uses boost::spirit.
Isolating the problem, I've found out that the following code does not copile with nvcc:
main.cu:
#include <boost/spirit/include/qi.hpp>
int main(){
exit(0);
}
Compiling with nvcc -o cudaTest main.cu I get a lot of errors that can be seen here.
But if I change the filename to main.cpp, and compile again using nvcc, it works. What is happening here and how can I fix it?
nvcc sometimes has trouble compiling complex template code such as is found in Boost, even if the code is only used in __host__ functions.
When a file's extension is .cpp, nvcc performs no parsing itself and instead forwards the code to the host compiler, which is why you observe different behavior depending on the file extension.
If possible, try to quarantine code which depends on Boost into .cpp files which needn't be parsed by nvcc.
I'd also make sure to try the nvcc which ships with the recent CUDA 4.1. nvcc's template support improves with each release.
I'm using the latest version of codelite with the built in mingw 4.8.1 compiler/linker.
The first issue I have, when I create a new g++ project in Codelite with MinGW and then add the -mwindows flag to the linker build settings to utilize (HBRUSH)GetStockObject(BLACK_BRUSH), any cout statement I have in code doesn't print to the console. I need the -mwindows flag for GetStockObject to work, but I have no idea why it would break the cout statement. The code compiles and runs just fine, just nothing gets printed to the console.
The second issue I have is when I try to instantiate a basic class that is in a different project but still under the same workspace. The linker will give out an undefined reference error when I try to instantiate any class in the other project if I just link the .h class file in the project I'm working in. For example:
Framework *test = new Framework();
will give out
E:/CodeLite/ElysiumEngine/Main/main.cpp:9: undefined reference to `Framework::Framework()'
When I include this api.hpp file in the header:
#ifndef FRAMEWORKAPI_HPP
#define FRAMEWORKAPI_HPP
#include "Framework.hpp"
#endif // FRAMEWORKAPI_HPP
but the code links and runs just fine once I do this:
#ifndef FRAMEWORKAPI_HPP
#define FRAMEWORKAPI_HPP
#include "Framework.hpp"
#include "Framework.cpp"
#endif // FRAMEWORKAPI_HPP
I've never had to link the .cpp file in any other compiler or project I'm working on. It doesn't make any sense to me.
Is there anything I can do to solve these two issues?
Just an answer to your 1st question:
The -mwindows flag causes the compiler to pass --subsystem,windows flag to the linker.
The linker flag --subsystem,windows causes your final executable to marked as a non-console (windowed) application and it also sets the default entry point to WinMainCRTStartup.
WinMainCRTStartup does not initialize console I/O and therefore anything printed/read at the console is ignored
I have to build a "proof of concept" using cgicc on Windows. But currently I am unable to build cgicc. The current release of cgicc v3.2.9 won't build neither in MinGW (gcc v4.5.0 / v3.4.5) nor Cygwin (gcc v4.3.4-3).
By using gcc v3.4.5 and automake in MinGW I got:
HTMLAttributeList.cpp:51: internal compiler error: in rest_of_handle_final, at toplev.c:2067
Please submit a full bug report, with preprocessed source if appropriate.
Using gcc v4.3.4 and automake gives for Cygwin:
In file included from CgiEnvironment.cpp:36:
../cgicc/CgiEnvironment.h:52: error: explicit instantiation of 'class std::vector<cgicc::HTTPCookie, std::allocator<cgicc::HTTPCookie> >' in namespace 'cgicc'
which does not enclose namespace 'std')
and for gcc v4.5.0 in MinGW:
../cgicc/CgiEnvironment.h:52:33: error: explicit instantiation of 'class std::vector<cgicc::HTTPCookie>' in namespace 'cgicc' (which does not enclose namespace
'std')
I tried to ignore the Automake and Autoconf scripts. I set up Eclipse-CDT for using the apropriate compiler switches (I also tried Code::Blocks):
-DHAVE_CONFIG_H -DWIN32 -I.. -Wall -W -pedantic -g -DDLL_EXPORT -DPIC -DCGICC_EXPORTS
But again I got:
explicit instantiation of 'class std::vector<cgicc::HTTPCookie, std::allocator<cgicc::HTTPCookie> >' in namespace 'cgicc' (which does not enclose namespace 'std') CgiEnvironment.h /cgicc/cgicc line 52
CgiEnvironment.h:51 to line 53 contains the ifdef WIN32:
#include <string>
#include <vector>
#include <cstdlib>
namespace cgicc {
...
#ifdef WIN32
template class CGICC_API std::vector<HTTPCookie>;
#endif
...
}
What goes wrong? Any suggestions?
Now I can compile cgicc. Thanks to a very good friend of mine, Vlad Lazarenko and some hours of investigation. But I have to do some major changes.
My friend helped me to go on the right way by understanding the main issue. He and Vlad Lazarenko gave me a good direction to investigate the __declspec(). This is a feature of Microsoft compilers which are now supported in gcc.
During investigation I stumbled over a post with migration hints for GCC3.4.3 to GCC4.1.2. So I moved the explicit instantiation of the templates behind the declared namespace in following headers:
Cgicc.h
CgiEnvironment.h
HTMLAttributeList.h
HTMLElementList.h
Next I discovered a strange behaviour while checking different compiler switches and other things regarding my build environment. During investigatiopn of cgicc header files the defined -DCGICC_EXPORTS becomes sometimes undefined (expansion is shown by Eclipse CDT). So I changed CgiDefs.h from:
// export library symbols
#ifdef CGICC_EXPORTS
# define CGICC_API __declspec(dllexport)
#else
# define CGICC_API __declspec(dllimport)
#endif
to
# define CGICC_API __declspec(dllimport)
At the end I changed the compiler switches to
-DWIN32 -DCGICC_EXPORTS -DHAVE_CONFIG_H -I.. -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++98. Most important is -std=gnu++98. Without gnu extensions __declspec() wont generate any symbols - even for a static library. I do not understand why I need that for a static library because the symbols should be in their object files which are packet into libcgicc.a.
Now some further questions:
Do anyone know a mechanism how CGICC_EXPORTS can became undefined
without #undef CGICC_EXPORTS and without -UCGICC_EXPORTS?
Why I have to use gnu extensions? I thought the defaults are independend.
Why do I have to use __declspec(dllexport) for a static library?
Why it is not enough to use the object files of a static library? Let me ask the same
in a different way: Why are no symbols found if I try to link object files of a static
library?
What is the advantage/disadvantage of "implicit template instantiation and vague
linkage" versus "explicit template instantiation"?
The CGICC_API should be either defined as __declspec(dllimport) or __declspec(dllexport).
It looks like that DLL_EXPORT macro that gets defined in command line should affect that, but it doesn't.
My guess is that some header handling it is not included. See this and that for more information.
I have a mixture of c and c++ files compiling under g++. As explained in:
What is the difference between g++ and gcc?
The c files are being compiled as c++ with the g++ command line. Not huge problem but migrating over to gcc will allow th c files to compile as c files and the c++ file to compile as c++.
What -I includes or -L libraries do I need to add to the gcc command line, that the g++ command line is including by default?
You shouldn't need to add any includes or libraries beyond what you already have.
Whatch out for C functions being called from C++ code - you need to tell the C++ compiler those are C functions so the program is linked correctly and works.
The standard practice is to add the following directives to all your C headers being included in C++ files:
#ifdef __cplusplus
extern "C" {
#endif
... C header contents go here ...
#ifdef __cplusplus
}
#endif
More info here: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
You shouldn't need to add any. If it's using C++ it should automatically bring in C++ libraries.
If not, you'll want -lstdc++ (and if you're still getting undefined references, -lc for the libc). Don't forget -lm if you use math functions.
GCC can determine which language a file is in based on the file extension. However, GCC does not automatically link in run time support for any language other than C. In practice that means you can compile C++ programs using gcc instead of g++ but you'll need to add the -lstdc++ directive:
#include <iostream>
int main()
{
std::cout << "Hello world\n";
}
g++ hello.cc
gcc hello.cc -lstdc++
More accurately, you will need to specify -lstdc++ if you you use the standard library, exceptions, operator new, or RTTI. For instance, try compiling the following without -lstdc++:
int main()
{
try {
throw 1;
}
catch (int i)
{
return i;
}
}
Please note that STL containers (including std::strings) use operator new by default. Strictly speaking you should be able to use the algorithms (std::min, std::find_first_of, etc.) binders and a few other things in the standard library without -lstdc++ but for the most part you might as well include it (the linker will ignore any libraries that you don't actually link to).
Why not compile the c objects with gcc and the c++ with g++ and then when you link, link using the g++?