-1

I wrote a cmake file that builds two shared library a vector3.c and a matrix4.c The matrix4 depends on the vector3, if I run my cmake project and only build the vector3 shared library it builds just fine, when I add the matrix4 shared library I get a cmake error. No rule to make target.

The folder structure

core_math
 ------CMakeLists.txt
-common/
 ------common_structs.h
-matrix4/
 ------CMakeLists.txt
 ------matrix4/src/matrix4_scalar.c
 ------matrix4/headers/matrix4_scalar.h
-vector3/
-------CMakeLists.txt
-------vector3/src/vector3_scalar.c
-------vector3/headers/vector3_scalar.h

core_math/CMakeLists.txt

PROJECT(core_math)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

ADD_SUBDIRECTORY(vector3_scalar)
ADD_SUBDIRECTORY(matrix4_scalar)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/static_lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/shared_lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/bin)

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

core_math/vector3/CMakeLists.txt

PROJECT(vector3_scalar)
SET(CMAKE_MACOSX_RPATH 1)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common)

SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h) 
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/vector3_scalar.c ${HEADER_FILES})

ADD_LIBRARY(vector3_scalar SHARED ${SRC_FILES})

core_math/matrix4_scalar/CMakeLists.txt

PROJECT(matrix4_scalar)
SET(CMAKE_MACOSX_RPATH 1)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common 
    ${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar)


SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h
    ${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar/headers/vector3_scalar.h
    ${CMAKE_CURRENT_SOURCE_DIR}/headers/matrix4_scalar.h)
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix4_scalar.c ${HEADER_FILES})

ADD_LIBRARY(matrix4_scalar SHARED ${SRC_FILES})

TARGET_LINK_LIBRARIES(matrix4_scalar vector3_scalar)

build error

-- Build files have been written to: /Users/blubee/MATH/project/build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object source/core_math/vector3_scalar/CMakeFiles/vector3_scalar.dir/sr
c/vector3_scalar.c.o
[ 50%] Linking C shared library $(CMAKE_BINARY_DIR)/lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/sr
c/matrix4_scalar.c.o
make[2]: *** No rule to make target `source/core_math/vector3_scalar//Users/blubee/MATH/pr
oject/build/lib/libvector3_scalar.dylib', needed by `source/core_math/matrix4_scalar//Use
rs/blubee/MATH/project/build/lib/libmatrix4_scalar.dylib'.  Stop.
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2

if I remove the target_link_libraries from the matrix4_scalar cmakelists.txt file then I get undefined symbols error instead.

Undefined symbols for architecture x86_64:
  "_vec3_deg2rad", referenced from:
      _mat4_rotate in matrix4_scalar.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [source/core_math/matrix4_scalar//Users/blubee/MATH/project/build/lib/libmatr
ix4_scalar.dylib] Error 1
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2
user1610950
  • 1,837
  • 5
  • 33
  • 49
  • you can remove the TARGET_LINK_LIBRARIES() instruction in matrix4_scalar/CMakeLists.txt. For shared libraries, you do not need to link with dependent libraries while creating the shared library. – cm161 Oct 19 '15 at 08:38
  • I tried that in the past but I get undefined symbol since the matrix4_scalar cannot find the vector3 function. – user1610950 Oct 19 '15 at 09:18
  • If you include `vector3_scalar.h` directly in `matrix4_scalar.c`, then you would need to have some "export prefix" defined for whatever is declared in `vector3_scalar.h`. Otherwise the liker tries to link those functions statically. So you could generate those "export headers" with CMake (see [`GENERATE_EXPORT_HEADER()`](https://cmake.org/cmake/help/v3.3/module/GenerateExportHeader.html) macro), if your toolchain does not provide it. – Florian Oct 19 '15 at 11:06
  • the common/common_structs.h is where the actual structs are defined then both matrix4 and vector3 can include that one header file and avoid circular dependency. <-- that was my though process in structuring it this way, is that incorrect? – user1610950 Oct 19 '15 at 11:15
  • No, that's ok. I was just referring to that on other platforms you have to define for each function where it comes from (statically linked or dynamically loaded). But as described [here](http://stackoverflow.com/questions/21400478/how-to-use-dylib-file-in-application) in XCode you can directly link against a dynamic library. Two things you could try: move `SET(CMAKE_MACOSX_RPATH 1)` to the main `CMakeLists.txt` because in a sub-directory it's of no use (see [here](http://stackoverflow.com/questions/31037882/whats-the-cmake-syntax-to-set-and-use-variables)) or changing `SHARED` to `STATIC`. – Florian Oct 19 '15 at 14:51
  • But if I look at `source/core_math/vector3_scalar//Users/blubee/MATH/pr oject/build/lib/libvector3_scalar.dylib` the `//` is very strange. Did you try to throw away your binary output directory and let CMake re-generate the make files from scratch? – Florian Oct 19 '15 at 15:01
  • @Florian I noticed that too but I can't figure out why that's happening. I've changed from using CMAKE_CURRENT_SOURCE_DIR to ${PROJECT_SOURCE_DIR}/ to no avail, I am not sure what I'm doing wrong with this build scripts. – user1610950 Oct 19 '15 at 15:35
  • @user1610950 I've found the problem, see my answer below. – Florian Oct 20 '15 at 19:14

1 Answers1

7

I have done some testing with your code and could reproduce the problem.

It's related to having used $(...) brackets for variable dereferencing in the SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ...) command. I've changed $(CMAKE_BINARY_DIR) to ${CMAKE_BINARY_DIR} and everything works fine:

> cmake --build .
-- Configuring done
-- Generating done
-- Build files have been written to: build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object vector3_scalar/CMakeFiles/vector3_scalar.dir/src/vector3_scalar.c.o
[ 50%] Linking C shared library ../shared_lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object matrix4_scalar/CMakeFiles/matrix4_scalar.dir/src/matrix4_scalar.c.o
[100%] Linking C shared library ../shared_lib/libmatrix4_scalar.dylib
[100%] Built target matrix4_scalar

References

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149
  • wow, man a typo caused all this headache! Thanks a lot for really digging deep and helping me solve this issue! – user1610950 Oct 21 '15 at 14:16