Undefinition of MSVC definition _MBCS and definition of _UNICODE not possible calling cmake from command line [duplicate] - visual-studio-2010

This question already has answers here:
How to define a C++ preprocessor macro through the command line with CMake?
(4 answers)
Closed 3 years ago.
I want to generate a visual studio project 2010 with cmake from a CMakeLists.txt. Basically this works fine. However, one detail lead to my following observation:
The default character set for the generated visual studio project is 'Multibyte Character'. I want to change it to Unicode. As far as I found out, I need to define either _UNICODE or UNICODE, but I also need to undefine _MBCS. This works out, if I put it in the CMakeLists.txt, but I can't get it working, if I want to set these definitions by command line:
CMakeList.txt, works fine:
add_definitions ( -D_UNICODE )
remove_definitions ( -D_MBCS )
Command line, definitions are ignored by cmake, if I do it like this:
cmake -D_UNICODE="" -U_MBCS=""
Command line, definitions are ignored by cmake, if I do it like this:
cmake -DCMAKE_CXX_FLAGS_INIT="-D_UNICODE -U_MBCS"
I assumed that both ways are the same, but obviously the handling of the definitions from command line is different. I am doing something wrong or is it only possible by using add_definitions / remove_definitions ?
By the way, I'm using cmake 3.10.

The -D flags passed to cmake are completely unrelated to the -D flags passed to the compiler. See cmake(1). In short, cmake -DVARIABLE=VALUE ... is roughly equivalent to using set(VARIABLE VALUE CACHE STRING "") inside your CMakeLists.txt.
If you cannot use add_definitions or target_compile_definitions, you can still pass flags to the compiler by setting CMAKE_CXX_FLAGS_INIT the first time you invoke cmake or by changing CMAKE_CXX_FLAGS on later invocations of cmake:
cmake -DCMAKE_CXX_FLAGS_INIT="-D_UNICODE -U_MBCS" ...

Related

define gets ignored by target_compile_definitions

I am looking to build a library and I need to pass two defines to that build, but cmake's target_compile_definitions() scrambles them in a manner that renders them unusable.
The two defines are:
-D'_LIB_EXCEPTION_ABI=__attribute__((visibility("default")))'
-D'_LIB_FALLTHROUGH()=((void)0)'
Unfortunately, the first one gets translated to (in the command build line):
-D'_LIB_EXCEPTION_ABI="\__attribute__((visibility(\"default\")))'"
While the second one is missing altogether from the command line.
CMake has known limitations on what compile definitions could be.
Among these limitations are function-style definitions (_LIB_FALLTHROUGH()) and ones containing double quotes (").
Instead of attempting to overcome these limitations, it is recommended to create a separate header file with these compile definitions:
#define _LIB_EXCEPTION_ABI __attribute__((visibility("default")))
#define _LIB_FALLTHROUGH() ((void)0)
This header file could be included with -include compiler option (gcc) or /FI option (Visual Studio).

adding a msvc flag starting with "/D" results in it being treated as an added definition

So I'm trying to add the /DYNAMICBASE option like this:
add_definitions(/DYNAMICBASE)
and the result in MSVC when I look in the project c++ command line options is this:
/D "YNAMICBASE"
How am I supposed to add this flag? I also tried using CMAKE_CXX_FLAGS but the same thing happens.
My comment (Visual Studio specific):
/D is a compiler (cl.exe) flag, while /DYNAMICBASE is a linker (link.exe) one.
is only half of the answer, and that is finding the root cause.
Translating it into something that cmake understands (setting the CMAKE_SHARED_LINKER_FLAGS and CMAKE_EXE_LINKER_FLAGS variables) which is solving the problem is #onqtam's merit.
So, the points should be divided.

Substituting for a .SET on the the command line

I have some (Microblaze) assembly I need to build (via the GCC cross-assembler and linker) and execute many times with the (same) constants, currently fixed via
.SET
commands, changed each time.
Is there a way to automate the setting of in-assembly constants in this way and so avoid the dull task of resetting the code for each build?
You can use the power of C pre-processor in your assembler files. This could be done simply changing file extension from .s to .S (capital S) on Unix-like platform or to .sx on Windows. Then using gcc instead of gas over these files will let C pre-processor first run through the source and then gas will be called automatically.
In this case you can use all regular pre-processor #define, #ifdef, etc. And of cause you can pass these defines from the command line with gcc's -D parameter.

Escaping quotes for COMPILE_DEFINITIONS

Currently I'm working on a cmake script to compile generated C code. I'm trying to generate a Visual Studio 10 project. The code contains several #include statements which have to be preprocessed before compilition:
#indude INC_FILE
Before starting with CMake the code was compiled with a manually maintained Visual Studio project. I added a preprocessor definition to replace INC_FILE with the final include header:
INC_FILE="foo.h"
For my new CMak script I tried to add this statement to the COMPILE_DEFINITION variable:
set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY COMPILE_DEFINITION "INC_FILE="foo.h"")
Sadly this doesn't work because the quotes are removed. In the generated visual studio project I found the in the project file:
INC_FILE=foo.h
I tried to escape the quotes:
"INC_FILE=\"foo.h\""
INC_FILE=\"foo.h\"
"INC_FILE=\\"foo.h\\"
"INC_FILE="foo.h"
All the above mentions possibilites didn't work. Are there any other tricks in cmake to get a correct quotes escaping for my preprocessor definition?
Tested with cmake 2.8.12.1:
add_executable(foo foo.cpp)
target_compile_definitions(foo PUBLIC FOO_INCL="foo.hpp")
Note 1
You can use include option instead of file's name macro:
#if defined(FOO_INCLUDE_SOME_FILE)
# include "some_file.hpp"
#elif defined(FOO_INCLUDE_OTHER_FILE)
# include "other_file.hpp"
#endif
IMHO it looks much cleaner.
Note 2
If you have a bad time with special characters use configure_file command:
> cat some_file.hpp.in
#include "#FOO_INCLUDE_FILE#"
> cat CMakeLists.txt
set(FOO_INCLUDE_FILE "other_file.hpp")
configure_file(some_file.hpp.in ${foo_BINARY_DIR}/include/some_file.hpp #ONLY)

Concatenation problems with debug print macro under gcc

To completely disable a debug output in c-source,
I usually define the following SIMPLE macro #1
#define dprintf(args)
To enable a debug output, I define macro #2 alternatively
#define dprintf(args) printk##args
The usage in source looks like:
dprintf(("Irqs:%lu\n",irqs));
A preprocessor should create following line if I use macro #2
printk("Irqs:%lu\n",irqs);
Under Windows Visual c++, there is no problem.
Using gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) under NETBEANS IDE 6.8,
I got the following error message:
"printk" and "(" does not give a valid preprocessing token
I tried the following under Linux
#define dprintk(args...) printk(args)
This works only with
dprintf("Irqs:%lu\n",irqs);
Visual C++ however does not know args...
I have to compile source code on windows
and Linux(386) platform alternatively.
Does anyone have an idea ?
Why not #define dprintf(args) print args ?
The double parenthesis could have been added to replace the variadic macro in visual C++ : the preprocessor will handle macro invocation as if there was only one parameter.
The token pasting operator ## can only be used to concatenate tokens, as its name implies. Some compilers, e.g. newer versions of gcc, enforce this more rigidly than others, as you have now discovered. As philippe says, though, you don't actually need ## in this particular example.

Resources