CMake为Windows/Linux添加库

ant*_*009 6 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)
Run Code Online (Sandbox Code Playgroud)

但是,当我在Visual Studio上编译时,我收到以下错误:

fatal error C1083: Cannot open source file: 'ws2_32.lib': No such file or directory
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能解决这个问题?

=========编辑在顶级目录中

# 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)
Run Code Online (Sandbox Code Playgroud)

在客户端的子目录中,我有这个CMakeLists.txt

# libray called client from client.c
ADD_LIBRARY(client client)
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

Mai*_*ann 20

免责声明:我的答案是哲学性的,应鼓励您避免直接触摸CMAKE_C_FLAGS.对于刚刚解决问题的直接答案,看看Bill(CMake的首席架构师)写道.

关于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转移到你.


小智 9

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


NG.*_*NG. 6

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

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