1

I am trying to build a c project with CMake using Visual Studio 14 however I cannot override the compiler flags being set by CMake which are causing project to fail to build. I am using this method in my CMakeLists.txt file

set(flags /nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_)
set(CMAKE_C_FLAGS ${flags})
set(rc_flags /l0x809)
set(CMAKE_RC_FLAGS ${rc_flags})
set(linker_flags /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /DLL)
set(CMAKE_LINKER_FLAGS ${linker_flags})

Any help would greatly be appreciated!

Edit: full example of main CMakeLists.txt is here

cmake_minimum_required(VERSION 3.4)
project(cuism C)

set(WINDOWS_SDK_INCLUDES "C:/Program Files\ (x86)/Microsoft\  SDKs/Windows/v7.1A/Include/")
set(WINDOWS_SDK_LIBRARIES "C:/Program Files\ (x86)/Microsoft\ SDKs/Windows/v7.1A/Lib")
set(WSOCK "WSock32.lib")
set(ODBC "odbc32.lib")
set(ODBCCP "odbccp32.lib")

set(includeDir "${CMAKE_SOURCE_DIR}/include/")
set(resourceDir "${CMAKE_SOURCE_DIR}/resources/")


include_directories(
    ${includeDir}
    ${resourceDir}
)

set(CMAKE_LIBRARY_PATH ${WINDOWS_SDK_LIBRARIES})
set(CMAKE_INCLUDE_PATH ${WINDOWS_SDK_INCLUDES})


set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_" )
set(CMAKE_C_FLAGS ${flags})

set(rc_flags /l0x809)
set(CMAKE_RC_FLAGS ${rc_flags})

set(linker_flags /NOLOGO /SUBSYSTEM:console /DLL)
set(CMAKE_LINKER_FLAGS ${linker_flags})

message(c flags are ${CMAKE_C_FLAGS})
message(rc flags are ${CMAKE_RC_FLAGS})
message(linker flags are ${CMAKE_LINKER_FLAGS})
message(linker EXE flags are ${CMAKE_EXE_LINKER_FLAGS})

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)


ADD_SUBDIRECTORY(cuimbct)
ADD_SUBDIRECTORY(cuimb)
ADD_SUBDIRECTORY(cuidll)

Each sudbdirectory has a CMakeLists.txt similar to this one

set(src cuimb.c "${includeDir}port.c" cuimben.c cuimb.rc)
add_library(cuimb SHARED ${src})
target_link_libraries(cuimb ${WSOCK} ${ODBC} ${ODBCCP})

Error is during linking stage due to error code LNK2019

simon-p-r
  • 3,623
  • 2
  • 20
  • 35
  • What did you try so far? When the above code is behind the `project()` command, I would say it should work. For more details what and how it works for me see e.g. [here](http://stackoverflow.com/questions/33828855/is-cmake-set-variable-recursive). – Florian Jun 29 '16 at 11:13
  • Tried both add_definitions() and add_compile_options() methods – simon-p-r Jun 29 '16 at 11:28
  • Just a guess: have you tried to add quotes to the code above like `set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_")`? – Florian Jun 29 '16 at 11:38
  • Yes I have tried that – simon-p-r Jun 29 '16 at 12:05
  • 2
    Please, provide [mcve] with **precise error message**. Your current code has definite problem that it doesn't enclose compiler flags **together** into quotes. Position of `project()` call is critical, but you don't show it. – Tsyvarev Jun 29 '16 at 12:21
  • @Tsyvarev I have added the CMakeLists.txt – simon-p-r Jun 29 '16 at 12:38
  • Ok, so the problem on the **link** stage, not on the *build* one. Probably, because your setting for `CMAKE_LINKER_FLAGS` has no effect: there is **no common linker flags for all types of targets**. E.g., for shared libraries variable [CMAKE_SHARED_LINKER_FLAGS](https://cmake.org/cmake/help/v3.0/variable/CMAKE_SHARED_LINKER_FLAGS.html) is used. – Tsyvarev Jun 29 '16 at 12:53
  • Thanks @Tsyvarev I will try that – simon-p-r Jun 29 '16 at 13:06

1 Answers1

1

I've given your code a try and - with some small modifications - could successfully apply those compiler/linker options. It includes the changes I and @Tsyvarev have suggested (quotes and use of CMAKE_SHARED_LINKER_FLAGS) and I've removed the static references to Windows SDK 7.1. This can be set with the -T toolset option:

> cmake -H"." -B"buildWin7" -T"v140_xp" -G"Visual Studio 14 2015" 
...

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(cuism C)

set(includeDir "${CMAKE_SOURCE_DIR}/include/")
set(resourceDir "${CMAKE_SOURCE_DIR}/resources/")

include_directories(
    ${includeDir}
    ${resourceDir}
)

set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2" )
set(CMAKE_C_FLAGS "${flags}")

set(rc_flags "/l0x809")
set(CMAKE_RC_FLAGS "${rc_flags}")

set(linker_flags "/NOLOGO /SUBSYSTEM:console /DLL")
set(CMAKE_SHARED_LINKER_FLAGS "${linker_flags}")

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

...

cuimb\CMakeLists.txt

...

add_library(cuimb SHARED ${src})
target_link_libraries(cuimb wsock32 odbc32 odbccp32)

Recommendation

To keep your CMake script code clean, you should move all of the compiler/linker options to a toolchain file. And I've added some of the options I have normally defined there. Plus I reduced it to a single configuration MyDebug (just Debug would append other Debug options), because your options don't seem to be made for Release.

> cmake -H"." -B "buildWin7" -DCMAKE_TOOLCHAIN_FILE:PATH="VS2015Toolchain.cmake" -G"Visual Studio 14 2015" 
...

VS2015Toolchain.cmake

if (NOT CMAKE_GENERATOR_TOOLSET)
    set(CMAKE_GENERATOR_TOOLSET "v140_xp" CACHE INTERNAL "")
endif()

set(CMAKE_CONFIGURATION_TYPES "MyDebug" CACHE INTERNAL "")

# NOTE: Standard is a console app. If you need a windows app, 
#       use WIN32 define in add_executable
set(CMAKE_WIN32_EXECUTABLE 0 CACHE INTERNAL "")

set(CMAKE_C_FLAGS "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /W4" CACHE INTERNAL "")
set(CMAKE_RC_FLAGS "/l0x809" CACHE INTERNAL "")
set(
    CMAKE_SHARED_LINKER_FLAGS 
    "/NOLOGO /SAFESEH:NO /INCREMENTAL:NO /debug" 
    CACHE INTERNAL ""
)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "")
Florian
  • 39,996
  • 9
  • 133
  • 149
  • Thanks @Florian I would use this approach once I make application cross platform and have more than one tool chain. – simon-p-r Jun 30 '16 at 12:31
  • @simon-p-r You're welcome. Just keep in mind that `CMAKE_GENERATOR_TOOLSET` can only be set in the toolchain or via the `-T` command line parameter. And be aware of your active build configuration. E.g. `CMAKE_C_FLAGS_DEBUG` and friends are appended to `CMAKE_C_FLAGS`. – Florian Jun 30 '16 at 12:37
  • Your answer taught me multiple new things, not the least of which is that CMake has some options that aren't displayed unless you CMake --help-full (e.g. the -B option) EDIT: Actually, -B seems to be a CPack option. I guess I don't understand your usage of the -H and -B flags. -H is for help and -B isn't listed as a CMake option. – Rich von Lehe Sep 23 '16 at 21:22
  • @RichvonLehe Yes, `-B` and `-H` options are internally used by CMake. So they are - even as they are widely used and very useful - unofficial and not documented (see also [Issue 0007872: Documentation missing "-H" and "-B" command line options](https://cmake.org/Bug/view.php?id=7872)). Please see [here](http://stackoverflow.com/questions/30999130/cmake-build-multiple-targets-in-different-build-directories) for an example without the use of `-B` and `-H`. – Florian Sep 25 '16 at 18:43