Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake adding libraries for Windows/Linux

Tags:

cmake

Visual Studio C++ 2008 / GCC 4.4.2

I have written a program to run on Linux and now I have to port my code to run on Windows. I have decided to use CMake as I want to keep the same build system for both platforms.

However, I need to link with some libraries for both platforms. In my CMakeLists.txt I have the following:

# 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)

However, when I compile on Visual Studio I get the following error:

fatal error C1083: Cannot open source file: 'ws2_32.lib': No such file or directory

What can I do to resolve this problem?

========= Edit In the top level 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)

In the subdirectory of client I have this CMakeLists.txt

# libray called client from client.c
ADD_LIBRARY(client client)

And in the subdirectory of test_clt where I create and link my executable.

# 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)
like image 445
ant2009 Avatar asked Feb 27 '10 16:02

ant2009


1 Answers

Disclaimer: My answer is of philosophical nature which should encourage you to avoid touching CMAKE_C_FLAGS directly. For the direct answer that just solves your problem look what Bill ( the lead architect of the CMake btw. ) wrote.

The thing about CMake is, that it lets you describe what you want to do without referring to a specific compiler or platform. What CMake does is building the compiler and linker flags from your usage of

  • include_directories
  • add_definitions
  • add_library
  • add_executable
  • target_link_libraries

If there are no external dependencies, other than the compiler itself, this is all you need. For external dependencies use find_package It defines a set of variables, like

  • find_package(SDL)

defines

  • SDL_INCLUDE_DIR
  • SDL_LIBRARY

for usage with respectively include_directories and target_link_libraries. CMake ships with a bunch of so called module files, like FindSDL.cmake and many others can be googled.

The next lower level is to use

  • find_path
  • find_library

which are used in the Find???.cmake modules itself.

The CMAKE_C_FLAGS variable is composed by CMake from these commands. Modifying it means you bypass CMake. There are cases, like for special optimization flags, you want to do this, but at this point all power and thus responsibility transfered from CMake to you.

like image 66
Maik Beckmann Avatar answered Oct 19 '22 16:10

Maik Beckmann