3
votes

Introduction:

I am trying to use CMake to obtain cross platform compilation scripts (for VS 9.0 on a Windows32 and Makefiles for Unix).

I am experiencing something i can't understand about add_subdirectory().

Let me show you my code :

Context:

My architecture for a module named "module1" is something like this :

  • CMakeLists.txt
  • include/
    • file1.h
    • file2.h
    • *.h
  • src/
    • file1.cpp
    • file2.cpp
    • *.cpp
  • test/
    • CMakeLists.txt
    • src/
      • testfile1.cpp
      • testfile2.cpp

The architecture of my whole application is composed of these modules which are in themselves projects that could work independantly.

My goals:

  1. I want to compile my module as a library

  2. I want to test the library with the code in the test/ folder

Here are the CMakeLists i wrote :

This one is the CMakeLists.txt in the root directory of my module.

#ENSURE MINIMUM VERSION OF CMAKE
cmake_minimum_required(VERSION 2.8)

#CONFIGURATION OF THE PROJECT   
    #NAME OF THE PROJECT    
     project(MyProject)

    #OUTPUT OF THE PROJECT  
    set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE}) 

    #ADD THE HEADERS OF THE LIBRARY BEING CREATED   
    include_directories(include)

    #ADD 3rd PARTY OPENCV LIBRARIES     
    find_package(OpenCV REQUIRED)       

    #ADD 3rd PARTY XERCES LIBRARIES
    include_directories(${XERCES_INCLUDE_DIR})
    link_directories(${XERCES_LIB_DIR})     
    set(Xerces_LIBS xerces-c_3D.lib)


#CONFIGURATION OF THE LIBRARY   
file(GLOB_RECURSE MYPROJECT_MODULE_CXX src/*)   
file(GLOB_RECURSE MYPROJECT_MODULE_HDR include/*)       

#NAME OF THE PRESENT LIBRARY    
set(MYPROJECT_MODULE_LIB_NAME myModuleLib)
add_library(${MYPROJECT_MODULE_LIB_NAME}
        SHARED
        ${MYPROJECT_MODULE_CXX}
        ${MYPROJECT_MODULE_HDR}
        )   
target_link_libraries(${MYPROJECT_MODULE_LIB_NAME}
               ${OpenCV_LIBS}
               ${Xerces_LIBS}
               )

#CONTINUE IN THE SUB FOLDERS
add_subdirectory(test)

And then, in the test/ folder, here is the CMakeLists.txt

#ENSURE MINIMUM VERSION OF CMAKE
cmake_minimum_required(VERSION 2.8)

#CONFIGURATION OF THE PROJECT
    #NAME OF THE PROJECT
    project(MyProjectTest)

    #OUTPUT OF THE PROJECT
    set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})

    #ADD OUR TESTED LIBRARY
    include_directories(../include)
    link_directories(../build/lib/${CMAKE_BUILD_TYPE})


#CONFIGURATION OF THE EXE
    file(GLOB_RECURSE MYPROJECT_MODULE_TEST_CXX src/*)

    #NAME OF THE PRESENT EXECUTABLE
    set(MYPROJECT_MODULE_TEST_BIN_NAME myModuleTest)
    add_executable(${MYPROJECT_MODULE_TEST_BIN_NAME}
               ${MYPROJECT_MODULE_TEST_CXX}
               )
    target_link_libraries(${MYPROJECT_MODULE_TEST_BIN_NAME}
                  ${MYPROJECT_MODULE_LIB_NAME}
                  )

Question

The CMake outputs a correct MyProject.sln Visual Studio 9.0 solution, which compiles successfully in my library linked with OpenCV and Xerces (and other 3rd part libraries). However the test binary did not output any MyProjectTest.sln.

I thought, (and read in the CMake documentation) that add_subdirectory(dir) was used to do CMake in the following sub directory (i mean, the name could not be clearer :p !), so shouldn't it continue CMake in the test/ directory and create my MyProjectTest.sln solution ?

I use the GUI CMake to run the root CMakeLists.txt in a build directory that i create in the root of my module. When I explore the build directory that's where I can find my MyProjet.sln, a test/ folder, but no MyProjectTest.sln in it !

2
You are correct, there should be a MyProjectTest.sln solution. Is your project publicly available? There must be some detail you're leaving out of your question that explains why it's missing. What version of CMake are you using? For every "project" command there should be a correspondingly named *.sln file created.DLRdave
I'm using CMake 2.8, and it's a build off tree (that's the term they use in the documentation to say that i don't build the bin in the source tree itself but in a build directory).... Thanks to have looked at my code, and to look again I can't understand why it doesn't work... I thought of cmake using relative path and therefore could not continue in the src tree... I am lost with CMake...jmartel

2 Answers

3
votes

This may not solve your original problem but in your test/folder/CMakeLists.txt try changing

#ADD OUR TESTED LIBRARY
include_directories(../include)
link_directories(../build/lib/${CMAKE_BUILD_TYPE})

to

#ADD OUR TESTED LIBRARY
include_directories(${CMAKE_SOURCE_DIR}/include)
link_directories(${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})

otherwise you are assuming that your build folder is always named build.

1
votes

After three days trying everything, I finally found the answer... Sir DLRdave was right actually: the problem was not from the code itself but from something "out of the code".

Problem found:

I created and edited all my files with Notepad++. Actually when opening the files with windows notepad (because i was curious) a strange rectangle symbol appeared and the file did not look like the one I usually see on Notepad++ I found out that the symbol was a "\n\r" that Notepad++ did not show me (it must be filtered) but going on windows notepad, you could see that the whole file was "impure" and appeared on a single line instead of the layout i saw on Notepad++.

As this "encoding" bug appeared only in the subdirectory CMakeLists, it could not be read but said no error when interpreting with CMake and that's probably why I had no returned error from running CMake.

Solution:

I used the native2ascii.exe tool from Java to correct the encoding error.

The why:

Actually what it probably means is that the syntaxic parser of CMake has probably not been designed for filtering this type of char appearing with strange encoding, that's why it gave me 3 days of intense debugging.