【发布时间】:2017-02-20 07:10:43
【问题描述】:
这是一个解释起来有点复杂的问题,而且它在技术上涉及很多代码,所以我会尽力解释它。如果事实证明我需要发布代码,我会发布人们要求的部分,因为他们要求它,以避免过于混乱。
我也很确定我知道一般问题是什么,只是不知道如何解决它或弄清楚如何解决它。其中大部分涉及我知之甚少的东西,而且由于其他 SO 问题和无数的 Google 搜索等,以及将它们拼凑在一起的大量试验和错误,我才走到了现在的位置。
我将首先声明我认为问题在于我正在做的部分工作是编译为 32 位的,而一部分是 64 位的。希望这是准确的,它将帮助您在正确的地方集中注意力阅读本文。
基本上,我有一个使用 CMake 和 Visual Studio 12 2013 在 Windows 上构建和编译的 C++ 代码库,以及一个使用 gfortran 在 Linux 上构建和编译的 FORTRAN 代码库。最终目标是使 FORTRAN 成为某种可以被 C++ 代码使用的库,并通过 CMake 让所有这些都很好地工作,这样当前的 C++ 代码开发人员就不必做任何额外或烦人的事情了使用它。
到目前为止,我已经有了一个正在试验的小型示例代码库,一旦我得到它,我将使用相同的概念来使实际代码工作。
我的意思是一切都很好,但是当我实际运行生成的程序时,我收到以下错误:
The application was unable to start correctly (0xc000007b). Click OK to close the application.
关于出了什么问题的任何想法(Google 结果似乎暗示可执行文件和库分别是 32 位和 64 位,反之亦然),以及如何解决它?
请注意,这一切都是在 Windows 上构建的,只是 FORTRAN 是在 Makefile 中使用 gfortran 构建的,它是从 CMake 调用的。我实际上并不确切知道 CMake 是如何调用make 的。我确实安装了 MSYS2,在进入这个阶段之前我已经使用它了,但我不知道 CMake 是如何进行调用的。如果你知道我是怎么知道的,请告诉我!
在这里,我将发布我用来编译所有内容的写得很糟糕的 CMakeLists.txt 和 Makefile。如果您想查看其他详细信息,请告诉我!此外,由于有这么多活动部件,我不确定在软件版本方面提到哪些东西真正相关。如果您有什么想知道的,请告诉我。
再次,我为我所有的笨拙道歉——这不是我的强项。
Makefile: (我的编辑器将制表符更改为空格)
FC=gfortran -g
CC=g++ -g
DLL_SRC_DIR=.
BUILD_DIR=build
all:
$(FC) -c $(DLL_SRC_DIR)/fdll.f90 -o $(BUILD_DIR)/fdll.o
$(CC) -c -DBUILDING_C_DLL $(DLL_SRC_DIR)/cdll.cpp -o $(BUILD_DIR)/cdll.o
$(CC) -shared -o $(BUILD_DIR)/libcdll.dll $(BUILD_DIR)/cdll.o $(BUILD_DIR)/fdll.o -Wl,--out-implib,$(BUILD_DIR)/libcdll.a,--output-def,$(BUILD_DIR)/libcdll.def -lgfortran
/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0/VC/BIN/lib /MACHINE:x86 /DEF:$(BUILD_DIR)\\libcdll.def /OUT:$(BUILD_DIR)\\libcdll.lib
clean:
rm -f $(BUILD_DIR)/*
CMakeLists.txt
project(cmake_test)
add_executable(cprog cprog.cpp)
find_path(FORTRAN_DIR NAMES cdll.cpp fdll.f90 Makefile PATHS ../source)
execute_process(COMMAND make
WORKING_DIRECTORY ${FORTRAN_DIR})
set(FORTRAN_LIB ${FORTRAN_DIR}/build/libcdll.lib)
include_directories(${FORTRAN_DIR})
set(MY_LIBRARIES ${MY_LIBRARIES} ${FORTRAN_LIB})
target_link_libraries(cprog ${MY_LIBRARIES})
# See: http://stackoverflow.com/questions/10671916/how-to-copy-dll-files-into-the-same-folder-as-the-executable-using-cmake
add_custom_command(TARGET cprog POST_BUILD # Adds a post-build event to cprog
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake -E copy_if_different..."
"${FORTRAN_DIR}/build/libcdll.dll" # <--this is the file to copy
$<TARGET_FILE_DIR:cprog>) # <--this is where to copy it
【问题讨论】:
-
这并不完全清楚(也许我没有彻底阅读这个问题)——你不是在尝试将 Windows 可执行文件链接到 Linux 库吗?
-
好吧,您可能想澄清您的问题,看来我并不是唯一一个最初感到困惑的人。至于您评论的其余部分,如果您有材料要添加到您的问题中添加它,请不要在 cmets 中提出补充问题,它们太难阅读了。
-
Lahey 曾经支持 gfortran 和 Visual Studio 之间的接口。一些商业 Fortran 产品可与 Visual Studio 一起使用。否则,建议坚持使用 g++/gfortran 的单一组合发行版(可能是 MinGW,如果您已经选择了它,或者您不能接受 cygwin 许可条款)。无论哪种情况,单个 .exe 都必须完全是 32 位或 64 位模式。
-
顺便说一句,这是 Fortran。它已经正式使用了超过四分之一个世纪。请参阅 en.wikipedia.org/wiki/Fortran 下的 Fortran 90 条目
-
您的 makefile 为 DLL 的导入库指定 /machine:x86,即 32 位。你是用 gfortran 编译成 32 位还是 64 位?您的操作系统是 64 位的,并且 gfortran 命令行中没有
-m 32,这让我怀疑您正在为 64 位编译 DLL。您是在构建 32 位还是 64 位 EXE?您可以使用dumpbin /headers filename.xxx来确定EXE 或DLL 的位数。您要构建什么位数的 EXE/DLL?你是如何调用cmake的?无法从您发布的信息中确定这些内容。
标签: c++ visual-studio dll cmake fortran