Ziv
Ziv

Reputation: 2421

CMake trying to link directory as an executable if their names match

I'm encountering an annoying error in CMake where the following conditions hold:

  1. A target name is identical to name of the directory defining the target.
  2. I am using the RUNTIME_OUTPUT_DIRECTORY property for the target.

Under these conditions, I get the errors:

CMake seems to be trying to build a target named . , apparently trying to refer to the current directory name rather than the desired target name.


Here's a trivial example. My file tree is:

/tmp/example$ tree
.
├── build
└── src
    ├── CMakeLists.txt
    └── hello_world
        ├── CMakeLists.txt
        └── HelloWorld.cpp

src/CMakeLists.txt:

set (ARBITRARY_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(hello_world)

src/hello_world:

add_executable(hello_world HelloWorld.cpp)
set_property(TARGET hello_world PROPERTY RUNTIME_OUTPUT_DIRECTORY ${ARBITRARY_OUTPUT_DIR})

...and HelloWorld.cpp itself is a trivial Hello World program, with a main() method.


I run:

/tmp/example/build$ cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 -G"Unix Makefiles"
/tmp/example/build$ make VERBOSE=1

And I get:

[ 50%] Building CXX object hello_world/CMakeFiles/hello_world.dir/HelloWorld.o
cd /tmp/example/build/hello_world && /usr/bin/g++-4.8     -O3 -DNDEBUG   -o CMakeFiles/hello_world.dir/HelloWorld.o -c /tmp/example/src/hello_world/HelloWorld.cpp
[100%] Linking CXX executable .
cd /tmp/example/build/hello_world && /usr/bin/cmake -E cmake_link_script CMakeFiles/hello_world.dir/link.txt --verbose=1
/usr/bin/g++-4.8   -O3 -DNDEBUG   CMakeFiles/hello_world.dir/HelloWorld.o  -o . -rdynamic
/usr/bin/ld: cannot open output file .: Is a directory
collect2: error: ld returned 1 exit status

As you can see, CMakeFiles/hello_world.dir/link.txt sets the linking target as -o . , which obviously won't work.


Is this a bug in CMake, or am I doing something wrong? Is there some workaround for this?

My tools are:

Upvotes: 3

Views: 878

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 65928

Your top-level build directory contains hello_world directory because of command add_subdirectory(hello_world).

By setting RUNTIME_OUTPUT_DIRECTORY property to top-level build directory, you want to create executable file with name hello_world there.

But in single directory it is impossible to have both file and directory with the same name.

You need to rename either subdirectory or executable or change directory to place executable.

Upvotes: 4

Related Questions