Nonstandard extension linking error using CMake

I have a C++11 project for which I have a CMakeLists.txt that builds perfectly with GCC.

I wanted to play around with non-standard extensions and changed (using mv) a single Manager.cpp file to Manager.cu. I am trying to compile the project with GCC.

The following marked within ** are the modifications made

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 **-xc++**")
set(SOURCE_FILES
        **Manager.cu**
            .......
            .......
)
**set_source_files_properties(${SOURCE_FILES} PROPERTIES LANGUAGE CXX)**
**add_executable(test ${SOURCE_FILES})**
**set_target_properties(test PROPERTIES LINKER_LANGUAGE CXX)**

When I try to build this in CLion 2018.2, I see that it is built successfully because of the following message:

[ 1%] Building CXX object CMakeFiles/test.dir/medyan/src/Manager.cu.o
...

Upon building all files, in the linking stage, I get infinite errors and warnings of the following type

...*.cpp.o error: stray ‘\371’ in program ..*cpp.o: error: stray ‘\34’
in program ....*.cu.o: error: stray ‘\2’ in program ....*.cu.o:
warning: null character(s) ignored ..*.cpp.o:3209:629: warning: null
character(s) ignored ..*.cpp.o:3209:1: error: stray ‘\22’ in program
..*.cpp.o:3209:631: warning: null character(s) ignored
..*.cpp.o:3209:1: error: stray ‘\24’ in program

I am not able to debug this as the error message is not helpful. Does it mean that CMake did not build it properly in the first place? How can I go about fixing this?

Upvotes: 0

Views: 813

Answers (2)

fdk1342
fdk1342

Reputation: 3564

There are several things going on.

  1. set_source_files_properties(${SOURCE_FILES} PROPERTIES LANGUAGE CXX) is needed to make sure that the source files are added into the project. In MSYS Makefiles generator any unrecognized files are not candidates for being compiled. In Visual Studio it just shows up in the IDE as a text file.

  2. In generators like MSYS Makefiles it doesn't automatically add the proper compiler flag to compile a file with a non-standard extension. In contrast the Visual Studio generator does know how to do this and no extra steps are necessary.

  3. Adding the -xc++ flag this way set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -xc++) breaks things. That's because these flags are also used during the link process. So on the link line it'll tell g++ to treat all object and archive files as c++ files and compile them.

  4. add_definitions("-xc++") works around these issues because it adds the flag on the compile line not link line.

Don't use add_definitions("-xc++"), use set_source_files_properties(${SOURCE_FILES} PROPERTIES COMPILE_OPTIONS -xc++) instead. Why? Because the first way makes every single file used in any target in CMakeLists.txt a c++ file which can cause problems if c files are used elsewhere. The second way just adds the -xc++ option just to the files in ${SOURCE_FILES}.

Upvotes: 3

So the key change was to add "-xc++" as a definition and not as part of CMAKE_CXX_FLAGS i.e.

add_definitions("-xc++")

This prevents the strange errors I was receiving and it compiles, and links effectively with no errors.

Upvotes: 1

Related Questions