CubeGod CubeGod - 2 months ago 7
C++ Question

mingw32 can't link to library

Alright, so this is an interesting one that has been tested on two versions of mingw*, it's probably user error but google failed me.

I still can't build more complex projects correctly even though they ought to, for example - let's take the example included in the newton physics engine sdk, it's a pretty simple program.

first we build newton using the included makefile (as specifically recommended by a maintainer because cmake kept outputting broken makefiles), this is simple enough - it outputs a perfectly reasonable .a file.

these are the flags in the newton makefile

-c -Wall -Wno-strict-aliasing -DPTW32_BUILD -DPTW32_STATIC_LIB -D_NEWTON_STATIC_LIB -D_MINGW_32_VER -m32 -O2 -fpic -g -msse -msse3 -msse4 -mfpmath=sse -ffloat-store -ffast-math -freciprocal-math -funsafe-math-optimizations -fsingle-precision-constant -I$(DG_INCLUDED_PATH) -I$(DG_INCLUDED_PHYSICS_PATH) -I$(DG_INCLUDED_MESH_PATH) -I$(DG_INCLUDED_OPENCL_PATH)


however, if I then want to actually build the example then we get some slight problems.

g++ -march=core2 -o out.exe ex.cpp -g -m32 -lNewton 2>&1 | tee build.log


And what do we get? linker errors. undefined references everywhere because the name mangling doesn't seem to match

I'm probably just overlooking something obvious but I'm a tad lost as to what that obvious thing would be.

*g++.exe (TDM-2 mingw32) 4.4.1 and g++.exe (GCC) 5.3.0
so that would be TDM mingw g++ 4.4.1 and vanilla mingw 5.3.0

here's the makefile (you may notice some minor tweaks to the makefile from the default mingw32 makefile, that is because originally it didn't build at all until I fixed some whitespace problems):

#*******************************************************
#
# Newton game dynamics
# copy right by Julio Jerez 2002 - 2012
#
#*******************************************************
#
# Generic makefile
# this make file generate the libraries:
# dg, physics, and newton
#
#*******************************************************


# ******************************************************
#
# dg low level library
#
# ******************************************************
DG_INCLUDED_PATH = ../../source/core
DG_PATH = $(DG_INCLUDED_PATH)/
DG_SRCS = \
$(DG_PATH)dgAABBPolygonSoup.cpp \
$(DG_PATH)dgAsyncThread.cpp \
$(DG_PATH)dgConvexHull3d.cpp \
$(DG_PATH)dgConvexHull4d.cpp \
$(DG_PATH)dg.cpp \
$(DG_PATH)dgCRC.cpp \
$(DG_PATH)dgDebug.cpp \
$(DG_PATH)dgDelaunayTetrahedralization.cpp \
$(DG_PATH)dgGeneralMatrix.cpp \
$(DG_PATH)dgGeneralVector.cpp \
$(DG_PATH)dgGoogol.cpp \
$(DG_PATH)dgIntersections.cpp \
$(DG_PATH)dgMatrix.cpp \
$(DG_PATH)dgMemory.cpp \
$(DG_PATH)dgMutexThread.cpp \
$(DG_PATH)dgNode.cpp \
$(DG_PATH)dgPolygonSoupBuilder.cpp \
$(DG_PATH)dgPolyhedra.cpp \
$(DG_PATH)dgPolyhedraMassProperties.cpp \
$(DG_PATH)dgQuaternion.cpp \
$(DG_PATH)dgRandom.cpp \
$(DG_PATH)dgRefCounter.cpp \
$(DG_PATH)dgRef.cpp \
$(DG_PATH)dgSmallDeterminant.cpp \
$(DG_PATH)dgSPDMatrix.cpp \
$(DG_PATH)dgObb.cpp \
$(DG_PATH)dgThread.cpp \
$(DG_PATH)dgThreadHive.cpp \
$(DG_PATH)dgTree.cpp \
$(DG_PATH)dgTypes.cpp


# ******************************************************
#
# Physics engine files
#
# ******************************************************
DG_INCLUDED_PHYSICS_PATH = ../../source/physics
DG_PHYSICS_PATH = $(DG_INCLUDED_PHYSICS_PATH)/
DG_PHYSICS_SRCS = \
$(DG_PHYSICS_PATH)dgBody.cpp \
$(DG_PHYSICS_PATH)dgDynamicBody.cpp \
$(DG_PHYSICS_PATH)dgKinematicBody.cpp \
$(DG_PHYSICS_PATH)dgBallConstraint.cpp \
$(DG_PHYSICS_PATH)dgBilateralConstraint.cpp \
$(DG_PHYSICS_PATH)dgBody.cpp \
$(DG_PHYSICS_PATH)dgDynamicBody.cpp \
$(DG_PHYSICS_PATH)dgKinematicBody.cpp \
$(DG_PHYSICS_PATH)dgBodyMasterList.cpp \
$(DG_PHYSICS_PATH)dgBroadPhase.cpp \
$(DG_PHYSICS_PATH)dgCollisionBox.cpp \
$(DG_PHYSICS_PATH)dgCollisionBVH.cpp \
$(DG_PHYSICS_PATH)dgCollisionCapsule.cpp \
$(DG_PHYSICS_PATH)dgCollisionChamferCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionCompoundFractured.cpp \
$(DG_PHYSICS_PATH)dgCollisionCompound.cpp \
$(DG_PHYSICS_PATH)dgCollisionCone.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvex.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvexHull.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvexPolygon.cpp \
$(DG_PHYSICS_PATH)dgCollision.cpp \
$(DG_PHYSICS_PATH)dgCollisionCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableClothPatch.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableSolidMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionHeightField.cpp \
$(DG_PHYSICS_PATH)dgCollisionInstance.cpp \
$(DG_PHYSICS_PATH)dgCollisionMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionNull.cpp \
$(DG_PHYSICS_PATH)dgCollisionScene.cpp \
$(DG_PHYSICS_PATH)dgCollisionSphere.cpp \
$(DG_PHYSICS_PATH)dgCollisionTaperedCapsule.cpp \
$(DG_PHYSICS_PATH)dgCollisionTaperedCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionUserMesh.cpp \
$(DG_PHYSICS_PATH)dgConstraint.cpp \
$(DG_PHYSICS_PATH)dgContact.cpp \
$(DG_PHYSICS_PATH)dgCorkscrewConstraint.cpp \
$(DG_PHYSICS_PATH)dgDeformableBody.cpp \
$(DG_PHYSICS_PATH)dgDeformableContact.cpp \
$(DG_PHYSICS_PATH)dgHingeConstraint.cpp \
$(DG_PHYSICS_PATH)dgNarrowPhaseCollision.cpp \
$(DG_PHYSICS_PATH)dgSlidingConstraint.cpp \
$(DG_PHYSICS_PATH)dgUniversalConstraint.cpp \
$(DG_PHYSICS_PATH)dgUpVectorConstraint.cpp \
$(DG_PHYSICS_PATH)dgUserConstraint.cpp \
$(DG_PHYSICS_PATH)dgWorld.cpp \
$(DG_PHYSICS_PATH)dgDeformableBodiesUpdate.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicsParallelSolver.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicsSimpleSolver.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicUpdate.cpp


# ******************************************************
#
# mesh gemotry
#
# ******************************************************
DG_INCLUDED_MESH_PATH = ../../source/meshUtil
DG_MESH_PATH = $(DG_INCLUDED_MESH_PATH)/
DG_MESH_SRCS = \
$(DG_MESH_PATH)dgMeshEffect1.cpp \
$(DG_MESH_PATH)dgMeshEffect2.cpp \
$(DG_MESH_PATH)dgMeshEffect3.cpp \
$(DG_MESH_PATH)dgMeshEffect4.cpp \
$(DG_MESH_PATH)dgMeshEffect5.cpp \
$(DG_MESH_PATH)dgMeshEffect6.cpp

# ******************************************************
#
# open cl
#
# ******************************************************
DG_INCLUDED_OPENCL_PATH = ../../source/openCL
DG_OPENCL_PATH = $(DG_INCLUDED_OPENCL_PATH)/
#DG_OPENCL_SRCS = \
# $(DG_OPENCL_PATH)dgOpencl.cpp \
# $(DG_OPENCL_PATH)dgOpenclInstance.cpp \
# $(DG_OPENCL_PATH)dgOpenclBroadPhase.cpp



# ******************************************************
#
# Newton engine files
#g++ -shared -o libNewton.dll libNewton.a
# ******************************************************
DG_INCLUDED_NEWTON_PATH = ../../source/newton
DG_NEWTON_PATH = $(DG_INCLUDED_NEWTON_PATH)/
DG_NEWTON_SRCS = \
$(DG_NEWTON_PATH)Newton.cpp \
$(DG_NEWTON_PATH)NewtonClass.cpp

# ******************************************************
#
# Allsource files
#
# ******************************************************
ALL_SRC_FILES = $(DG_SRCS) $(DG_PHYSICS_SRCS) $(DG_OPENCL_SRCS) $(DG_MESH_SRCS) $(DG_NEWTON_SRCS)
DG_OBJ_FILES = $(ALL_SRC_FILES:.cpp=.o)

COMPILER = gcc

# mingw options gcc 4.4.2
#CPU_FLAGS = -m32 -O0 -fPIC -g -msse -msse2 -mfpmath=sse
#CPU_FLAGS = -m32 -O0 -fPIC -g -msse -msse4.1 -mfpmath=sse
#CPU_FLAGS = -m32 -O2 -fpic -g -msse -msse4.1 -mfpmath=sse -ffloat-store -ffast-math -freciprocal-math -funsafe-math-optimizations -fsingle-precision-constant
CPU_FLAGS = -m32 -O2 -fpic -g -msse -msse3 -msse4 -mfpmath=sse -ffloat-store -ffast-math -freciprocal-math -funsafe-math-optimizations -fsingle-precision-constant

FLAGS = -Wall -Wno-strict-aliasing -DPTW32_BUILD -DPTW32_STATIC_LIB -D_NEWTON_STATIC_LIB -D_MINGW_32_VER $(CPU_FLAGS) -I$(DG_INCLUDED_PATH) -I$(DG_INCLUDED_PHYSICS_PATH) -I$(DG_INCLUDED_MESH_PATH) -I$(DG_INCLUDED_OPENCL_PATH)

.SUFFIXES : .o .cpp
.cpp.o :
$(COMPILER) $(FLAGS) -o $@ $<

# main target
engine : libNewton.a


# clean all objects target
clean :
rm $(DG_OBJ_FILES)
touch $(ALL_SRC_FILES)

# libraries targets
libNewton.a : $(DG_OBJ_FILES)
ar r $@ $?
strip -g -S -d -v libNewton.a -o libNewton.a
cp libNewton.a ../../../packages/mingw32/libNewton.a
cp ../../source/newton/Newton.h ../../../packages/mingw32/Newton.h
# $(COMPILER) -shared -Wl,-soname,libNewton.dll $? -o libNewton.dll
# cp libNewton.dll ../../../packages/mingw32/libNewton.dll
#sudo cp libNewton.dll /usr/lib


and the linker errors I get if I build without -c (all of the newton functionality is undefined, this is not a surprise to anyone since that's what -c is meant to do but the fact that it breaks for even the simplest of test cases implies something is wrong)

C:\Users\Thunder\AppData\Local\Temp\cchfxWSh.o: In function `Z20CreateBackgroundBodyP11NewtonWorld':
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:17: undefined reference to `_imp__NewtonCreateTreeCollision'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:20: undefined reference to `_imp__NewtonTreeCollisionBeginBuild'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:23: undefined reference to `_imp__NewtonTreeCollisionAddFace'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:26: undefined reference to `_imp__NewtonTreeCollisionEndBuild'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:29: undefined reference to `dGetIdentityMatrix()'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:30: undefined reference to `_imp__NewtonCreateDynamicBody'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:33: undefined reference to `_imp__NewtonDestroyCollision'
C:\Users\Thunder\AppData\Local\Temp\cchfxWSh.o: In function `ApplyGravity':
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:45: undefined reference to `_imp__NewtonBodyGetMassMatrix'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:47: undefined reference to `_imp__NewtonBodySetForce'
C:\Users\Thunder\AppData\Local\Temp\cchfxWSh.o: In function `Z18CreateFreeFallBallP11NewtonWorld':
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:53: undefined reference to `_imp__NewtonCreateSphere'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:56: undefined reference to `dGetIdentityMatrix()'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:58: undefined reference to `_imp__NewtonCreateDynamicBody'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:61: undefined reference to `_imp__NewtonBodySetForceAndTorqueCallback'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:65: undefined reference to `_imp__NewtonBodySetMassProperties'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:68: undefined reference to `_imp__NewtonBodySetLinearDamping'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:71: undefined reference to `_imp__NewtonDestroyCollision'
C:\Users\Thunder\AppData\Local\Temp\cchfxWSh.o: In function `main':
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:79: undefined reference to `_imp__NewtonCreate'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:86: undefined reference to `_imp__NewtonInvalidateCache'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:90: undefined reference to `_imp__NewtonUpdate'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:93: undefined reference to `_imp__NewtonBodyGetMatrix'
C:\Users\Thunder\Documents\projects\libproto framework\src/ex.cpp:98: undefined reference to `_imp__NewtonDestroy'
collect2.exe: error: ld returned 1 exit status

Answer

Your problem is simple.

the -c switch of gcc does only compilation step without linking and producing an executable module.

The fact that you instructed gcc to write an output to a file with .exe extension makes no special meaning to the gcc.

So you are just trying to execute the object file, so Winodws complains.


I assume that you mistyped the last arguments in the commands shown and they should read as hello_world.c