Переносимое программирование — сбой соединения с Win32, но соединение с linux

Я работаю над переносным приложением, которое работает под Linux и Windows.
Я кросс-компиляции в системе Linux, используя cmake, gcc 4.4.4 и mingw-gcc 4.4.4.

Я могу без проблем скомпилировать и связать версию своего приложения для Linux. Однако, если я пытаюсь кросс-компилировать для Windows, приложение компилируется нормально, но компоновщик заканчивается ошибкой «неопределенная ссылка».

Вот выдержка из исходного кода:

Заголовочный файл (fileactions.hpp):

class FileActions {
bool CopyFile(const std::string &source, const std::string &destination);
bool CopyFile(const boost::filesystem::path& source, const boost::filesystem::path& destination);
};

Исходный файл (fileactions.cpp):

bool FileActions::CopyFile(const boost::filesystem::path& source, const boost::filesystem::path& destination)
{
return this->CopyFile(source.string(), destination.string());
}

bool FileActions::CopyFile(const std::string &source, const std::string &destination)
{
/* ... do something */
}

Выдержка из кода, который вызывает ошибку ссылки:

bool TmmProject::PostImportOldVersion(int old_version) {
namespace fs = boost::filesystem;
FileActions dd;

fs::path backup;
/* fs::path _location; // This is actually defined in the class declaration */

/* do something more */

if( !dd.CopyFile(_location, backup ) ) {  <-- I get the linker error at this line
log << "<span style=\"color:red\">Failed to create backup file. Stopping import </span><br>";
log << "The error message is: " << dd.GetError() << "<br>";
_last_error = log.str();
return false;
}

/* do something more */
}

Как уже говорилось, приведенный выше код прекрасно работает, если я компилирую для системы linux, но не работает, если я использую mingw для компиляции для Win32. Точная ошибка компоновщика:

CMakeFiles/tmm.dir/tmmproject.cpp.obj:/.../tmm/tmmproject.cpp:408: undefined reference
to 'tmm::fileActions::CopyFileA(
boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const &,
boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const &
)'

Файл fileactions.cpp связан со статическим libray libtmm. Класс TmmProject, который вызывает ошибку, является частью той же библиотеки.

CMakeLists.txt, который используется для ссылки на библиотеку, выглядит следующим образом (сокращенно):

include_directories( ... )
link_directories ( ${Boost_LIBRARY_DIRS} )

file(GLOB TMM_HEADERS *.h)
file(GLOB TMM_SOURCES *.cpp)

set ( TMM_LIBS
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
m
)

IF( WIN32 )
ADD_LIBRARY( tmm STATIC ${TMM_SOURCES} )
target_link_libraries( tmm ${TMM_LIBS} )
# I found the following option from a similar quesiton in this froum, but
# actually it does not seem to make any difference
SET_TARGET_PROPERTIES( tmm PROPERTIES LINK_FLAGS -Wl,--export-all-symbols )
ELSE( WIN32 )
ADD_LIBRARY( tmm SHARED ${TMM_SOURCES} )
target_link_libraries( tmm ${TMM_LIBS} )
INSTALL(TARGETS tmm DESTINATION lib)
ENDIF( WIN32 )

Есть ли у кого-нибудь идея, в чем может быть причина неудачи?

1

Решение

Microsoft использует много определений в своем заголовке для поддержки юникода. В вашем случае имя OpenFile Кажется, также определено быть Eiter OpenFileA или если вы переключитесь на Unicode, это будет OpenFileW,
Чтобы избавиться от этой проблемы, добавьте это после включения заголовков от Microsoft.

#undef CopyFile

Вы можете, конечно, упаковать его в #ifdef ограничить это платформой Microsoft.

1

Другие решения

Microsoft использует макросы для того, чтобы приложения могли использовать формы UNICODE (широкий или 16-разрядный символ) и ASCII (8-разрядный символ) для системных вызовов. Так что где-то в Windows.h есть что-то вроде:

#if UNICODE
#define CopyFile CopyFileW
#else
#define CopyFile CopyFileA
#endif

Во время использования #undef CopyFile (и аналогичные) будет работать, я бы посоветовал вам избегать <windows.h> если это НЕОБХОДИМО АБСОЛЮТНО — если нужно, попробуйте ограничить его небольшим числом (в идеале одним) исходным файлом, который фактически напрямую взаимодействует с Widnows.

1

По вопросам рекламы [email protected]