1

The VS2015 solution has the following structure:

vs2015 Solution -

-Project-A (googletest source code)
-Project-B

-Folder-1 (with source and header files)
-Folder-2 (with source and header files in 2 sub-folders)
-Folder-3 (with source and header files)
-src (with source files)
-include (with header files)

-Project-C (unit tests)

I need to build a static library from all the sources in Project-B and link this static library to Project-C. I tried to use CMake just for Project-B, but could not get it to work. Besides, this creates a projectB.sln within the main *.sln.

What's the best way to deal with this, and ensure that this can scale later if I were to add a new project to the main solution? (I'm stuck with this set-up of the code because the previous developer structured it in that way.)

Community
  • 1
  • 1
Archie
  • 153
  • 9

1 Answers1

0

Why not use CMake for the whole project? Assuming your file structure is similar to that shown in your Visual Studio Solution Explorer, it could look something like this:

Top-level CMakeLists.txt:

cmake_minimum_required (VERSION 3.16)

# Name your VS solution.
project(MyProject)
enable_testing()

# Add the CMake file in the googletest repo
add_subdirectory(Project-A)
# Add the CMake file that configures your static library.
add_subdirectory(Project-B)
# Add the CMake file that configures your unit tests.
add_subdirectory(Project-C)

CMakeLists.txt file in Project-B folder:

# Add the VS project for the static library.
project(MyLibProj)

add_library(MyLib STATIC)

# Add the public/private sources for the static library.
target_sources(MyLib 
    PUBLIC
      Folder-1/MyClass1.cpp
      Folder-1/MyClass2.cpp
      ...
      Folder-2/SubFolder1/UtilityClass1.cpp
      Folder-2/SubFolder1/UtilityClass2.cpp
      ...
      Folder-2/SubFolder2/HelperClass1.cpp
      ...
      Folder-3/Circle.cpp
      Folder-3/Square.cpp
    PRIVATE
      src/ImplClass1.cpp
      src/ImplClass2.cpp
      ...
)

# Add the include directories for the library.
target_include_directories(MyLib 
    PUBLIC 
      ${CMAKE_CURRENT_LIST_DIR}/Folder-1
      ${CMAKE_CURRENT_LIST_DIR}/Folder-2/SubFolder1
      ${CMAKE_CURRENT_LIST_DIR}/Folder-2/SubFolder2
      ${CMAKE_CURRENT_LIST_DIR}/Folder-3
    PRIVATE
      ${CMAKE_CURRENT_LIST_DIR}/include
)

CMakeLists.txt file in Project-C folder:

# Add the VS project for the executable.
project(MyExeProj)

# Create the test executable, and link the static library to it.
add_executable(MyTestExe main.cpp)
target_link_libraries(MyTestExe PRIVATE MyLib)

add_test(NAME MyTest COMMAND MyTestExe)
Kevin
  • 16,549
  • 8
  • 60
  • 74
  • @squarekittles Should I add each *.cpp and *.h file individually? There are several files. I was hoping there would be a way to search for all in each folder and add them at once. Is there a way or do you recommend added each file individually? – Archie Apr 26 '20 at 18:52
  • I get this error: Cannot specify sources for target "MyLib" which is not built by this project. Same error for the include files. Also, the include files are not in a separate 'include' dir. So I added each *.h file separately. – Archie Apr 26 '20 at 19:35
  • @Archie You could use globbing to grab all the source files in the Project-B directory for example, `file(GLOB_RECURSE MY_FILES Project-B/*.cpp)`. However, using globbing has drawbacks, as discussed in the answers to this [question](https://stackoverflow.com/q/32411963/3987854). That is why my example lists the sources individually. – Kevin Apr 26 '20 at 19:38
  • gotcha. I added each file individually. But build fails. Cannot specify sources for target "MyLib" which is not built by this project. I guess it is not finding all the source and header files. – Archie Apr 26 '20 at 19:42
  • @Archie You likely have to modify where the source/include files are a bit, to match what your file structure looks like. My example was only an example, based on your provided information. Regarding the error, did you add the line `add_library(MyLib STATIC)` *before* specifying the source files? – Kevin Apr 26 '20 at 19:45
  • I had missed that line. Thank you. I still get the error for target_include_directories. I'm probably missing some header files. BTW, I also get this An interface source of target "MyLib" has a relative path. This warning is for project developers. Use -Wno-dev to suppress it. Do I need to change something? – Archie Apr 26 '20 at 19:59
  • @Archie To get rid of the warning, you can put the *full* path to each source file, rather than the relative path. Just put `${CMAKE_CURRENT_LIST_DIR}/` before each source file – Kevin Apr 26 '20 at 20:37
  • I finally managed to successfully build the solution. Changed the target_include_directories to Set(header_files ...) because the subfolders did not have an 'include' dir. Now it builds the vs solution but 'Mylib.lib' is not generated. In addition I do not see the unit test project in the solution. – Archie Apr 26 '20 at 21:03
  • @Archie If the solution built, then its subprojects should have all built as well. Is the `MyLibProj` project even in the solution? Are you sure the top-level CMake file correctly adds all of the sub-directories? Again, you may have to modify the directory names from my example to match *your* specific file system structure. – Kevin Apr 28 '20 at 12:17
  • I finally got it to work. There were some inter-dependencies. Thanks for your help. – Archie May 04 '20 at 11:39