I'm writing my first cmake file from scratch for a project that requires, amongst other things, ODE. If there are other bad practices that I'm doing, comments on that are also very welcome.
The makefile generation step with cmake is working, however in the build step with make, it complains:
Scanning dependencies of target ode_oscillex
[ 50%] Building CXX object CMakeFiles/ode_oscillex.dir/ode_oscillex.cpp.o
[100%] Linking CXX executable ode_oscillex
ld: library not found for -lGLU
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [ode_oscillex] Error 1
make[1]: *** [CMakeFiles/ode_oscillex.dir/all] Error 2
make: *** [all] Error 2
And I can't figure out what library -lGLU is supposed to be. Based on the Eclipse setup this project was previously set up in, I'm already adding X11, OpenGL and GLUT, and there shouldn't be anything else additionally. I'm setting this up on OS X.
My CMakeLists.txt is
cmake_minimum_required (VERSION 3.3)
set(PROJECT_NAME ode_oscillex)
set(TARGET ${PROJECT_NAME})
project (${PROJECT_NAME})
# Add manually built ODE library
set(ODE_PATH /Users/steve/ode-0.13.1)
set(ODE_INC_PATH ${ODE_PATH}/include)
set(ODE_LIB_PATH ${ODE_PATH}/ode/src/.libs)
set(DS_INC_PATH ${ODE_PATH}/include/drawstuff) # not sure why drawstuff needs subfolder to be specified, when ode doesn't...
set(DS_LIB_PATH ${ODE_PATH}/drawstuff/src/.libs)
include_directories(${ODE_INC_PATH} ${DS_INC_PATH})
link_directories(${ODE_LIB_PATH} ${DS_LIB_PATH})
### Add manually built Eigen
SET( EIGEN3_INCLUDE_DIR ../eigen3.1.4) # This is also sucky
include_directories(${EIGEN3_INCLUDE_DIR})
### Add Executable
add_executable(${TARGET} ${PROJECT_NAME}.cpp)
### Adding other required libraries
find_package(X11 REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
include_directories( ${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${X11_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${X11_LIBRARIES})
target_link_libraries(${TARGET} ode drawstuff GLU GL glut X11)
The problematic instructions for me are:
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${X11_LIBRARIES})
target_link_libraries(${TARGET} ode drawstuff GLU GL glut X11)
Generally, you shouldn't link "project", you need to link
"project artifacts" (i.e. "${TARGET}").
So try to rewrite this as follows:
target_link_libraries(${TARGET} <other required libraries like "ode"...> {OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${X11_LIBRARIES})
and remove the other line completely.
Generally when you called find_package()s above, those macros filled in corresponding variables which tell how to properly get proper compiler and linker flags (for OpenGL, GLUT etc respectively). So when you use appropriate variables in the target_link_libraries invocation, you can be sure that the linker flags and libraries, specific to a particular system.
On the the other hand, when you simply use target_link_libraries(<target> GLU GL glut...) you forcibly instruct cmake to link your <target> against those GL-related libraries, no matter if they installed in a particular system, nor how they are named there.
So in general you should prefer the first approach for external libraries, it's more reliable and generic.
Related
I am new to CMake. I can not resolve the flowing error. Could someone help me?
------------ERROR--------------
ld: library not found for -lnetcdf
collect2: error: ld returned 1 exit status
make[3]: *** [NUP] Error 1
make[2]: *** [CMakeFiles/NUP.dir/all] Error 2
make[1]: *** [CMakeFiles/NUP.dir/rule] Error 2
make: *** [NUP] Error 2
------------------- CMake File------------------
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
find_package(netcdf REQUIRED)
if(netcdf_FOUND)
include_directories(${INCLUDE_FILE})
set(
SOURCE_FILES
${PROJECT_BINARY_DIR} unpack.f90
)
add_executable(NUP ${SOURCE_FILES} )
target_link_libraries(NUP netcdf)
endif()
--------------unpack.f90-------------------
PROGRAM unpack_array
IMPLICIT NONE
INCLUDE 'netcdf.inc'
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307)
......
I am using MACOS Catalina. Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
If you're using find_package() to find NetCDF on your machine, you shouldn't need to manually specify the paths as you have. Let find_package do that for you.
Note: CMake doesn't ship with a Find Module for NetCDF, so you'll have to download one (like this one) from the internet. Then, you need to tell CMake where to locate this FindNetCDF.cmake file on your system using CMAKE_MODULE_PATH. Finally, you can use the NetCDF::NetCDF imported target to link NetCDF to your project's targets.
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
# Don't need this, you already enabled Fortran above in the 'project' call.
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
# Add the location of the 'FindNetCDF.cmake' file to your module path.
list(APPEND CMAKE_MODULE_PATH "/path/to/downloaded/find/module")
# Then, call find package for NetCDF.
find_package(NetCDF REQUIRED)
if(${NetCDF_FOUND})
# Don't need this if you use the imported target below.
include_directories(${INCLUDE_FILE})
# Don't provide directories with source file list.
set(SOURCE_FILES
${PROJECT_BINARY_DIR}
unpack.f90
)
add_executable(NUP ${SOURCE_FILES})
# Use the imported target to link netcdf instead.
target_link_libraries(NUP PRIVATE NetCDF::NetCDF)
endif()
As commented, there are other approaches to adding NetCDF to your CMake project. If you use a different find module, the syntax of the provided NetCDF CMake variables and imported targets may be slightly different. You'll have to examine the find module file itself.
In addition, you may instead use a CMake package configuration file (e.g. netCDFConfig.cmake) downloaded from the internet to add NetCDF to your project. In this case, you would still use find_package(), but you would specify the configuration file's location using CMAKE_PREFIX_PATH, rather than CMAKE_MODULE_PATH.
You can find detailed descriptions for each of these approaches in the CMake find_package() documentation. I highly encourage you spend some time to read it.
I have a problem with Connector/C++.
I'm using CLion as IDE and want to create a c++ program to interact with mysql database.
this is my CMakeList.txt file which i include c++/connector static and dynamic libraries in it:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Static Libraries
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libcrypto.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libssl.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8-static.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn-static.lib)
# Dynamic Link Libraries
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libcrypto-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libssl-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn-7-vs14.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn8-2-vs14.dll)
And i just include xdevapi.h header in my c++ source file like this:
#include <iostream>
#include <mysqlx/xdevapi.h>
using namespace std;
int main()
{
return 0;
}
And i run file in Release mode in clion and i receive these errors:
Error message i see in the clion console
====================[ Build | cpp_programming | Release ]=======================
"C:\Program Files\JetBrains\CLion 2019.3.2\bin\cmake\win\bin\cmake.exe" --build C:\Users\Kianoush\CLionProjects\cpp_programming\cmake-build-release --target cpp_programming -- -j 2
Scanning dependencies of target cpp_programming
[ 50%] Building CXX object CMakeFiles/cpp_programming.dir/main.cpp.obj
[100%] Linking CXX executable cpp_programming.exe
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x21): undefined reference to `mysqlx::abi2::r0::DbDoc::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x2c): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo[_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo]+0x87): undefined reference to `mysqlx::abi2::r0::string::Impl::to_utf8[abi:cxx11](mysqlx::abi2::r0::string const&)'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE[_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE]+0x20): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$.refptr._ZTVN6mysqlx4abi22r05DbDocE[.refptr._ZTVN6mysqlx4abi22r05DbDocE]+0x0): undefined reference to `vtable for mysqlx::abi2::r0::DbDoc'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\cpp_programming.dir\build.make:97: recipe for target 'cpp_programming.exe' failed
CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/cpp_programming.dir/all' failed
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/cpp_programming.dir/rule' failed
mingw32-make.exe[3]: *** [cpp_programming.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/cpp_programming.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/cpp_programming.dir/rule] Error 2
mingw32-make.exe: *** [cpp_programming] Error 2
Makefile:117: recipe for target 'cpp_programming' failed
Do i make mistakes in linking dll files or static files ?
What solution do you suggest ?
please help me, this take me in trouble for many days.
Full screen image
There are a couple of issues here.
You do not need to link all of these different libraries. You really only should require one mysqlcppconn library to be linked. To locate the library, try using find_library(), and use it for linking instead. Your CMake file should reduce to something like this:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Find the mysqlcppconn library.
find_library(mysqlcppconn_LIB
mysqlcppconn8
HINTS ${MYSQL_CPPCONN_DIR}/lib/vs14
# Static Libraries
target_link_libraries(${PROJECT_NAME} PUBLIC ${mysqlcppconn_LIB})
I'm not sure if you are using the ssl and crypto libraries, so add those back in if needed.
Your libraries (VisualC++) do not match the compiler (MinGW) you are using. To my knowledge, the MySQL Connector C++ downloads do not provide a MinGW set of libraries; they only provide libraries that are built with the Visual Studio compiler. Thus, you need to switch to use the VisualC++ compiler to use these libraries. Another option would be to download the MySQL source and try to build it with MinGW, but that may be more difficult.
Hope this helps!
I am using CLion editor (with CMake) for my C project,
I've never used an external library though,
my question is how do I link an external lib (for ex. libxml2) to my project?
I've seen some questions similar to this but none worked for me.
My project is compiled on Windows, and I have libxml .dll, include, and .lib files(binaries for Windows).
Edit: My CMakeLists.txt file after the answer suggested:
cmake_minimum_required(VERSION 3.2)
project(time_table)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES
course.c
course.h
day.h
defines.h
find_tables.c
find_tables.h
item.h
parse_info.c
parse_info.h
table.c
table.h
time_table.c grades.c grades.h)
link_libraries(C:/Users/Gal/Desktop/time_table/libxml2-2.7.8.win32/lib)
add_executable(time_table ${SOURCE_FILES})
target_link_libraries(time_table libxml2)
and this is what I get:
"C:\Program Files (x86)\JetBrains\CLion 1.1.1\bin\cmake\bin\cmake.exe" --build C:\Users\Gal\.clion11\system\cmake\generated\2eda76ff\2eda76ff\Debug --target time_table -- -j 8
[ 14%] Linking C executable time_table.exe
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -llibxml2
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [time_table.exe] Error 1
CMakeFiles\time_table.dir\build.make:225: recipe for target 'time_table.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/time_table.dir/all' failed
mingw32-make.exe[2]: *** [CMakeFiles/time_table.dir/all] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/time_table.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/time_table.dir/rule] Error 2
What is wrong?
There is a key work for libraries installed on your machine. <lib_name>_INCLUDE_DIR and <lib_name>_LIBRARIES once you have done find_package. This works for me.
find_package(LibXml2 REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<my_stuff> ${LIBXML2_INCLUDE_DIR})
add_executable(<my_exe> <my_source_files>)
target_link_libraries(<my_exe> ${LIBXML2_LIBRARIES})
---- Just a note for your curiosity ----
If you ever needed to build (1) a (static) library of your calculations, maybe reusable, and (2) an executable that uses that library and LIBXML2, do this.
find_package(LibXml2 REQUIRED)
# add a calculation library: file "lib<mycalc>.a"
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<your header files folder> ${LIBXML2_INCLUDE_DIR})
add_library(<mycalc> STATIC ${CMAKE_CURRENT_SOURCE_DIR}/<your src files folder>)
target_link_libraries(<mycalc> ${LIBXML2_LIBRARIES})
# add the executable: file <my_exe>
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<your header files folder> ${LIBXML2_INCLUDE_DIR})
add_executable(<my_exe> <your exe src files>)
target_link_libraries(<my_exe> <mycalc> ${LIBXML2_LIBRARIES})
Assume that full path to the library(.lib) can be expressed as
<library_dir>/<library_name>.lib
For compile executable, which uses this library, you need:
CMakeLists.txt:
link_libraries(<library_dir>)
add_excutable(<my_exe> ..)
target_link_libraries(<my_exe> <library_name>)
For use(run) compiled executable, you need to have <library_name>.dll either under one of the directory, listed in the PATH environment variable, or within same directory with executable.
there are 32bit and 64bit version of libxml2, to be found here.
you can put them below the PATH - or the C:\Windows directory.
With moderns CMake (version 3.2 or newer), it got much easier:
Search for the library. CMake has an according find module, thus it boils down to
find_package(LibXml2 REQUIRED)
Then you can link the library it to your target foo
target_link_libraries(foo PUBLIC LibXml2::LibXml2)
That's it folks! No fiddling around with headers and libraries, all done automatically.
If you have not installed the library, you might want to set LibXml2_DIR to the location where LibXml2 is located, i.e., by passing -DLibXml2_DIR=C:\software\libxml2 to your CMake call. That will help CMake finding LibXml2.
I am pretty new to cmake and here is my CMakeLists.txt file on my project's root directory
cmake_minimum_required (VERSION 2.6)
project (Tools C)
set(CMAKE_C_FLAGS "-ansi -pedantic -Wall -Werror")
include_directories("include")
SET_SOURCE_FILES_PROPERTIES(lib/xstr.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
SET_SOURCE_FILES_PROPERTIES(lib/counter.c PROPERTIES
OBJECT_DEPENDS "lib/xstr.c")
SET_SOURCE_FILES_PROPERTIES(lib/dynamic_array.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
SET_SOURCE_FILES_PROPERTIES(lib/list.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
add_executable(cat cat.c lib/xalloc.c lib/xfopen.c)
add_executable(counter counter.c lib/counter.c)
add_executable(darr dynamic_array.c lib/dynamic_array.c)
add_executable(linked list.c lib/list.c)
I keep c files that contains a main() function on my root directory. I keep other c files on {project_root}/lib directory.
My problem is that I am getting following error:
[ 33%] Built target cat
mingw32-make.exe[2]: *** No rule to make target 'lib/xstr.c', needed by 'CMakeFi
les/counter.dir/lib/counter.c.obj'. Stop.
CMakeFiles\Makefile2:94: recipe for target 'CMakeFiles/counter.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/counter.dir/all] Error 2
Makefile:75: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
What I want to achieve is to link{project_root}/cat.c with {project_root}/lib/xstr.c and {project_root}/lib/xalloc.c etc.
How can I achieve that?
You are taking cmake far too complicated! You have to set dependencies within targets, not source files. In your specific case, I suggest you add a few intermediate libraries. You can have them static so that the executable linking to them will not have problems in retrieving the linked library at runtime (the executable will integrate all the symbols and definitions he needs from the library).
Your code can be reduced as follow:
cmake_minimum_required (VERSION 2.8) # <<--2.6 is very outdated
project (Tools C)
set(CMAKE_C_FLAGS "-ansi -pedantic -Wall -Werror")
include_directories("include")
add_library(xalloc STATIC lib/xalloc.c)
add_library(xstr STATIC lib/xstr.c)
add_executable(cat cat.c lib/xfopen.c)
add_executable(counter counter.c lib/counter.c)
add_executable(darr dynamic_array.c lib/dynamic_array.c)
add_executable(linked list.c lib/list.c)
target_link_libraries(cat xalloc)
target_link_libraries(counter xstr xalloc) #xstr needs stuff from xalloc
target_link_libraries(darr xalloc)
target_link_libraries(linked xalloc)
Note: Are you sure you need darr and linked as executables? They look very much like a library... Also, having a file called counter.c and one lib/counter.c does not seem very safe (same for dynamic_array and list).
Some useful links:
http://www.cmake.org/cmake/help/v3.0/command/add_library.html
http://www.cmake.org/cmake/help/v3.0/command/target_link_libraries.html
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)
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.
By adding ws2_32.lib to the C_FLAGS, you are using it at compile time, and not link time. If you look at the error message, you can see it it treating the file as if it were a c++ source file: Cannot open source file: 'ws2_32.lib'. target_link_libraries(target ws2_32) should work.
You need to use the Target Link Libraries command. The target would be the executable you're building.
EDIT: You shouldn't specify the libs you're linking against in C_FLAGS. You can do something like TARGET_LINK_LIBRARIES(execName, ws_32, ...). I'm not 100% sure if you need the .lib. Been a while since I used CMake.