CMake: How to use different ADD_EXECUTABLE for debug build? - visual-studio

I'd like to build my application such that debug mode is a console application and release mode is a Win32 application. According to the documentation I need to add WIN32 to add_executable depending on whether I want a console application or not.
Because I'm using Visual Studio, I can't use CMAKE_BUILD_TYPE (the generated project contains multiple configurations). How can I tell CMAKE to use WIN32 for release builds and omit it for debug builds?

Quoting http://www.cmake.org/Wiki/VSConfigSpecificSettings
if(WIN32)
set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
set_target_properties(WindowApplicationExample PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
set_target_properties(WindowApplicationExample PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "_CONSOLE")
set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:windows")
set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:windows")
endif(WIN32)
UPDATE: This feature is broken in recent versions due to a bug. One workaround I've found is to specify "/SUBSYSTEM:windows" instead of "/SUBSYSTEM:WINDOWS". That seems to work for some reason.

Dunno if this bug has been fixed in CMake yet. I'm using VC++ 2010 express and CMake v2.8.10.1 (which is currently the latest release) and I'm still having the exact same problem.
A working solution was provided here: modify your source code (e.g. main.cpp/main.c) by adding:
#ifndef NDEBUG
#pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#endif
Alternatively, you could add the linker flag "/SUBSYSTEM:WINDOWS" to the release-mode build. I'm using this definition which seems to work:
#ifdef _MSC_VER
# ifdef NDEBUG
# pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
# else
# pragma comment(linker, "/SUBSYSTEM:CONSOLE")
# endif
#endif
Use the entry-point setting in order to avoid linker errors in case you've defined:
int main(int argc, char* argv[]) { ... }

Related

How to exclude a file for a compilation config?

I have a project that can either be built as an DLL or an EXE file, to be built as an .EXE file, a Main.cpp shall be included in the project.
I've set the Debug and Release configuration to build it as EXE file.
Now I'd like to set DebugDLL and ReleaseDLL configuration, (and other necessary adjustment), so that such Main.cpp will be excluded during compilation, and only generate DLL file?
we don't in fact exclude source file because we don't include them but we exclude headers and include them.
to exclude some code from source file consider using "conditional compilation"
#ifdef COMPILING_DLL
// ... dll code
#elif defined _CONSOLE
// .... console coe
#elif defined _WIN32
// ... win32 code
#endif

Unexplainable error "Please use the /MD switch for _AFXDLL builds"

I use VisualStudio2010 and CMake 2.8.12.1. I created a CMakeLists.txt for a MFC project. MFC capability was done by following lines in the CMake file:
add_definitions(-D_AFXDLL) #enables MFC
set(CMAKE_MFC_FLAG 2) #use shared MFC library
Furthermore the project will be build with MD as runtime library (default). But now I want my project to be build as MT (which also requires to specify static MFC library). So I replaced the lines above with:
add_definitions(-D_AFXDLL) #enables MFC
set(CMAKE_MFC_FLAG 1) #use static MFC library
set(CMAKE_CXX_FLAGS_RELEASE "/MT") #set release configuration to MT
set(CMAKE_CXX_FLAGS_DEBUG "/MTd") #set debug configuration to MTd
If I build my project now, I get error message:
fatal error C1189: #error : Please use the /MD switch for _AFXDLL builds
As far as I know this means that there's a mismatch between MT/MD on one side and static/shared MFC library on the other side. I checked the configuration in my project settings once again. Runtime library IS set to MT and MFC library IS set to static. So I do not understand the error. Does anybody know help? Did I miss something?
Regards,
Michael
_AFXDLL is never used with a static MFC build! _AFXDLL.
_AFXDLL is only set when the shared MFC builds are used.
Also static MFC build implies a static CRT.

Opencv in visual studio 2010 [duplicate]

I'm trying to use opencv 2.3 with Visual Studio 2010 Express. My code is from example:
#include "stdafx.h"
#include <highgui.h>
int _tmain(int argc, _TCHAR* argv[])
{
int c;
// allocate memory for an image
IplImage *img;
// capture from video device #1
CvCapture* capture = cvCaptureFromCAM(1);
// create a window to display the images
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
// position the window
cvMoveWindow("mainWin", 5, 5);
while(1)
{
// retrieve the captured frame
img=cvQueryFrame(capture);
// show the image in the window
cvShowImage("mainWin", img );
// wait 10 ms for a key to be pressed
c=cvWaitKey(10);
// escape key terminates program
if(c == 27)
break;
}
return 0;
}
What have I done so far?
Added build\bin and one of build\{x86|x64}\{vc9\vc10\mingw}\bin to my system path (to use DLLs).
Added build\{x86|x64}\{vc9\vc10\mingw}\lib or build\{x86|x64}\{vc9\vc10\mingw}\staticlib as library directories to my linker settings.
Added build\include and build\include\opencv as include directories to my compiler settings.
And the result is:
1>LINK : fatal error LNK1104: cannot open file 'c:\OpenCV2.3\build\x86\vc10\lib.obj'
There's no lib.obj in OpenCV folders. I've only unziped OpenCV-2.3.0-win-superpack.exe, without using CMake software.
What am I doing wrong?
Well, the official guide is for installing OpenCV 2.1 on VS2010, so I wrote some instructions below that shows how to properly install and configure the x86 version of OpenCV 2.3 on Visual Studio 2010 (Express), since a lot of folks seem to have problems setting it up correctly.
Download OpenCV-2.3.0-win-superpack.exe and execute it to extract all files to a folder named OpenCV2.3. Inside this folder there are 2 directories: build and opencv. All the setup on VS2010 will refer to the build directory. For practical purposes I moved the folder OpenCV2.3 to my C:\ drive, so pay attention to the paths I suggest on this guide as yours might be different.
On Visual Studio, create a new Win32 Console Application project and name it whatever you like. After that, a new window will show up. Click on the tab Application Settings and make sure the option Empty Project gets selected:
Add a new file main.cpp to the folder Source Files, then add this code to main.cpp:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: ./opencv_hello <file.png>\n");
return -1;
}
IplImage* img = cvLoadImage(argv[1], CV_LOAD_IMAGE_UNCHANGED);
if (!img)
{
return -1;
}
cvNamedWindow("display", CV_WINDOW_AUTOSIZE);
cvShowImage("display", img );
cvWaitKey(0);
return 0;
}
At this point, we need to configure the project so it can locate OpenCV headers and libraries. Go to the Project Properties (ALT+F7), and once the new window shows up do the following:
On the Configuration box, select All Configurations
Open Configuration Properties > C/C++ > General, and edit the field Additional Include Directories to add these 3 paths (for the headers):
C:\OpenCV2.3\build\include\opencv
C:\OpenCV2.3\build\include\opencv2
C:\OpenCV2.3\build\include
Note that include\opencv is for the C interface of OpenCV and include\opencv2 if for the C++ interface. We are also adding the folder include to prevent our build from being broken by some headers of the C interface that refer to C++ headers as opencv2\core.
Then, add the path of the libraries on Configuration Properties > Linker > General, and on the Additional Library Directories field, add this: C:\OpenCV2.3\build\x86\vc9\lib:
Finally, for this simple test we are going to add the libraries opencv_core230.lib and opencv_highgui230.lib. So go to Configuration Properties > Linker > Input and add them:
When writing more complex applications you'll probably need to add other OpenCV libs that I did not
mentioned on this little project of ours.
Press F7 to Build Solution and you should see:
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
To be able to execute the application you'll need to modify the PATH environment variable of your system to add the location of OpenCV's DLLs. Add this to end of PATH:
; C:\OpenCV2.3\build\x86\vc9\bin
If you are struggling with editing the PATH environment variables, you can also copy the required .dll files to your project folder:
The dll files are located in this folder ../OpenCV2.3/build.x86/vc9/bin
Then copy them to the folder where .exe file is created:
c:\Users\PIMMES\Documents\Visual Studio 2010\Projects\eigenfaces\Debug (Ofcourse you have to change the path to your Debug folder)
You only have to copy the .dll files which you are using in your project (#include for example) For example if you get an error message saying opencv_core231d.dll is not found then get this .dll file from the above location (bin folder) and copy to your project Debug folder.
Hope this helps..
Whenever I make a program that uses opencv 2.2 or greater I include everything, and then comment out the libraries I don't need. Try this, I'm sure you need more than highgui.h
#include "opencv2\opencv.hpp"
using namespace cv;
//#pragma comment(lib, "opencv/opencv_calib3d231.lib")
//#pragma comment(lib, "opencv/opencv_contrib231.lib")
#pragma comment(lib, "opencv/opencv_core231.lib")
//#pragma comment(lib, "opencv/opencv_features2d231.lib")
//#pragma comment(lib, "opencv/opencv_flann231.lib")
//#pragma comment(lib, "opencv/opencv_gpu231.lib")
//#pragma comment(lib, "opencv/opencv_haartraining_engine.lib")
#pragma comment(lib, "opencv/opencv_highgui231.lib")
//#pragma comment(lib, "opencv/opencv_imgproc231.lib")
//#pragma comment(lib, "opencv/opencv_legacy231.lib")
//#pragma comment(lib, "opencv/opencv_ml231.lib")
#pragma comment(lib, "opencv/opencv_objdetect231.lib")
//#pragma comment(lib, "opencv/opencv_ts231.lib")
//#pragma comment(lib, "opencv/opencv_video231.lib")

How to compile the header file with Q_OBJECT macro in Xcode?

I create C++ project in Xcode which links against the Qt framework. The hello world program works well. When I add a class derived from QObject and add the Q_OBJCET macro, there is link error.
The class is
MyObject.h
#ifndef MyObject_h
#define MyObject_h
#include <QtCore/QObject>
class MyOBject : public QObject
{
Q_OBJECT
public:
MyOBject();
};
#endif
MyObject.cpp
#include "MyObject.h"
MyOBject::MyOBject()
{
}
I know I should use the moc to compile the MyObject.h first and add the generated moc_MyObject.cpp to the Xcode project.
In Microsoft Visual Studio, I can configure this header file to be compiled with moc custom tool. And add the generate cpp file to VS project.
But this is Xcode. My question is: Is there equivalent mean in Xcode to compile the header file including Q_OBJECT macro?
Here's how you do it in Xcode 6:
Select your target and in Build Rules make a new custom rule.
Set the "Process" drop down to "Source files with names matching" and type in *.h next to that.
Set the "Using" drop down to "Custom script:" and in the script type something close to this:
/path/to/your/Qt/bin/moc ${INPUT_FILE_PATH} -o ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}_moc.cpp
You'll have to change the path to wherever your moc executable is.
Now set the "Output files" to:
${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}_moc.cpp
That's it for the Custom Rule.
Now to get the headers to be compiled with this rule. While your target is still selected go to "Build Phases". Expand the "Compile Sources" section, hit the "+" button at the bottom. Find and add the header files with Q_OBJECT classes in them. Add those headers to your project first if you can't find them in there.
That's it, Xcode will then run moc on those headers and it will understand that the output from moc is a .cpp and needs to be compiled and linked into you app and do that for you.
I didn't find how to set the custom tool for a specific header file in Xcode. I found a workaround via the build phase script (Build Phases -> Add Build Phase -> Add Run Script). I added the moc command line as script, and included the generated moc_MyObject.cpp file to MyObject.cpp. It works now.

How to include a build timestamp in a VC++ project?

I am converting a makefile project into a Visual Studio VC++ project. It's actually C source code.
One of the statements I have in my makefile is:
echo char * gLibraryBuildSig ="%DATE% %TIME%"; > BuildTimestamp.c
This produces a C source file with a single line in it:
char * gLibraryBuildSig ="Sun 08/23/2009 17:56:05.05";
In the makefile I then compile all the C source with cl.exe, and after linking, delete the BuildTimestamp.c file. This gives me a global symbol that provides the bubild time as a string.
How can I do the same thing in a VS2008 project? Keep in mind it's not MSBuild.
I'm part-way there. To generate a C module at build time in Visual Studio, I just use the pre-build event.
How do I include that generated file into the compile, but also exclude it from source control and project management?
Or, is there a better way to do what I want?
The compiler (cl.exe) has predefined macros __DATE__ and __TIME__, as well as __TIMESTAMP__. You can compile a file containing only these as a pre-link step.
I might be 10 years late, but I like this simple approach. My solution is
my pre-build step:
echo #define DBJ_BUILD_TIMESTAMP __DATE__ " " __TIME__ > build_time_stamp.inc
That little inc, contains a compile time constant in both C and C++. I usually include it in my main.cpp
#include "build_time_stamp.inc"
Since it is generated on each build, it provokes (re)compilation of main.cpp
Usage might be
printf( "\nBuild time stamp: " DBJ_BUILD_TIMESTAMP );
If you do not what to be bothered by GIT to commit/sync/push, that inc file, after each build, simply do not include it in a project. In any case if you want to use it in some more complex scenario, simply keep it in a global constant:
constexpr auto build_time_stamp = DBJ_BUILD_TIMESTAMP ;
Enjoy ...
Another alternative is to use the preprocessor to include the generated file:
#include "BuildTimeStamp.c"
The file that includes this file can be one of the files in the project under source control.

Resources