Behold: My Cmakelists.txt file
project(facedetectlib)
cmake_minimum_required(VERSION 2.8)
include (GenerateExportHeader)
SET(CMAKE_VERBOSE_MAKEFILE TRUE)
file(GLOB HEADER_LIST ./include/*.h)
include_directories(./include)
aux_source_directory(. SRC_LIST)
find_package(OpenCV REQUIRED )
# Allow the developer to select if Dynamic or Static libraries are built
OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
# Set the LIB_TYPE variable to STATIC
SET (LIB_TYPE STATIC)
IF (BUILD_SHARED_LIBS)
# User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED'
SET (LIB_TYPE SHARED)
ENDIF (BUILD_SHARED_LIBS)
add_library(ocvfacedetectlib ${LIB_TYPE} ${SRC_LIST} ${HEADER_LIST})
target_link_libraries(ocvfacedetectlib ${OpenCV_LIBS})
GENERATE_EXPORT_HEADER( ocvfacedetectlib
BASE_NAME ocvfacedetectlib
EXPORT_MACRO_NAME ocvfacedetectlib_EXPORT
EXPORT_FILE_NAME ocvfacedetectlib_Export.h
STATIC_DEFINE ocvfacedetectlib_BUILT_AS_STATIC
)
Using this cmake file and piecing together some instructions from here:
http://www.cmake.org/Wiki/BuildingWinDLL
I am trying to figure out if the DLL is getting built correctly. My header file for my little library has the following in it:
#include "ocvfacedetectlib_Export.h"
typedef unsigned char uint8_t;
extern "C" {
ocvfacedetectlib_EXPORT uint8_t * facedetect( uint8_t *imageData, long buffsize, unsigned char *retbuffer );
}
And then I have in my .cpp file this:
ocvfacedetectlib_EXPORT uint8_t * facedetect( uint8_t *imageData, long buffsize, unsigned char *retbuffer )
{ ..do stuff using OpenCV
...}
This seems to be enough to generate a DLL but I am not sure if it is being built correctly - I am unable to load it use js.ctypes() which is what I am trying to do as my end goal.
For what it's worth—my .cpp has a main() method as well and when I build the code to an .exe it runs.
What is the proper way to generate a windows DLL from a CMake project for later versions of CMake than 2.8, and what has to be changed in the source code to make it work?
Related
Is there any way to disable code insight in Clion for only one file in the project?
I have a swig file with just a few lines. But every time when I go into the file clion complains about header and freeze for long time. I have to open this file in phpstorm or other editor which can't parse c++.
complain messages from Clion
//anal.swig
%module anal
%{
#include "anal.cpp"
%}
void anal(char *str, int size);
The are several ways to do it:
1. Change the file extension from ".h/.cpp" to ".templ" (non C++ related)
2. Clion has special IDE macros, so you can add guard
#ifndef __CLION_IDE__
//anal.swig
%module anal
%{
#include "anal.cpp"
%}
#endif
void anal(char *str, int size);
CLion has #pragma ide diagnostic ignored for selective switch off.
I have installed OpenCV as described here: Installing openCV 2.4 for C/C++ for Visual Studio.
I try to link openCV libraries and I am stuck at "the local method" in this tutorial.
I have two places with openCV files:
[username]/opencv (official)/ where I extracted openCV source (referred further as source directory)
[username]/opencv-build/ where I built openCV using cmake and then compiled it with Visual Studio (referred further as build directory)
The tutorial I try to follow says to link $(OPENCV_DIR)\include which refers to build directory. However, "include" folder in my build directory contains only some cmake files, while "include" in the source directory contains openCV headers (in folders opencv and opencv). I understand that I should rather use the source directory instead, but I tried with both and none of them works.
Next, the tutorial says to link $(OPENCV_DIR)\libs. I have a folder "lib" so I guess it is just a spelling error. My folder "lib" contains two folders: "Debug" and "Release". Should I add [username]/opencv-build/lib/Debug to Debug Property Page and [username]/opencv-build/lib/Release to Release Property Page?
I have added 242 version libraries to Linker input in both Property Pages.
Whatever I did, Visual Studio highlights all of the include statements and hence, everything else.
#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
Any ideas what I am doing wrong?
EDIT after go4sri answer:
Change to opencv\include\opencv solved the problems with includes (except "stdafx.h"), however I tried the following "hello world" now:
#include <cv.h>
#include <highgui.h>
int main ( int argc, char **argv )
{
cvNamedWindow( "My Window", 1 );
IplImage *img = cvCreateImage( cvSize( 640, 480 ), IPL_DEPTH_8U, 1 );
CvFont font;
double hScale = 1.0;
double vScale = 1.0;
int lineWidth = 1;
cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,
hScale, vScale, 0, lineWidth );
cvPutText( img, "Hello World!", cvPoint( 200, 400 ), &font,
cvScalar( 255, 255, 0 ) );
cvShowImage( "My Window", img );
cvWaitKey();
return 0;
}
Although, includes are no longer highlighted, everything else still is. Errors are "identifier XXX is undefined".
EDIT
I have copied some of the files from the previous versions of openCV to <source_directory>\include\opencv2. Now Visual Studio does not highlight anything, however when I try to build it, I get "unresolved external symbol" error for: _cvCreateImage, _cvInitFont, _cvNamedWindow, _cvPutText, _cvShowImage and _cvWaitKey.
You were right to use the include from the source directory.
Change the includes to :
#include <opencv\cv.h>
#include <opencv\cxcore.h>
#include <opencv\highgui.h>
They are all contained in the opencv directory under include.This is the standard way of using Opencv.
However, you can also change the include options to <source_dir>\include\opencv;<source_dir>\include\opencv2;<source_dir>\include [This is not recommended]
For the libs:
Yes. Use the Debug directory in the additional library directories option for Debug( and Release for the release)
You will also need to change the input library names - Note that all debug libraries end with a d while the release libs do not.
For example:
The debug lib will be named: opencv_imgproc242d.lib
The release lib will be named: opencv_imgproc242.lib
Hope this helps...
I have to instrument gcc for some purposes. The goal is to be able to track what GCC functions are called during a particularly compile. Unfortunately I'm not really familiar with the architecture of GCC so I need a little help. I tried the following steps:
1) Hacking gcc/Makefile.in and adding "-finstrument-functions" flag to T_CFLAGS.
2) I have an already implemented and tested version of start_test and end_test functions. They are called from gcc/main.c, before and after toplev_main() call. The containing file is linked to gcc (the object is added to OBJS-common and the dependency is defined later in gcc/Makefile.in)
3) Downloading prerequisites with contrib/download_prerequisites.
4) Executing the configuration from a clean build directory (on the same level with the source dir): ./../gcc-4.6.2/configure --prefix="/opt/gcc-4.6.2/" --enable-languages="c,c++"
5) Starting the build with "make all"
This way I runned out of memory, although I had 28G.
Next I tried to remove the T_CFLAGS settings from the Makefile and give -finstrument-functions to the make command: make CFLAGS="-finstrument-functions". The build was successful this way but when I tried to compile something it resulted empty output files. (Theoretically end_test should have written its result to a given file.)
What do I make wrong?
Thanks in advance!
Unless you specifically exclude it from being instrumented, main itself is subject to instrumentation, so placing calls to your start_test and end_test inside main is not how you want to do it. The 'correct' way to ensure that the file is opened and closed at the right times is to define a 'constructor' and 'destructor', and GCC automatically generates calls to them before and after main:
void start_test (void)
__attribute__ ( (no_instrument_function, constructor));
void end_test (void)
__attribute__ ( (no_instrument_function, destructor));
/* FILE to write profiling information. */
static FILE *profiler_out;
void start_test (void)
{
profiler_out = fopen ("profiler.out", "w");
if (profiler_out == NULL)
exit (-1);
}
void end_test (void)
{
fclose (profiler_out);
}
Footnotes:
Read more about constructor, destructor and no_instrument_function attributes here. They are function attributes that GCC understands.
Read this excellent guide to instrumentation, on the IBM website.
dll export header
extern "C"
void _declspec(dllexport) __stdcall foo();
.def file
EXPORTS
foo #1
When I build the dll by 64bit build config, I meet this warning.
warning LNK4197: export 'foo' specified multiple times; using first specification
But If I build the dll by 32bit build config, the warning never occurs.
What is the problem? What is the difference.
In dll header for interface, we usually use this technic,
#ifdef EXPORT_DLL
#define BASICAPI _declspec(dllexport)
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL
But if def file also exists, we always will be meet the warning when we are building 64bit dll.
So, should we write the codes like this?
#ifdef EXPORT_DLL
#define BASICAPI
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL
It works well. But it's not familiar to me.
Give me any your opinions.
It's generally not good practise to specify exports twice for the same function. If you already have __declspec(dllexport) then you do not need to specify the export in a .def file as well. Conversely, if you have the export listed in a .def file, then there's no need for a __declspec(dllexport).
I believe the reason for the warning is that in x86 builds, the __declspec(dllexport) is exporting the decorated name with a leading underscore, but the 64-bit compiler does not decorate names with a leading underscore, leading to the duplicate. To verify this, you could look at the 32-bit DLL in Dependency Walker and you should see two exported functions, "foo" and "_foo".
__declspec(dllexport) and .def files are two different ways to export symbols from a dll. You don't need both and should omit ono of them. The __declspec method is far more versatile for c++ programs as it exports names with c++ mangling, allowing overloaded functions to be exported, but conversely that does make the names harder to import via GetProcAddress.
Also, using a generic macro like EXPORT_DLL is dangerous as it means that you can't build a dll, that uses another dll, without the one one dll trying to export all the symbols of both dlls.
DevStudio automatically creates a symbol on dll projects: <PROJECT>_EXPORTS making it easy and safe to create a EXPORT macro:
#ifdef EXPORT
#undef EXPORT
#endif
#ifdef PROJECTNAMEHERE_EXPORTS
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXTERN_C EXPORT void __stdcall Function1(void);
EXTERN_C EXPORT void __cdecl Function2(...);
EXPORT void Function3(void);
Functions 1 & 2 can be gotten with GetProcAddress as _Function1#0 and Function2 respectively. Function3 is going to be exported via a compiler specific mangled name that will look something like: #Function3##UAG_DB#Z. This name is different for each overload of the function, which is how it allows overloading to work.
Its important to know the name mangling of __declspec as .def files don't care and would just export Function1, Function2 and Function3.
When using autotools (with a config.h file) for both a library, and a software built on that library, the compiler complains about a redefinition of some macros (PACKAGE_NAME, PACKAGE_TARNAME and so on).
How can I prevent this?
The config.h file is needed in the library to propagate it's setting to the software that use it.
Right now I have a wrapper script library_config.h that includes the original config.h and provides defaults when the user is not using autotools, but even undefining the macros in that package I get the redefinition warning from gcc.
#ifndef LIB_CONFIG_H
#define LIB_CONFIG_H
#ifdef HAVE_CONFIG_H
# include "config.h"
# undef PACKAGE
# undef PACKAGE_BUGREPORT
# undef PACKAGE_NAME
# undef PACKAGE_STRING
# undef PACKAGE_TARNAME
# undef PACKAGE_VERSION
# undef VERSION
#else
# if defined (WIN32)
# define HAVE_UNORDERED_MAP 1
# define TR1_MIXED_NAMESPACE 1
# elif defined (__GXX_EXPERIMENTAL_CXX0X__)
# define HAVE_UNORDERED_MAP 1
# else
# define HAVE_TR1_UNORDERED_MAP 1
# endif
#endif
#endif
I believe the best option would be to have a library without that macros: How can I avoid the definition of PACKAGE, PACKAGE_NAME and so on in the library when using autotools?
EDIT: attemp to explain better.
When using the AC_CONFIG_HEADER macro in the configure.ac of the library I produce a config.h file with a lot of useful defines. This defines are useful for the library itself (both for it's compiled part and for its header files) AND for the client software. It's a pity however that the AC_CONFIG_HEADER mixes the useful macros that I need with other generic defines with fixed names (PACKAGE, PACKAGE_NAME) that clash when autotools are used also for the client software configuration.
If your application might dynamically link to the library, it makes no sense to have the static strings from the library statically built into the application.
Otherwise, you might want to look for ax_prefix_config_h.m4.
I would still just try to avoid installing a config.h file and define the library's API without resorting to config.h:
/* library.h */
const char library_version[];
/* library.c */
#include "library.h"
#include "config.h" /* the library's config.h */
const char library_version[] = PACKAGE_VERSION;
/* application.c */
#include "library.h"
#include "config.h" /* the application's config.h */
int main()
{
print("This is app version %s.\n", PACKAGE_VERSION);
print("The library is version %s\n", library_version);
return 0;
}
Make sure that the public library header files do not #include "config.h", and that the library does not install its config.h.
You should be able to designate the library as a "subpackage" of the software by calling AC_CONFIG_SUBDIRS([library]) in the software's configure.ac. That should eliminate the conflicts, and the settings from the top-level configure will still propagate down to the subpackage.
Here is the link to the page of the Autoconf manual describing this feature: http://www.gnu.org/software/hello/manual/automake/Subpackages.html