Visual Studio, MSBuild: First build after a clean fails, following builds succeed - visual-studio-2010

There's obviously something wrong with my build, but I can't figure it out. I narrowed this down to one of my projects: first build after clean fails, all following builds succeed.
I get linking errors which say that some symbols are already defined:
>------ Build started: Project: Problem, Configuration: Debug Win32 ------
> Blah blah blah...
23> Creating library D:\SVN.DRA.WorkingCopy\Debug\Problem.lib and object D:\SVN.DRA.WorkingCopy\Debug\Problem.exp
23>ProblemDependency1.lib(PD1.obj) : error LNK2005: "public: unsigned short __thiscall PD2Class::getFoo(void)const " (?getFoo#PD2Class##QBEGXZ) already defined in ProblemDependecy2.lib(ProblemDependency2.dll)
23>ProblemDependency1.lib(PD1.obj) : error LNK2005: "public: void __thiscall PD2Class2::`default constructor closure'(void)" (??_FPD2Class2#Image#DRA##QAEXXZ) already defined in ProblemDependency2.lib(ProblemDependency2.dll)
23>D:\SVN.DRA.WorkingCopy\Debug\Problem.dll : fatal error LNK1169: one or more multiply defined symbols found
Problem is a C++/CLI project, built with the /clr switch, which references the unmanaged C++ projects ProblemDependency1, a static lib, and ProblemDependency2, a dll.
ProblemDependency1 references ProblemDependency2.
getFoo() is declared as inline and defined outside of the class declaration, in the .h
PD2Class2 doesn't have an explicitly defined default constructor, but it has a constructor which has all default arguments, so you could say it includes the default constructor as a special case
The .h's where these are defined have #pragma once as their first line.
Any hint on troubleshooting this? I can post more info if needed
Update: I solved the first error thanks to Anders Abel's suggestion, but I still can't solve the second one (the one about the default constructor)
Update: If I compile using MSBuild outside Visual Studio, it fails always, with the same error
Edit: Here's some code. First, a bit of PD2Class2's declaration. PD2Class2's real name is CImage (feeling lazy to anonymize), CImage.h:
#pragma once
#pragma warning( disable: 4251 ) //TODO: Disable and solve
#include "ImageProperties.h"
#include "../CommonCppLibrary/CriticalSection.h"
#include <windows.h>
#include <stdexcept>
#include <string>
class CSharedMemory;
class EmptyImageException;
struct IShape;
struct SImageStatics {
unsigned short low3Percentile;
unsigned short high97Percentile;
unsigned short medianPixelValue;
unsigned short meanPixelValue;
unsigned short minPixelValue;
unsigned short maxPixelValue;
};
namespace DRA{
namespace Image{
class __declspec(dllexport) CImage {
friend class CImageLock;
//Attributes
int m_iPitch;
protected:
mutable CImageProperties m_cProperties;
CSharedMemory * m_pSharedMemmory;
mutable DRA::CommonCpp::CCriticalSection m_csData;
static const float PIXEL_FREQUENCY_COVERAGE;
static const float PIXEL_CUTOFF_PERCENTAGE;
static const int MINIMUM_PIXEL_FREQUENCY; //Pixels with a frequency lower than this are ignored
static const int MINIMUM_WINDOW_WIDTH_FOR_16_BITS;
//Methods
//Some private methods
public:
CImage( DWORD dwWidth = 0, DWORD dwHeight = 0, ULONG uBytesPerPixel = 0,
bool isSigned = false, EPhotometricInterpretation ePI = PI_UNKNOWN,
UINT bitsStored = 0, float pw = -1.0f, float ph = -1.0f, BYTE * pData = NULL );
CImage( const CImageProperties& cProperties, int iPitch = 0 );
CImage( const CImage& rImage );
virtual ~CImage();
virtual CImage& operator=( const CImage& );
bool operator==( const CImage& rImage );
//Alter State
//More methods
//Query State
//More methods
};
}
}
Next, the constructor's definition, from CImage.cpp:
CImage::CImage( DWORD dwWidth, DWORD dwHeight, ULONG uBytesPerPixel, bool isSigned,
EPhotometricInterpretation ePI, UINT bitsStored, float pw, float ph,
BYTE * pData ) :
m_iPitch( dwWidth * uBytesPerPixel ),
m_cProperties( dwWidth, dwHeight, uBytesPerPixel, bitsStored, ePI, isSigned, pw, ph ),
m_pSharedMemmory( NULL ),
m_csData(){
m_pSharedMemmory = new CSharedMemory( pData ? pData : new BYTE[getSize()] );
}

Is getFoo() marked as __declspec(dllexport)? If it is an inline function, it is instantiated/used from wherever it is called through the included header. It shouldn't be part of the functions that the dll exports and it should not have a dllexport directive.
__declspec(dllexport) might be handled through a macro that is expanded to dllexport or dllimport depending on if it is the dll or code using the dll that is compiled. If there is any macro in the function declaration you might have to dig into it to find if there is an export directive.
Update
I think that if the header file is used both when the dll is built and when the dll is used, it is incorrect to have __declspec(dllexport) in the header file. Instead use a macro system:
#ifdef PROBLEMDEPENDENCY2
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT CImage
{
//...
}
Then define the PROBLEMDEPENDENCY2 preprocessor symbol when building the dll, but not when using it. The problem with hardcoding __declspec(dllexport) in the header file is that the compiler will try to export the class both from ProblemDependency2 (which is correct) and from ProblemDependency1 (which is incorrect).

Just something I've run into recently to check:
Are you building on a network volume? I had been having problems with not being able to debug my applications because the .pdb file was not "there" after the build and before the debug launch due to latency in the SAN that I was working on as a build directory.
Once I moved the project build to a local volume, everything was fine.
Don't know if that's what's happening to you or not, but something I'd look into.

I dont' have much c++ experience, but problems like this in other .NET languages, often result from having a DLL reference to another project in the same solution (to the DLL in the "obj" or "bin" folder of the other project, instead of a project reference. This stops Visual Studio from being able to figure out the build order, and, hence, the first time after a "clean", you will not have the DLL you are depending on. On the second build, this DLL will already have been built, and the build will succeed.

Related

C++11, Is it possible to force an instance to be extern but also a constant expression of a non-type template parameter?

Using C++11, g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18).
Lets pretend I have a templated function (pardon my terminology if it isn't quite right).
I want to perform a "general" algorithm based on what was supposed to be compile-time instances of "field". Where the only things that really changed are these constants which I moved into trait classes (only added one here but imagine there are more). Originally I was declaring it as
constexpr field FIELD1{1};
However in C++11, non-type template params need to have external linkage (unlike C++14 which can have internal and external linkage?). So because not's in the same translation unit I needed to use extern in order to give it external linkage (sorry if I butchered that explanation also). But by defining it extern I can't define it using constexpr and it seems that losing that constexpr constructor this field is no longer a valid constant expression to qualify as a non-type template param.
Any suggestions if there is some way I can get around this? Open to a new method of doing things. Below is a simplified (incomplete, and non-compiling version to get the gist of the organization).
So the error I am seeing is along the lines of
error: the value of ‘FIELD1’ is not usable in a constant expression
note: ‘FIELD1’ was not declared ‘constexpr’
extern const field FIELD1;
Not quite sure what could be a best alternative.
I can get rid of the second error by removing the constexpr from the constructor. But then I don't know how to approach the constant expression issue.
field.H
struct field
{
int thingone;
constexpr field(int i):thingone(i){}
};
extern const field FIELD1;
field.C
#include "field.H"
const field FIELD1{0};
field_traits.H
#include "field.H"
template< const field& T >
class fieldTraits;
template< >
class fieldTraits<FIELD1>
{
public:
// Let's say I have common field names
// with different constants that I want to plug
// into the "function_name" algorithm
static constexpr size_t field_val = 1;
};
function.H
#include "field.H"
template< const field& T, typename TT = fieldTraits<T> >
void function_name()
{
// Let's pretend I'm doing something useful with that data
std::cout << T.thingone << std::endl;
std::cout << TT::field_val << std::endl;
}
So because not's in the same translation unit I needed to use extern in order to give it external linkage (sorry if I butchered that explanation also). But by defining it extern I can't define it using constexpr [...]
Per my comment, you can. It wouldn't work for you, but it's a step that helps in coming up with something that would work:
extern constexpr int i = 10;
This is perfectly valid, gives i external linkage, and makes i usable in constant expressions.
But it doesn't allow multiple definitions, so it can't work in a header file which is included in multiple translation units.
Ordinarily, the way around that is with inline:
extern inline constexpr int i = 10;
But variables cannot be declared inline in C++11.
Except... when they don't need to be declared inline because the effect has already been achieved implicitly:
struct S {
static constexpr int i = 10;
};
Now, S::i has external linkage and is usable in constant expressions!
You may not even need to define your own class for this, depending on the constant's type: consider std::integral_constant. You can write
using i = std::integral_constant<int, 10>;
and now i::value will do exactly what you want.

Unresolved external symbols since Visual Studio 2015 update 3: boost python linking error if destructor is virtual

We are getting strange unresolved symbols linking errors since we updated to Visual Studio 2015 update 3. Anyone else encountered the same kind of issues ?
What is really weird is that boost::get_pointer is a template method, defined in a boost header. I do not understand how we can get an undefined external symbol in that case :(.
Here is a reproducer, with boost 1.61 and Python 3.5.1:
#include <vector>
#include <boost/python.hpp>
using namespace boost::python;
class Canard {
public:
Canard() {}
virtual ~Canard() {}
};
BOOST_PYTHON_MODULE(coin)
{
register_ptr_to_python< std::shared_ptr<Canard> >();
}
And the error:
Severity Code Description Project File Line
Error LNK2019 unresolved external symbol "class Canard const volatile * __cdecl boost::get_pointer<class Canard const volatile >(class Canard const volatile *)" (??$get_pointer#$$CDVCanard###boost##YAPEDVCanard##PEDV1##Z) referenced in function "private: static struct _typeobject * __cdecl boost::python::objects::make_ptr_instance<class Canard,struct boost::python::objects::pointer_holder<class std::shared_ptr<class Canard>,class Canard> >::get_derived_class_object<class Canard>(struct boost::mpl::bool_<1>,class Canard const volatile *)" (??$get_derived_class_object#VCanard###?$make_ptr_instance#VCanard##U?$pointer_holder#V?$shared_ptr#VCanard###std##VCanard###objects#python#boost###objects#python#boost##CAPEAU_typeobject##U?$bool_#$00#mpl#3#PEDVCanard###Z) CCMasterKernelPyPy C:\work\dev\builds\internal\Master\SDK\MasterKernelPyPy\main.obj 1
But as soon as I remove the virtual in front of the destructor of the Canard class, then it starts working.... Does anyone have a clue ? Is it a Visual Studio bug ?
Visual Studio 2015 update 3 has added lots of features and improvements (see the release notes https://www.visualstudio.com/news/releasenotes/vs2015-update3-vs#visualcpp).
It also have some known issues (https://msdn.microsoft.com/vs-knownissues/vs2015-update3 see the Passing non-pointer-like types to uninitialized_copy section).
To fix your problem you need to explicitly specify the conversion to pointer of your class, explicitly:
namespace boost
{
template <>
Canard const volatile * get_pointer<class Canard const volatile >(
class Canard const volatile *c)
{
return c;
}
}
Good luck,
Ohad

NDK C++11, call to deleted constructor error

I have a class called RenderCommand:
class RenderCommand
{
public:
RenderCommandType commandType;
RenderCommand() : commandType(RenderCommandTypeNone) {};
virtual ~RenderCommand() {};
};
I then have a queue of these RenderCommands which stores unique_ptrs to them:
typedef std::deque<std::unique_ptr<RenderCommand>> RenderQueue;
Finally in a section of code, I create a vector of these RenderQueues, and try to resize it:
std::vector<RenderQueue> queues;
queues.resize(4);
The resize line is giving me a few issues. In clang I get the error message:
call to deleted constructor of 'std::unique_ptr<RenderCommand, std::default_delete<RenderCommand> >'
With GCC 4.8, I just get a whole bunch of errors similar to
required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<RenderCommand>, const std::unique_ptr<RenderCommand>&, const std::unique_ptr<RenderCommand>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<RenderCommand>, std::unique_ptr<RenderCommand>&, std::unique_ptr<RenderCommand>*>; _Tp = std::unique_ptr<RenderCommand>]'
This compiles fine in Visual Studio 2012 however so I'm a little lost. I appreciate any help you guys can give!
EDIT: RenderCommandType is just an enum:
enum RenderCommandType
{
RenderCommandTypeNone = 0,
RenderCommandTypeBeginRepeat,
RenderCommandTypeEndRepeat,
RenderCommandTypeBeginScene,
RenderCommandTypeEndScene,
//etc
};
EDIT2: Ok this seems to be a std::deque problem, changing RenderQueue to:
typedef std::vector<std::unique_ptr<RenderCommand>> RenderQueue;
works. Also removing references to my own class and just using an int still doesn't work (unless like above I replace deque with vector):
std::vector<std::deque<std::unique_ptr<int>>> tempQueue;
tempQueue.resize(4);
:-/
I simplified your example to
#include <deque>
#include <vector>
struct A {
A(const A&) = delete;
};
void f()
{
std::vector<std::deque<A> > q;
q.resize(4);
}
With g++ 4.6, this example compiles fine. From g++ 4.7 on however, it prints a lot of error messages, finally resulting in the mentioned
error: use of deleted function ‘A::A(const A&)’
Replacing deque with vector or list doesn't show this behaviour.
So, it seems this is either a regression from g++ 4.6 to 4.7 or a correction of a previous bug. In any case, I filed a bug report with g++, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59192

Steps to make a loadable DLL of some tcl methods in Visual Studio

I want to create a loadable DLL of some of my tcl methods. But I am not getting how to do this. For that I have taken a simple example of tcl api which adds two numbers and prints the sum. Now I want to create a loadable DLL for this to export this tcl functionality.
But I am not understanding how to do it in Visual Studio. I have written a C code which can call this tcl api and get the sum of two integers, but again I don't want it to do this way. I want to create a DLL file to use this tcl functionality. How can I create this DLL on Visual Studio 2010.
Below is my sample tcl program that I am using:
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is the C code which can use this tcl functionality :
#include <tcl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source myscript.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
I have successfully compiled this code with the below command
gcc simple_addition_wrapper_new.c -I/usr/include/tcl8.5/ -ltcl8.5 -o simple_addition_op
The above code is working with the expected output.
What steps do I need to take to create a loadable dll for this in Visual Studio 2010?
If you look at the answers to this question: here it gives the basic outline of the process you need to go through. There are links from my answer to some Microsoft MSDN articles on creating DLLs.
To go into this in a little more detail for a C++ dll that has Tcl embedded in it.
The first step is to create a new visual studio project with the correct type, one that is going to build a dll that exports symbols. My example project is called TclEmbeddedInDll and that name appears in code in symbols such as TCLEMBEDDEDINDLL_API that are generated by Visual Studio.
The dllmain.cpp look like this:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
allocInterp() ;
break ;
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
destroyInterp() ;
break;
}
}
return TRUE;
}
The allocInterp() and destroyInterp() functions are defined in the TclEmbeddedInDll.h, the reason for using functions here rather than creating the Tcl_Interp directly is that it keeps the details about Tcl away from the DLL interface. If you create the interp here then you have to include tcl.h and then things get complicated when you try and use the DLL in another program.
The TclEmbeddedInDll.h and .cpp are shown next, the function fnTclEmbeddedInDll() is the one that is exported from the DLL - I'm using C linkage for this rather than C++ as it makes it easier to call the function from other languages IMHO.
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the TCLEMBEDDEDINDLL_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// TCLEMBEDDEDINDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef TCLEMBEDDEDINDLL_EXPORTS
#define TCLEMBEDDEDINDLL_API __declspec(dllexport)
#else
#define TCLEMBEDDEDINDLL_API __declspec(dllimport)
#endif
extern "C" {
TCLEMBEDDEDINDLL_API void fnTclEmbeddedInDll(void);
}
void allocInterp() ;
void destroyInterp() ;
// TclEmbeddedInDll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
extern "C" {
static Tcl_Interp *interp ;
// This is an example of an exported function.
TCLEMBEDDEDINDLL_API void fnTclEmbeddedInDll(void)
{
int code;
const char *result;
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
result = Tcl_GetString(Tcl_GetObjResult(interp));
}
}
void allocInterp()
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
void destroyInterp()
{
Tcl_DeleteInterp(interp);
}
The implementation of allocInterp() and destroyInterp() is very naive, no error checking is done.
Finally for the Dll the stdafx.h file ties it all together like this:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here
#include <tcl.h>
#include "TclEmbeddedInDll.h"

Why can't I create a MacOS framework with unresolved symbols?

I thought one feature of dynamic libraries (and by extension Apple's Mach-O Frameworks) was to leave some symbols (methods) undefined until the using application gets linked, but it appears all symbols have to be resolved for clang++ to successfully build a Framework.
For example, in building a framework for flight simulations, one might leave a C routine named aero undefined (but with an 'extern aero()' specification.) But XCode 4.2 refuses to build the framework, calling _aero an "undefined symbol."
Here's the header file included by both Objective-C and ANSI-C routines:
// FlightVehicleCAdapter_data.h
#ifndef FlightVehicleCAdapter_data_h
#define FlightVehicleCAdapter_data_h
#ifdef __cplusplus
external "C" {
#endif
extern void aero( void );
#ifdef __cplusplus
}
#endif
And here is where it gets called:
// FlightVehicleCAdapter.m
-(void) calcAero {
aero();
[self setBodyAeroForce_lb: [lsVector3 vectorFromScalarX:fv_data->f_aero_v.x
Y:fv_data->f_aero_v.y
Z:fv_data->f_aero_v.z]];
[self setBodyAeroMoment_ftlb:[lsVector3 vectorFromScalarX:fv_data->m_aero_v.x
Y:fv_data->m_aero_v.y
Z:fv_data->m_aero_v.z]];
}
I had hoped to be able to define the real aero() routine in the application that would link this framework, but when trying to build the framework itself the linker refuses to build it without a concrete aero() implementation:
Undefined symbols for architecture [i386|x86_64]:
"_aero", referenced from:
-[FlightVehicleCAdapter calcAero] in FlightVehicleCAdapter.o
So I then defined a dummy aero() routine:
// dummy_aero.c
// not showing fv_data structure definition for clarity
void aero(void){
fv_data->f_aero_v.x = 0.0;
fv_data->f_aero_v.y = 0.0;
fv_data->f_aero_v.z = 0.0;
fv_data->m_aero_v.x = 0.0;
fv_data->m_aero_v.y = 0.0;
fv_data->m_aero_v.z = 0.0;
}
This definition of aero() satisfies clang++ such that the Mach-O framework (dynamic library) is successfully built. But when I link the resulting framework with the application target which includes a non-trivial aero() routine, the framework's dummy aero() is being called instead of the application's aero().
You need to pass the -bundle_loader <executable> option to the linker, although I'm not sure that works for frameworks. Alternatively, you can use -undefined dynamic_lookup.
You need to do this for aero():
#ifdef __cplusplus
extern "C" {
#endif
extern void aero( void );
#ifdef __cplusplus
}
#endif
This makes sure the function is declared in C++ to have a C-resolvable name. C++ builds names differently than C does.
Note that then aero() can be linked at runtime.

Resources