mingw32 无法 link 到库

mingw32 can't link to library

好吧,这是一个有趣的问题,已经在两个版本的 mingw* 上进行了测试,这可能是用户错误,但 google 让我失望了。

我仍然无法正确构建更复杂的项目,即使它们应该如此,例如 - 让我们以牛顿物理引擎 sdk 中包含的示例为例,它是一个非常简单的程序。

首先我们使用包含的 makefile 构建 newton(正如维护者特别推荐的那样,因为 cmake 不断输出损坏的 makefile),这很简单 - 它输出一个完全合理的 .a 文件。

这些是 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)

但是,如果我想实际构建示例,那么我们会遇到一些小问题。

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

我们得到了什么?链接器错误。到处都是未定义的引用,因为名称修改似乎不匹配

我可能只是忽略了一些明显的东西,但我有点迷失了那个明显的东西是什么。

*g++.exe (TDM-2 mingw32) 4.4.1 和 g++.exe (GCC) 5.3.0 所以那将是 TDM mingw g++ 4.4.1 和 vanilla mingw 5.3.0

这是 makefile(您可能会注意到默认 mingw32 makefile 对 makefile 的一些细微调整,这是因为最初它根本没有构建,直到我修复了一些空白问题):

#*******************************************************
#
# 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

以及如果我在没有 -c 的情况下构建时出现的链接器错误(所有牛顿功能都未定义,这对任何人来说都不足为奇,因为这就是 -c 的本意,但事实上它甚至会中断最简单的测试用例暗示有问题)

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

你的问题很简单。

gcc-c 开关仅执行编译步骤,而不链接和生成可执行模块。

您指示 gcc 将输出写入扩展名为 .exe 的文件这一事实对 gcc 没有特殊意义。

所以你只是想执行目标文件,所以 Winodws 报错。


我假设您在显示的命令中输错了最后一个参数,它们应该读作 hello_world.c

好吧,我终于缩小了无法编译或link任何东西的根本原因。

原因是我已经 link 成功编写的两个库被编写为与 C++98 兼容 - 这些构建和 link 很好。 然而,我的框架也使用的 newton dynamics 和 box2D [这是我在移植时遇到的问题] 都依赖于 C++11 或更高版本。

这花了一段时间才找到,因为我从来没有想过问题可能只出在工具链的 C++11 子集上,当我注意到我什至无法构建最简单的 c++11 项目(仅使用 nullptr 的项目),如果我使用的是 g++ 4.5 或更早版本,这是可以预期的,但它自 4.6 及更高版本以来就可用。

因此我们开始进行故障排除,我使用 hello world 应用程序(非常标准,但无论如何都包含代码)并使用

构建它
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

g++.exe -Wall -fexceptions -g -O2 -c gcc530_sanitytest\main.cpp -o obj\Debug\main.o

这个效果很好。

如果我们再尝试

g++.exe -Wall -fexceptions -std=c++11 -g -O2 -c gcc530_sanitytest\main.cpp -o obj\Debug\main.o

然后我们得到大量错误

即:

||=== Build: Debug in gcc530_sanitytest (compiler: GNU GCC Compiler) ===|
c:\mingw\include\sys\stat.h|173|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: '_ino_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: '_mode_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: '_off_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|173|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: '_ino_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: '_mode_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: '_off_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|180|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: '_ino_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: '_mode_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: '__off64_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|188|error: 'time_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '_ino_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '_mode_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '_dev_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '__off64_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '__time64_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '__time64_t' does not name a type|
c:\mingw\include\sys\stat.h|195|error: '__time64_t' does not name a type|
c:\mingw\include\io.h|335|error: 'time_t' does not name a type|
c:\mingw\include\io.h|335|error: 'time_t' does not name a type|
c:\mingw\include\io.h|335|error: 'time_t' does not name a type|
c:\mingw\include\io.h|336|error: 'time_t' does not name a type|
c:\mingw\include\io.h|336|error: 'time_t' does not name a type|
c:\mingw\include\io.h|336|error: 'time_t' does not name a type|
c:\mingw\include\io.h|362|error: '__time64_t' does not name a type|
c:\mingw\include\io.h|362|error: '__time64_t' does not name a type|
c:\mingw\include\io.h|362|error: '__time64_t' does not name a type|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|146|error: '::fwide' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|153|error: '::mbsinit' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|198|error: '::wmemcmp' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|199|error: '::wmemcpy' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|200|error: '::wmemmove' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|201|error: '::wmemset' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|208|error: '::wmemchr' has not been declared|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar||In function 'wchar_t* std::wmemchr(wchar_t*, wchar_t, std::size_t)':|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|229|error: invalid conversion from 'const wchar_t*' to 'wchar_t*' [-fpermissive]|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\cwchar|228|note:   initializing argument 1 of 'wchar_t* std::wmemchr(wchar_t*, wchar_t, std::size_t)'|
c:\mingw\lib\gcc\mingw32.3.0\include\c++\bits\char_traits.h|353|error: 'wmemcmp' was not declared in this scope|
||More errors follow but not being shown.|
||Edit the max errors limit in compiler options...|
||=== Build failed: 50 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

因此得出明显的结论,即构建环境已损坏,就我而言,这很好地回答了这个问题 - 仍然给 serge 确认的答案,因为 reminding/educating 我在什么 - c 确实如此(尽管这不是根本原因)。

也许这就是 mingw 设计的工作方式,但后来它被设计破坏了(无论如何我怀疑这一点,我看不出他们故意破坏 C++11 的原因)