CMake добавление библиотек для Windows / Linux - PullRequest
6 голосов
/ 27 февраля 2010

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)

Ответы [ 3 ]

20 голосов
/ 28 февраля 2010

Отказ от ответственности: Мой ответ носит философский характер, поэтому следует избегать прямого прикосновения к CMAKE_C_FLAGS. Чтобы получить прямой ответ, который просто решит вашу проблему, посмотрите, что написал Билл ( ведущий архитектор CMake btw. ).

Смысл CMake в том, что он позволяет вам описывать, что вы хотите делать, не обращаясь к конкретному компилятору или платформе. CMake создает флаги компилятора и компоновщика, используя

  • include_directories
  • add_definitions
  • add_library
  • add_executable
  • target_link_libraries

Если нет никаких внешних зависимостей, кроме самого компилятора, это все, что вам нужно. Для внешних зависимостей используйте find_package Он определяет набор переменных, например

определяет

  • SDL_INCLUDE_DIR
  • SDL_LIBRARY

для использования с соответственно include_directories и target_link_libraries. CMake поставляется с кучей так называемых файлов модулей, таких как FindSDL.cmake и многими другими, которые можно гуглить.

Следующий более низкий уровень должен использовать

  • find_path
  • find_library

, которые используются в самих модулях Find ???. Cmake.

Переменная CMAKE_C_FLAGS составлена ​​CMake из этих команд. Его изменение означает, что вы обходите CMake. В некоторых случаях, например, для специальных флагов оптимизации, вы хотите сделать это, но в этот момент вся мощь и, следовательно, ответственность передаются от CMake к вам.

9 голосов
/ 28 февраля 2010

Добавляя ws2_32.lib в C_FLAGS, вы используете его во время компиляции, а не во время компоновки. Если вы посмотрите на сообщение об ошибке, вы увидите, что он обрабатывает файл так, как если бы он был исходным файлом c ++: Не удается открыть исходный файл: 'ws2_32.lib'. target_link_libraries (target ws2_32) должен работать.

6 голосов
/ 27 февраля 2010

Вам необходимо использовать команду Target Link Libraries . Целью будет исполняемый файл, который вы создаете.

РЕДАКТИРОВАТЬ: Вы не должны указывать библиотеки, с которыми вы ссылаетесь в C_FLAGS. Вы можете сделать что-то вроде TARGET_LINK_LIBRARIES (execName, ws_32, ...). Я не уверен на 100%, если вам нужен .lib. Прошло некоторое время с тех пор, как я использовал CMake.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...