You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Configuration "unittest" leads to error "only one main... allowed" #1270
I use configuration "unittest" to add a dependency to a unittest framework. But there is some strange behavior which an unexperienced developer cannot understand.
Issue 1: Although the package contains an app.d file, running command "dub test" will detect the targetType "library". Target type library will add itself a void main method which will now lead to error:
Generating test runner configuration 'bug1-test-unittest' for 'unittest' (library).
...
source\app.d(3,6): Error: only one main/WinMain/DllMain allowed. Previously found main at ..\..\AppData\Local\Temp\dub_test_root-4ddc4093-e161-491c-b61b-b8f1c8b719fd.d(9,12)
There is no information, that the second main method was generated by dub. Although why is target type "library" detected?
Issue 2:: Attribute mainSourceFile is quite hard to understand. By adding this attribute, app.d is excluded from the compilation (...Excluding main source file source/app.d from test...)
What is hard to understand is following: If I now also add attribute "targetType = executable" then mainSourceFile attribute is ignored and app.d isn't excluded anymore.
This is quite annoying if all one wants to do is to e.g. simply start a script before/after building a unittest. Adding the "unittest" configuration somehow breaks the "normal" unittest behaviour. See below example.
$ dub --version
DUB version 1.9.0, built on Jun 7 2018
Minimal example
source/app.d:
void main(){}
dub.sdl:
name "test"
Output of dub test --verbose (succeeds):
Using dub registry url 'https://code.dlang.org/'
Refreshing local packages (refresh existing: true)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Note: Failed to determine version of package mytest at .. Assuming ~master.
Refreshing local packages (refresh existing: false)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Refreshing local packages (refresh existing: false)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Checking for upgrades.
Using cached upgrade results...
No source files found in configuration 'library'. Falling back to "dub -b unittest".
Configuring dependent mytest, deps:
Performing "unittest" build using /Library/D/dmd/bin/dmd for x86_64.
mytest ~master: building configuration "application"...
/Library/D/dmd/bin/dmd -c -of.dub/build/application-unittest-posix.osx-x86_64-dmd_2080-6878B1D82B97B3507BAD24C0266CCBB5/mytest.o -debug -g -unittest -w -version=Have_mytest -Isource/ source/app.d -vcolumns
Linking...
/Library/D/dmd/bin/dmd -of.dub/build/application-unittest-posix.osx-x86_64-dmd_2080-6878B1D82B97B3507BAD24C0266CCBB5/mytest .dub/build/application-unittest-posix.osx-x86_64-dmd_2080-6878B1D82B97B3507BAD24C0266CCBB5/mytest.o -g
Copying target from /Users/Timoses/programs/dotfim/mytest/.dub/build/application-unittest-posix.osx-x86_64-dmd_2080-6878B1D82B97B3507BAD24C0266CCBB5/mytest to /Users/Timoses/programs/dotfim/mytest
Running ./mytest
Now let's break it
Change dub.sdl to:
name "test"
configuration "unittest" {
preBuildCommands "echo \"HELLO\""
}
Output of dub test --verbose (fails):
Using dub registry url 'https://code.dlang.org/'
Refreshing local packages (refresh existing: true)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Ignoring version specification (>=0.0.0) for path based dependency .
Note: Failed to determine version of package mytest at .. Assuming ~master.
Refreshing local packages (refresh existing: false)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Refreshing local packages (refresh existing: false)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Checking for upgrades.
Using cached upgrade results...
Generating test runner configuration 'mytest-test-unittest' for 'unittest' (library).
Get module name from path: /Users/Timoses/programs/dotfim/mytest/source/app.d
Refreshing local packages (refresh existing: false)...
Looking for local package map at /var/lib/dub/packages/local-packages.json
Looking for local package map at /Users/Timoses/.dub/packages/local-packages.json
Try to load local package map at /Users/Timoses/.dub/packages/local-packages.json
Configuring dependent mytest, deps:
Performing "unittest" build using /Library/D/dmd/bin/dmd for x86_64.
mytest ~master: building configuration "mytest-test-unittest"...
Running pre-build commands...
Running echo "HELLO"
HELLO
/Library/D/dmd/bin/dmd -c -of.dub/build/mytest-test-unittest-unittest-posix.osx-x86_64-dmd_2080-EBCD2572FBC9DD092DC8E29B010CF88C/mytest-test-unittest.o -debug -g -unittest -w -version=VibeCustomMain -version=Have_mytest -Isource/ /var/folders/xf/n9z8fjbd0tx4l6t3h1l1n4_00000gn/T/dub_test_root-286ff5ba-2ea5-4569-8532-bb47822835eb.d source/app.d -vcolumns
source/app.d(1,6): Error: only one `main` allowed. Previously found `main` at /var/folders/xf/n9z8fjbd0tx4l6t3h1l1n4_00000gn/T/dub_test_root-286ff5ba-2ea5-4569-8532-bb47822835eb.d(9,12)
FAIL .dub/build/mytest-test-unittest-unittest-posix.osx-x86_64-dmd_2080-EBCD2572FBC9DD092DC8E29B010CF88C/ mytest-test-unittest executable
/Library/D/dmd/bin/dmd failed with exit code 1.
In the working case the output shows
No source files found in configuration 'library'. Falling back to "dub -b unittest".
whereas that is not shown in the non-working output.
The behaviour feels very opaque. Apparently, specifying the unittest configuration overwrites the behaviour.
However, that still fails with "only one main allowed. ...". Additionally it tells that user:
## Warning for package mytest, configuration unittest ##
The following compiler flags have been specified in the package description
file. They are handled by DUB and direct use in packages is discouraged.
Alternatively, you can set the DFLAGS environment variable to pass custom flags
to the compiler, or use one of the suggestions below:
unittests: Call DUB with --build=unittest
Well.. How then should a custom "unittest" configuration be set up? And what are the quirks behind the scene that make dub test work in one case but not in the other?
And here is what I get, when I try to run dub build in the project dir.
Performing "debug" build using /usr/local/bin/ldc for aarch64, arm_hardfloat.
alerter ~master: building configuration "alerter"...
Error: No source files
/usr/local/bin/ldc failed with exit code 1.
alerter ~master: building configuration "alerter"...
So you aren't building the debug configuration, and source/alerter.d is excluded from the alerter configuration.
Ok, dub -b debug successfully builds the project. However, it uses the "library" target type by default and if I specify the "targetType" : "executable"
Performing "debug" build using /usr/local/bin/ldc for aarch64, arm_hardfloat.
alerter ~master: building configuration "debug"...
Error: module `alerter` is in file 'alerter.d' which cannot be read
import path[0] = source/
import path[1] = /Users/pavels/.local/share/ldc2/bin/../import
/usr/local/bin/ldc failed with exit code 1.
Do you have a working dub.json by chance for a single executable script with a custom name?
I have run into this problem as well and while searching for answers, I ran into this GitHub issue. In the current dub version, the system does work, but it's quite confusing for newer engineers due to the following reasons:
The implicitly generated application or library configurations are not visible, so there is no easy way to know that special logic was being done by default, and the user just assumes this is normal behavior.
The definition of any configuration causes the defaults to be lost, e.g. someone adding a special test configuration suddenly finds errors like this while simply trying to build the app or run unittests.
Even after the user discovers they must now re-write multiple configurations, the default behavior of the generated 'application' or 'library' configs is not documented, thus the engineer has to figure it out someone through trial and error.
With that being said, I find the following dub.sdl does most of what is needed for my use case (having a separate integration test configuration that tests the fully built program from the outside):
Activity
Timoses commentedon Dec 20, 2018
This is quite annoying if all one wants to do is to e.g. simply start a script before/after building a unittest. Adding the "unittest" configuration somehow breaks the "normal" unittest behaviour. See below example.
Minimal example
source/app.d:dub.sdl:Output of
dub test --verbose(succeeds):Now let's break it
Change
dub.sdlto:Output of
dub test --verbose(fails):In the working case the output shows
whereas that is not shown in the non-working output.
The behaviour feels very opaque. Apparently, specifying the unittest configuration overwrites the behaviour.
One could specify in
dub.sdl:However, that still fails with "only one main allowed. ...". Additionally it tells that user:
Well.. How then should a custom "unittest" configuration be set up? And what are the quirks behind the scene that make
dub testwork in one case but not in the other?tastyminerals commentedon Aug 11, 2021
Bump! Same issue. Is this going to be fixed? How should one trigger unittests in dub?
Geod24 commentedon Aug 11, 2021
Use
mainSourceFilein your configuration. It will be automatically excluded from other configurations.tastyminerals commentedon Aug 11, 2021
Unfortunately, it doesn't work with
dub test:Geod24 commentedon Aug 12, 2021
Where is the
configurationsarray ?What I meant was:
tastyminerals commentedon Aug 12, 2021
Here is the current dub.json
{ "name": "alerter", "sourcePaths": ["source"], "copyFiles": ["./resources"], "targetPath": "build", "configurations": [ { "name": "debug", "mainSourceFile": "source/alerter.d" }, { "name": "unittest" } ], "buildTypes": { "release": { "buildOptions": [ "releaseMode", "inline", "optimize" ] }, "tests": { "buildOptions": [ "unittests" ] } } }And here is what I get, when I try to run
dub buildin the project dir.I tried
dub -boptions and they also don't work.Geod24 commentedon Aug 12, 2021
So you aren't building the
debugconfiguration, andsource/alerter.dis excluded from thealerterconfiguration.tastyminerals commentedon Aug 12, 2021
Ok,
dub -b debugsuccessfully builds the project. However, it uses the "library" target type by default and if I specify the"targetType" : "executable"{ "name": "debug", "mainSourceFile": "alerter.d", "targetType": "executable" }I get :(
Do you have a working
dub.jsonby chance for a single executable script with a custom name?vnayar commentedon Feb 6, 2022
I have run into this problem as well and while searching for answers, I ran into this GitHub issue. In the current dub version, the system does work, but it's quite confusing for newer engineers due to the following reasons:
applicationorlibraryconfigurations are not visible, so there is no easy way to know that special logic was being done by default, and the user just assumes this is normal behavior.configurationcauses the defaults to be lost, e.g. someone adding a special test configuration suddenly finds errors like this while simply trying to build the app or run unittests.With that being said, I find the following
dub.sdldoes most of what is needed for my use case (having a separate integration test configuration that tests the fully built program from the outside):