How to compile a single source file from list of sources set in a static library

Let’s say I have the following CMakeLists.txt

cmake_minimum_required(VERSION 3.22.0)

project(TallyWorld DESCRIPTION “” LANGUAGES CXX)

add_library(LibraryA STATIC
“POC/file1.cpp”
“POC/file2.cpp”
“POC/file3.cpp” )

Now to build LibraryA target I can use below command to build
cmake --build --preset= --target Library1

What I am looking a similar way to build file1.cpp,file2.cpp,etc. Something like below
cmake --build --preset= --target file1

Any help would be greatly appreciated.

Regards,
Mohsin Siddiqui

AFAIK CMake isn’t meant to do that. Build systems generally care about build targets (like a library or executable), not so much individual files.

If you really, really need to do that, you could always make a single library (e.g. object library) per cpp file, although 1) I’m not sure what build speed results you would get if you were to do that on a large project, 2) if two files anywhere in your project have the same name, even inside different libraries, you could easily fall into a case where you have two targets with the same name, and then CMake will complain, and 3) you will need to repeat target-specific properties like target_compile_features() for each of these libraries, which essentially means you’ll need a function to set them, which in turn will quickly make your CMake code hard to read.

# Untested, fix issues if any!
add_library(file1-lib OBJECT file1.cpp)
setup_tally_world_lib(file1-lib)
# ...
add_library(fileN-lib OBJECT fileN.cpp)
setup_tally_world_lib(fileN-lib)

add_library(tally-world-lib)
target_link_libraries(tally-world-lib
  PUBLIC
    file1-lib
    file2-lib
    # ...
    fileN-lib)

You could then run the appropriate target using the --target CLI option. As a final note, I remember reading somewhere in CMake’s doc that (for XCode only I think?) you can’t have a library with no sources as tally-world-lib does above.

Personally this seems like way too much badness for something you probably don’t need!

The makefile generators generate make targets for individual source files. For example, this:

add_executable(App src1.cpp src2.cpp)

will allow you to run any of the following commands:

> make src1.o
> make src2.o
> make App

Note that these targets are only generated in the makefile for the directory which defines the actual library/executable, not in any parent directory makefiles. So if your target is in an add_subdirectory(), you have to cd into the corresponding binary directory to have access to the *.o make targets. You can run make help in a directory to see the list of make targets available there; the *.o targets will be there if they’re present.

I don’t know whether any other generators offer similar functionality.

Yeah… This is where I also reached but agree it seems to much of complexing build system. Let me express exact reasoning why we want to do this way and may be I can get some better way to handle the same. So we are using Visual Studio 2022 as an IDE and what we want that opened cpp/kotlin/swift source, on right click I can give a option to compile a single file so that I dont have to compile whole library to see if my changes does not have any syntax error.

Please let me know if you have any idea to handle above .

No, its only there with Makefile and Ninja. XCode and Visual Studio Generator lacks it

I know, my reply is late, but anyway… If you only want “to see if my (your) changes does not have any syntax error” I assume that you changed only this file and built the library previously. Then you can build the library target as you wrote above and your build system will only compile the changed file (and insert it into the static lib, of course). This is true at least for source files; if you changed a header file, then it’s likely that more files need to be compiled, but that should be acceptable as well.

Did I miss anything?

1 Like