-2

I have the following task. There is a java package that needs to be ported to c++17. A transpiling tool is being used to help with the task and avoid manual rewrite of every single file. Currently for all java classes/interfaces the corresponding c++ class is being created.

The first problem I see with this is that the original java package is huge and it has more then 180 folders. Those all are replicated in the new c++ code-base. We would like to use Cmake as a build tool but the very first problem we see is that we can not simply split the project in multiple sub-directories and simply build separate shared libraries in each sub directory since those have dependencies on each other, and I am really afraid of ending up with circular dependency.
I know it is a lot to ask here but still, what would be the best practice (if any exists) on how to organize such port form java to c++ with cmake. We would like to keep the folder structure since it is logical. The only solution I see so far is to build one giant target that depends on everything. Any comments and ideas or examples of such structure are highly appreciated.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Tito
  • 2,234
  • 6
  • 31
  • 65
  • I'd recommend grouping folders that have circular dependencies together. Look at http://stan4j.com/ for an automated tool that'll help you figure out dependencies – Alecto Irene Perez Jul 24 '19 at 21:08

1 Answers1

1

You could structure the build so that the end result is indeed a giant target including everything, but the subcomponents that go into that build are specified in a piecewise fashion that would put the settings closer to their sources.

As a basic example, I set up a test project with

base CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(cmake_test)

add_library(megalib SHARED dummy.cpp)
add_subdirectory(a)
add_subdirectory(b)

a/CMakeLists.txt:

target_include_directories(megalib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(megalib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/a.cpp)

b/CMakeLists.txt:

target_include_directories(megalib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(megalib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/b.cpp)

And the resulting compilation log (using the Ninja generator):

[1/4] /usr/bin/c++  -Dmegalib_EXPORTS -I/tmp/cmake-test/a -I/tmp/cmake-test/b -fPIC -MD -MT CMakeFiles/megalib.dir/dummy.cpp.o -MF CMakeFiles/megalib.dir/dummy.cpp.o.d -o CMakeFiles/megalib.dir/dummy.cpp.o -c /tmp/cmake-test/dummy.cpp
[2/4] /usr/bin/c++  -Dmegalib_EXPORTS -I/tmp/cmake-test/a -I/tmp/cmake-test/b -fPIC -MD -MT CMakeFiles/megalib.dir/a/a.cpp.o -MF CMakeFiles/megalib.dir/a/a.cpp.o.d -o CMakeFiles/megalib.dir/a/a.cpp.o -c /tmp/cmake-test/a/a.cpp
[3/4] /usr/bin/c++  -Dmegalib_EXPORTS -I/tmp/cmake-test/a -I/tmp/cmake-test/b -fPIC -MD -MT CMakeFiles/megalib.dir/b/b.cpp.o -MF CMakeFiles/megalib.dir/b/b.cpp.o.d -o CMakeFiles/megalib.dir/b/b.cpp.o -c /tmp/cmake-test/b/b.cpp
[4/4] : && /usr/bin/c++ -fPIC    -shared -Wl,-soname,libmegalib.so -o libmegalib.so CMakeFiles/megalib.dir/dummy.cpp.o CMakeFiles/megalib.dir/a/a.cpp.o CMakeFiles/megalib.dir/b/b.cpp.o   && :

It might then be useful to set up some macros to reduce the amount of repetition between subdirectories. (Especially to reduce the burden of having to specify an absolute file path for every source file you add in a subdirectory.)

Daniel Schepler
  • 3,043
  • 14
  • 20
  • many thanks daniel, this was exactly what i was looking for especiatelly the command target_sources – Tito Jul 25 '19 at 05:08
  • "Especially to reduce the burden of having to specify an absolute file path for every source file you add in a subdirectory." - Since CMake 3.13 the command [target_sources](https://cmake.org/cmake/help/v3.13/command/target_sources.html) **automatically transforms relative paths** based on `CMAKE_CURRENT_SOURCE_DIR` variable. So there is no needs to specify `${CMAKE_CURRENT_SOURCE_DIR}/` as a prefix for the path. – Tsyvarev Jul 25 '19 at 10:50
  • Hmm, I was using CMake 3.14.5 for my tests and got errors without the `${CMAKE_CURRENT_SOURCE_DIR}/` prefix. – Daniel Schepler Jul 25 '19 at 15:34