CMake为Windows / Linux添加库

时间:2010-02-27 16:49:53

标签: cmake

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 个答案:

答案 0 :(得分:20)

免责声明:我的回答是哲学性的,应该鼓励您避免直接触及CMAKE_C_FLAGS。对于直接回答,只是解决了你的问题,看看Bill(the lead architect of the CMake btw.)写的是什么。

关于CMake的事情是,它允许您在不参考特定编译器或平台的情况下描述您想要做的事情。 CMake所做的是根据您的

使用构建编译器和链接器标志
  • include_directories
  • add_definitions
  • add_library
  • add_executable
  • target_link_libraries

如果除了编译器本身之外没有外部依赖项,这就是您所需要的。对于外部依赖项使用   find_package 它定义了一组变量,比如

  • find_package(SDL)

定义

  • SDL_INCLUDE_DIR
  • SDL_LIBRARY

分别用于include_directories和target_link_libraries。 CMake附带了一堆所谓的模块文件,比如FindSDL.cmake,还有很多其他文件可以用Google搜索。

下一个较低级别是使用

  • find_path
  • find_library

在Find ???。cmake模块本身中使用。

CMAKE_C_FLAGS变量由CMake从这些命令组成。修改它意味着你绕过CMake。有些情况,比如特殊的优化标志,你想要做到这一点,但是在这一点上,所有的权力和责任都从CMake传递给你。

答案 1 :(得分:9)

通过将ws2_32.lib添加到C_FLAGS,您在编译时使用它,而不是链接时间。如果您查看错误消息,您可以看到它将文件视为c ++源文件:无法打开源文件:'ws2_32.lib'。 target_link_libraries(target ws2_32)应该可以工作。

答案 2 :(得分:6)

您需要使用Target Link Libraries命令。目标将是您正在构建的可执行文件。

编辑:您不应在C_FLAGS中指定要链接的库。您可以执行类似TARGET_LINK_LIBRARIES(execName,ws_32,...)的操作。如果你需要.lib,我不是100%肯定。我使用CMake已经有一段时间了。