Visual Studio C++ 2008 / GCC 4.4.2
Я записал программу для работы Linux, и теперь я должен портировать свой код для работы Windows. Я решил использовать CMake, поскольку я хочу сохранить ту же систему сборки для обеих платформ.
Однако я должен связаться с некоторыми библиотеками для обеих платформ. В моем CMakeLists.txt у меня есть следующее:
# Compile with gcc c89 standard
IF(CMAKE_COMPILER_IS_GNUCXX)
MESSAGE(STATUS "GCC detected - Adding compiler flags")
SET(CMAKE_C_FLAGS "-pthread -ggdb -Wextra -Wall -pedantic -std=c89")
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
IF(WIN32)
SET(CMAKE_C_FLAGS "ws2_32.lib")
ENDIF(WIN32)
Однако, когда я компилирую на Visual Studio, я получаю следующую ошибку:
fatal error C1083: Cannot open source file: 'ws2_32.lib': No such file or directory
Что я могу сделать для разрешения этой проблемы?
========= Редактирование В высокоуровневом каталоге
# Project Client Server
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
# Name of project
PROJECT(CLIENT_SERVER)
# Compile with gcc c89 standard
IF(CMAKE_COMPILER_IS_GNUCXX)
MESSAGE(STATUS "GCC detected - Adding compiler flags")
SET(CMAKE_C_FLAGS "-pthread -ggdb -Wextra -Wall -pedantic -std=c89")
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
IF(WIN32)
SET(CMAKE_C_FLAGS "ws2_32")
ENDIF(WIN32)
# Includes
INCLUDE_DIRECTORIES(${CLIENT_SERVER_SOURCE_DIR}/cltsvr_ults)
INCLUDE_DIRECTORIES(${CLIENT_SERVER_SOURCE_DIR}/server)
INCLUDE_DIRECTORIES(${CLIENT_SERVER_SOURCE_DIR}/client)
# libraries
LINK_DIRECTORIES($CLIENT_SERVER/cltsvr_ults)
# Add subdirectories
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(server)
ADD_SUBDIRECTORY(cltsvr_ults)
ADD_SUBDIRECTORY(test_client)
ADD_SUBDIRECTORY(test_server)
В подкаталоге клиента у меня есть этот CMakeLists.txt
# libray called client from client.c
ADD_LIBRARY(client client)
И в подкаталоге test_clt, где я создаю и связываю свой исполняемый файл.
# Test client add executable
INCLUDE_DIRECTORIES($CLIENT_SERVER_SOURCE_DIR/client)
INCLUDE_DIRECTORIES($CLIENT_SERVER_SOURCE_DIR/cltsvr_ults)
# Link the library
LINK_DIRECTORIES($CLIENT_SERVER/client)
# Add the executable
ADD_EXECUTABLE(clt test_clt)
# Link the executable to the client library
IF(WIN32)
TARGET_LINK_LIBRARIES(clt client ws2_32)
ENDIF(WIN32)
Вам необходимо использовать команду Целевые библиотеки ссылок . Целью будет исполняемый файл, который вы создаете.
РЕДАКТИРОВАТЬ: Вы не должны указывать библиотеки, с которыми вы связываете, в C_FLAGS. Вы можете сделать что-то вроде TARGET_LINK_LIBRARIES (execName, ws_32, ...). Я не уверен на 100%, нужен ли вам файл .lib. Прошло много времени с тех пор, как я использовал CMake.
Отказ от ответственности: мой ответ философского характера, который должен побудить вас избегать прямого контакта с CMAKE_C_FLAGS. Чтобы получить прямой ответ, который решит вашу проблему, посмотрите, что написал Билл (, кстати, ведущий архитектор CMake. ).
Особенность CMake в том, что он позволяет описывать то, что вы хотите делать, без ссылки на конкретный компилятор или платформу.CMake создает флаги компилятора и компоновщика на основе использования вами
Если нет внешних зависимостей, кроме самого компилятора, это все, что вам нужно. Для внешних зависимостей используйте find_package . Он определяет набор переменных, например
определяет
для использования с соответствующими каталогами include_directories. и target_link_libraries. CMake поставляется с набором так называемых файлов модулей, таких как FindSDL.cmake и многие другие, которые можно найти в Google.
На следующем более низком уровне используется
, которые используются в самих модулях Find ???. Cmake.
Переменная CMAKE_C_FLAGS составляется CMake из этих команд. Его изменение означает, что вы обойдете CMake. В некоторых случаях, например, для специальных флагов оптимизации, вы хотите это сделать, но на этом этапе вся власть и, следовательно, ответственность передаются от CMake к вам.
Добавляя ws2_32.lib в C_FLAGS, вы используете его во время компиляции, а не во время компоновки. Если вы посмотрите на сообщение об ошибке, вы увидите, что он обрабатывает файл, как если бы это был исходный файл на C ++: Невозможно открыть исходный файл: 'ws2_32.lib'. target_link_libraries (target ws2_32) должен работать.